CoffeeScript for the Rubyist

  • 516 views
Uploaded on

Presented at AlohaRubyConf in Honolulu, HI on 10/09/2012

Presented at AlohaRubyConf in Honolulu, HI on 10/09/2012

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
516
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
14
Comments
0
Likes
3

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Transcript

  • 1. COFFEESCRIPT A Rubyist’s Love Affair @markbates
  • 2. ALOHA!
  • 3. Cats
  • 4. Cats
  • 5. DistributedProgramming with Ruby Addison-Wesley 2009http://books.markbates.com
  • 6. Programming in CoffeeScript Addison-Wesley 2012 http://books.markbates.com
  • 7. A (BRIEF) HISTORY LESSON
  • 8. “I need to come up with a scripting languagefor web browsers. I know! Ill make it cool and Lispy! ” Dramatic Re-enactment (1995)
  • 9. “ Yeah, So... Java is getting really popular. So were going to need you to rewrite your language into something a bit more Java- esque and name it something like JavaScript.  Yeah, and were going to need it in a week. Thanks, thatd be great. ” Dramatic Re-enactment (1995)
  • 10. var MyApp.Models.Product = Backbone.Model.extend({ isLiked: function() { var _ref; return ! ((_ref = this.like()) != null ? _ref.isNew() : void 0); }; like: function() { return new MyApp.Models.Like(this.get("like")); }; image: function(size) { var img; if (size == null) { size = "full"; } if (this.get("image") != null) { img = this.get("image")[size]; } if (img == null) { img = "/images/fallback/product_" + size + "_default.png"; } return img; };});
  • 11. FAST FORWARD About 15 Years
  • 12. var MyApp.Models.Product = Backbone.Model.extend({ isLiked: function() { var _ref; return ! ((_ref = this.like()) != null ? _ref.isNew() : void 0); }; like: function() { return new MyApp.Models.Like(this.get("like")); }; image: function(size) { var img; if (size == null) { size = "full"; } if (this.get("image") != null) { img = this.get("image")[size]; } if (img == null) { img = "/images/fallback/product_" + size + "_default.png"; } return img; };});
  • 13. class MyApp.Models.Product extends Backbone.Model isLiked: -> !@like()?.isNew() like: -> new MyApp.Models.Like(@get("like")) image: (size = "full") -> if @get("image")? img = @get("image")[size] unless img? img = "/images/fallback/product_#{size}_default.png" return img
  • 14. WHAT IS COFFEESCRIPT?
  • 15. What is CoffeeScript?
  • 16. What is CoffeeScript?“A little language that compiles into JavaScript.”
  • 17. What is CoffeeScript?“A little language that compiles into JavaScript.”Easily integrates with your current JavaScript
  • 18. What is CoffeeScript?“A little language that compiles into JavaScript.”Easily integrates with your current JavaScriptEasier to read, write, maintain, refactor, etc...
  • 19. What is CoffeeScript?“A little language that compiles into JavaScript.”Easily integrates with your current JavaScriptEasier to read, write, maintain, refactor, etc...A Hybrid of Ruby and Python.
  • 20. What is CoffeeScript?“A little language that compiles into JavaScript.”Easily integrates with your current JavaScriptEasier to read, write, maintain, refactor, etc...A Hybrid of Ruby and Python.Helpful.
  • 21. What CoffeeScript Is Not?Not Magic!Limited by what JavaScript can already do
  • 22. “I’m happy writing JavaScript.I don’t need to learn another language. ”
  • 23. FINE WITH ME
  • 24. BUT...
  • 25. ANOTHER (BRIEF) HISTORY LESSON
  • 26. .MODEL SMALL DISP: MOV BL,VAL1.STACK 64 ADD BL,VAL2.DATA MOV AH,00H VAL1 DB 01H MOV AL,BL VAL2 DB 01H MOV LP,CL LP DB 00H MOV CL,10 V1 DB 00H DIV CL V2 DB 00H MOV CL,LP NL DB 0DH,0AH,$ MOV V1,AL.CODE MOV V2,AHMAIN PROC MOV DL,V1 MOV AX,@DATA ADD DL,30H MOV DS,AX MOV AH,02H INT 21H MOV AH,01H INT 21H MOV DL,V2 MOV CL,AL ADD DL,30H SUB CL,30H MOV AH,02H SUB CL,2 INT 21H MOV AH,02H MOV DL,VAL2 MOV DL,VAL1 MOV VAL1,DL ADD DL,30H MOV VAL2,BL INT 21H MOV AH,09H MOV AH,09H LEA DX,NL LEA DX,NL INT 21H INT 21H LOOP DISP MOV AH,02H MOV DL,VAL2 MOV AH,4CH ADD DL,30H INT 21H INT 21H MAIN ENDP MOV AH,09H END MAIN LEA DX,NL INT 21H
  • 27. .MODEL SMALL DISP:.STACK 64 MOV BL,VAL1 ADD BL,VAL2 Assembly.DATA MOV AH,00H VAL1 DB 01H MOV AL,BL VAL2 DB 01H MOV LP,CL LP DB 00H MOV CL,10 V1 DB 00H DIV CL V2 DB 00H MOV CL,LP NL DB 0DH,0AH,$ MOV V1,AL.CODE MOV V2,AHMAIN PROC MOV DL,V1 MOV AX,@DATA ADD DL,30H MOV DS,AX MOV AH,02H INT 21H MOV AH,01H INT 21H MOV DL,V2 MOV CL,AL ADD DL,30H SUB CL,30H MOV AH,02H SUB CL,2 INT 21H MOV AH,02H MOV DL,VAL2 MOV DL,VAL1 MOV VAL1,DL ADD DL,30H MOV VAL2,BL INT 21H MOV AH,09H MOV AH,09H LEA DX,NL LEA DX,NL INT 21H INT 21H LOOP DISP MOV AH,02H MOV DL,VAL2 MOV AH,4CH ADD DL,30H INT 21H INT 21H MAIN ENDP MOV AH,09H END MAIN LEA DX,NL INT 21H
  • 28. #include <stdio.h> Cint fibonacci(){ int n = 100; int a = 0; int b = 1; int sum; int i; for (i = 0; i < n; i++) { printf("%dn", a); sum = a + b; a = b; b = sum; } return 0;}
  • 29. public static void fibonacci() { Java int n = 100; int a = 0; int b = 1; for (int i = 0; i < n; i++) { System.out.println(a); a = a + b; b = a - b; }}
  • 30. def fibonacci Ruby a = 0 b = 1 100.times do printf("%dn", a) a, b = b, a + b endend
  • 31. “I can write an app just as well in Javaas I can in Ruby, but damn it if Rubyisn’t nicer to read and write! ”
  • 32. SAME GOES FORCOFFEESCRIPT
  • 33. SYNTAX
  • 34. $(function() { $ -> success = (data) -> success = function(data) { if data.errors? if (data.errors != null) { alert "There was an error!" alert("There was an error!"); else } else { $("#content").text(data.message) $("#content").text(data.message); } $.get(/users, success, json) }; $.get(/users, success, json);}); JavaScript CoffeeScript
  • 35. Syntax RulesNo semi-colons (ever!)No curly braces*No ‘function’ keywordRelaxed parenthesesWhitespace significant formatting
  • 36. Parentheses Rules# Not required without arguments:noArg1 = -> # do something# Not required without arguments:noArg2 = () -> # do something # Required without arguments:# Required with Arguments: noArg1()withArg = (arg) -> noArg2() # do something # Not required with arguments: withArg("bar") withArg "bar"
  • 37. Parentheses Rules# Bad:$ "#some_id" .text()# $("#some_id".text());# Good:$("#some_id").text()# $("#some_id").text();
  • 38. Whitespace
  • 39. Whitespace$(function() {success = function(data) {if (data.errors != null) {alert("There was an error!");} else {$("#content").text(data.message);}};$.get(/users, success, json);});
  • 40. Whitespace$(function() { def fibonaccisuccess = function(data) { a = 0if (data.errors != null) { b = 1alert("There was an error!"); 100.times do} else { printf("%dn", a)$("#content").text(data.message); a, b = b, a + b} end}; end$.get(/users, success, json);});
  • 41. Whitespace$(function() { def fibonacci a = 0 success = function(data) { b = 1 if (data.errors != null) { alert("There was an error!"); 100.times do } else { printf("%dn", a) $("#content").text(data.message); a, b = b, a + b } end }; end $.get(/users, success, json);});
  • 42. Whitespace$ -> success = (data) -> if data.errors? alert "There was an error!" else $("#content").text(data.message) $.get(/users, success, json)
  • 43. RUBYSCRIPT?
  • 44. Conditionalsif true doSomething() if true doSomething() doSomething() unless trueunless true doSomething() if true doSomething() else doSomethingElse()
  • 45. Objects/HashessomeObject = {conf: "AlohaRubyConf", talk: "CoffeeScript"}someObject = conf: "AlohaRubyConf" talk: "CoffeeScript"someFunction(conf: "AlohaRubyConf", talk: "CoffeeScript")
  • 46. Objects/Hashesvar someObject;someObject = { conf: "AlohaRubyConf", talk: "CoffeeScript"};someObject = { conf: "AlohaRubyConf", talk: "CoffeeScript"};someFunction({ conf: "AlohaRubyConf", talk: "CoffeeScript"});
  • 47. String Interpolationname = "AlohaRubyConf 2012"console.log "Hello #{name}"# Hello AlohaRubyConf 2012console.log Hello #{name}# Hello #{name}
  • 48. String Interpolationname = "AlohaRubyConf 2012" var name;console.log "Hello #{name}" name = "AlohaRubyConf 2012";# Hello AlohaRubyConf 2012 console.log("Hello " + name);console.log Hello #{name}# Hello #{name} console.log(Hello #{name});
  • 49. Heredocshtml = """ <div class="comment" id="tweet-#{tweet.id_str}"> <hr> <div class=tweet> <span class="imgr"><imgsrc="#{tweet.profile_image_url}"></span> <span class="txtr"> <h5><a href="http://twitter.com/#{tweet.from_user}"target="_blank">@#{tweet.from_user}</a></h5> <p>#{tweet.text}</p> <p class="comment-posted-on">#{tweet.created_at}</p> </span> </div> </div>"""
  • 50. Heredocsvar html;html = "<div class="comment" id="tweet-" + tweet.id_str+ "">n <hr>n <div class=tweet>n <span class="imgr"><img src="" + tweet.profile_image_url + ""></span>n <span class="txtr">n <h5><a href="http://twitter.com/" + tweet.from_user + "" target="_blank">@" + tweet.from_user + "</a></h5>n <p>" +tweet.text + "</p>n <p class="comment-posted-on">"+ tweet.created_at + "</p>n </span>n </div>n</div>";
  • 51. Functionsp = (name) -> console.log "Hello #{name}"p(AlohaRubyConf 2012)
  • 52. Functionsvar p;p = function(name) { return console.log("Hello " + name);};p(AlohaRubyConf 2012);
  • 53. Functionsp = (name)-> console.log "Hello #{name}"p(AlohaRubyConf 2012)
  • 54. Functionsp = (name)-> console.log "Hello #{name}" CoffeeScriptp(AlohaRubyConf 2012)
  • 55. Functionsp = (name)-> console.log "Hello #{name}" CoffeeScriptp(AlohaRubyConf 2012)p = ->(name) { puts "Hello #{name}"} Ruby 1.9p.call(AlohaRubyConf 2012)
  • 56. Loops & Comprehensionsfor someName in someArray console.log someNamefor key, value of someObject console.log "#{key}: #{value}"
  • 57. Loops & Comprehensionsvar key, someName, value, _i, _len;for (_i = 0, _len = someArray.length; _i < _len; _i++) { someName = someArray[_i]; console.log(someName);}for (key in someObject) { value = someObject[key]; console.log("" + key + ": " + value);}
  • 58. Loops & Comprehensionsnumbers = [1..5]console.log number for number in numbers
  • 59. Loops & Comprehensionsvar number, numbers, _i, _len;numbers = [1, 2, 3, 4, 5];for (_i = 0, _len = numbers.length; _i < _len; _i++) { number = numbers[_i]; console.log(number);}
  • 60. Loops & Comprehensionsnumbers = [1..5]console.log number for number in numbers when number <= 3
  • 61. Loops & Comprehensionsvar number, numbers, _i, _len;numbers = [1, 2, 3, 4, 5];for (_i = 0, _len = numbers.length; _i < _len; _i++) { number = numbers[_i]; if (number <= 3) { console.log(number); }}
  • 62. Loops & Comprehensionsnumbers = [1, 2, 3, 4, 5]low_numbers = (number * 2 for number in numbers when number <= 3)console.log low_numbers # [ 2, 4, 6 ]
  • 63. Loops & Comprehensionsvar low_numbers, number, numbers;numbers = [1, 2, 3, 4, 5];low_numbers = (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = numbers.length; _i < _len; _i++) { number = numbers[_i]; if (number <= 3) { _results.push(number * 2); } } return _results;})();console.log(low_numbers);
  • 64. Classesclass Employeeemp = new Employee()emp.firstName = "Mark"
  • 65. Classesvar Employee, emp;Employee = (function() { Employee.name = Employee; function Employee() {} return Employee;})();emp = new Employee();emp.firstName = "Mark";
  • 66. Classesclass Employee constructor: (@options = {}) -> salary: -> @options.salary ?= "$250,000"emp = new Employee()console.log emp.salary() # "$250,000"emp = new Employee(salary: "$100,000")console.log emp.salary() # "$100,000"
  • 67. Classesvar Employee, emp;Employee = (function() { Employee.name = Employee; function Employee(options) { this.options = options != null ? options : {}; } Employee.prototype.salary = function() { var _base, _ref; return (_ref = (_base = this.options).salary) != null ? _ref : _base.salary = "$250,000"; }; return Employee;})();emp = new Employee();console.log(emp.salary());emp = new Employee({ salary: "$100,000"});console.log(emp.salary());
  • 68. Extending Classesclass Manager extends Employee salary: -> "#{super} w/ $10k Bonus"manager = new Manager()console.log manager.salary() # "$250,000 w/ $10k Bonus"
  • 69. Extending Classesvar Manager, manager, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ =parent.prototype; return child; };Manager = (function(_super) { __extends(Manager, _super); Manager.name = Manager; function Manager() { var _base; Manager.__super__.constructor.apply(this, arguments); } Manager.prototype.salary = function() { return "" + Manager.__super__.salary.apply(this, arguments) + " w/ $10k Bonus"; }; return Manager;})(Employee);manager = new Manager();console.log(manager.salary());
  • 70. Bound Functionsclass User constructor: (@name) -> sayHi: -> console.log "Hello #{@name}"bob = new User(bob)mary = new User(mary)log = (callback)-> console.log "about to execute callback..." callback() console.log "...executed callback"log(bob.sayHi)log(mary.sayHi)
  • 71. Bound Functionsabout to execute callback...Hello undefined...executed callbackabout to execute callback...Hello undefined...executed callback
  • 72. Bound Functionsclass User constructor: (@name) -> sayHi: -> console.log "Hello #{@name}"bob = new User(bob)mary = new User(mary)log = (callback)-> console.log "about to execute callback..." callback() console.log "...executed callback"log(bob.sayHi)log(mary.sayHi)
  • 73. Bound Functionsclass User constructor: (@name) -> sayHi: -> console.log "Hello #{@name}"bob = new User(bob)mary = new User(mary)log = (callback)-> console.log "about to execute callback..." callback() console.log "...executed callback"log(bob.sayHi)log(mary.sayHi)
  • 74. Bound Functionsclass User constructor: (@name) -> sayHi: => console.log "Hello #{@name}"bob = new User(bob)mary = new User(mary)log = (callback)-> console.log "about to execute callback..." callback() console.log "...executed callback"log(bob.sayHi)log(mary.sayHi)
  • 75. Bound Functionsabout to execute callback...Hello bob...executed callbackabout to execute callback...Hello mary...executed callback
  • 76. Bound Functionsclass User constructor: (@name) -> sayHi: => console.log "Hello #{@name}"
  • 77. Bound Functionsvar User, __bind = function(fn, me){ return function(){ return fn.apply(me,arguments); }; };User = (function() { User.name = User; function User(name) { this.name = name; this.sayHi = __bind(this.sayHi, this); } User.prototype.sayHi = function() { return console.log("Hello " + this.name); }; return User;})();
  • 78. FINALLYOne of my favorite features
  • 79. Existential Operatorif foo? console.log "foo"
  • 80. Existential Operatorif (typeof foo !== "undefined" && foo !== null) { console.log("foo");}
  • 81. BUT WAIT! THERE’S MORE!
  • 82. Existential Operatorconsole?.log "foo"
  • 83. Existential Operatorconsole?.log "foo"if (typeof console !== "undefined" && console !== null) { console.log("foo");}
  • 84. Existential Operatorif currentUser?.firstName? console.log currentUser.firstName
  • 85. Existential Operatorif currentUser?.firstName? console.log currentUser.firstNameif ((typeof currentUser !== "undefined" && currentUser !==null ? currentUser.firstName : void 0) != null) { console.log(currentUser.firstName);}
  • 86. FINALLY
  • 87. The Raven
  • 88. The RavenOnce upon a mignight dreary while I pondered, weak and weary,Over many quaint and curious volume of forgotten lore -While I nodded, nearly napping, suddenly there came a tapping,As of some one gently rapping, rapping at my chamber door"Tis some visiter". I muttered, "tapping at my chamber door" -"only this and nothing more."Ah distinctly I remember it was in the bleak December;And each separate dying ember wrought its ghost upon the floor.Eagerly I wished the morrow - vainly I had sought to borrow,From my books surcease of sorrow - sorrow For the lost Lenore -For the rare and radiant maiden whom the angels name Lenore -Nameless here For evermore
  • 89. The Ravenvar __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length;i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };while (I(pondered, weak && weary, Over(many(quaint && curious(volume inforgotten(lore - While(I(nodded, nearly(napping, suddenly(there(came(a(tapping,As in some(one(gently(rapping, rapping(at(my(chamber(door)))))))))))))))))))) {  Once(upon(a(mignight(dreary))));}"Tis some visiter".I(muttered, "tapping at my chamber door" - "only this andnothing more.");Ah(distinctly(I(remember(it(__indexOf.call(the(bleak(December)), was) >= 0)))));And(each(separate(dying(ember(wrought(its(ghost(upon(the(floor.Eagerly(I(wished(the(morrow - vainly(I(had(sought(to(borrow, From(my(books(surcease in sorrow -sorrow(For(the(lost(Lenore - For(the(rare &&radiant(maiden(whom(the(angels(name(Lenore -Nameless(here(For(evermore)))))))))))))))))))))))))))))))))))));
  • 90. CELEBRITY ENDORSEMENTS
  • 91. Matt Aimonetti
  • 92. Matt Aimonetti“You should go to Mark’s Talk.”
  • 93. Matt Aimonetti“You should go to Mark’s Talk.”“Buy... his... book. It’s... Great.”
  • 94. Corey Haines
  • 95. Corey Haines“When I’m not engaged in auto- erotic asphyxiation I write CoffeeScript, you should too!”
  • 96. Konstantin Haase
  • 97. Konstantin Haase “I’m not negative, I’m justGerman, but I’m definitely positive about CoffeeScript!”
  • 98. What Didn’t I Cover?Default Arguments OperatorsRanges The `do` keywordSplatted Arguments Plenty more!ScopingSecurityStrict ModeFixes common ‘mistakes’
  • 99. Mahalo!
  • 100. Mahalo!myName = "Mark Bates"you.should buyBook("Programming in CoffeeScript") .at("http://books.markbates.com")you.should followMe(@markbates)