COFFEESCRIPT   A Rubyist’s Love Affair
Mark Bates
DistributedProgramming    with    Ruby     Addison-Wesley          2009http://books.markbates.com
Programming      in CoffeeScript      Addison-Wesley           2012 http://books.markbates.com
A (BRIEF) HISTORY LESSON
“I need to come up with a scripting languagefor web browsers.    I know! Ill make it cool and Lispy!      ”               ...
“   Yeah, So... Java is getting really popular.    So were going to need you to rewrite your    language into something a ...
var MyApp.Models.Product = Backbone.Model.extend({  isLiked: function() {     var _ref;     return ! ((_ref = this.like())...
FAST FORWARD    About 15 Years
var MyApp.Models.Product = Backbone.Model.extend({  isLiked: function() {     var _ref;     return ! ((_ref = this.like())...
class MyApp.Models.Product extends Backbone.Model  isLiked: ->    !@like()?.isNew()  like: ->    new MyApp.Models.Like(@ge...
WHAT IS COFFEESCRIPT?
What is CoffeeScript?
What is CoffeeScript?“A little language that compiles into JavaScript.”
What is CoffeeScript?“A little language that compiles into JavaScript.”Easily integrates with your current JavaScript
What is CoffeeScript?“A little language that compiles into JavaScript.”Easily integrates with your current JavaScriptEasie...
What is CoffeeScript?“A little language that compiles into JavaScript.”Easily integrates with your current JavaScriptEasie...
What is CoffeeScript?“A little language that compiles into JavaScript.”Easily integrates with your current JavaScriptEasie...
What CoffeeScript Is Not?Not Magic!Limited by what JavaScript can already do
“I’m happy writing JavaScript.I don’t need to learn another language.   ”
FINE WITH ME
BUT...
.MODEL SMALL                           DISP:                                               MOV BL,VAL1.STACK 64           ...
.MODEL SMALL                                      DISP:                                       Assembly           MOV BL,VA...
#include <stdio.h>            Cint fibonacci(){  int n = 100;  int a = 0;  int b = 1;  int sum;  int i;    for (i = 0; i <...
public static void fibonacci() {    Java  int n = 100;  int a = 0;  int b = 1;    for (int i = 0; i < n; i++) {      Syste...
def fibonacci           Ruby  a = 0  b = 1  100.times do    printf("%dn", a)    a, b = b, a + b  endend
“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!   ”
SAME GOES FORCOFFEESCRIPT
SYNTAX
$(function() {                             $ ->                                             success = (data) ->  success =...
Syntax RulesNo semi-colons (ever!)No curly braces*No ‘function’ keywordRelaxed parenthesesWhitespace significant formatting
Parentheses Rules# Not required without arguments:noArg1 = ->  # do something# Not required without arguments:noArg2 = () ...
Parentheses Rulesvar noArg1, noArg2, withArg;noArg1 = function() {};noArg2 = function() {};withArg = function(arg) {};noAr...
Parentheses Rules# Bad:$ "#some_id" .text()# $("#some_id".text());# Good:$("#some_id").text()# $("#some_id").text();
Whitespace
Whitespace$(function() {success = function(data) {if (data.errors != null) {alert("There was an error!");} else {$("#conte...
Whitespace$(function() {                      def fibonaccisuccess = function(data) {          a = 0if (data.errors != nul...
Whitespace$(function() {                             def fibonacci                                             a = 0  succ...
Whitespace$ ->  success = (data) ->     if data.errors?       alert "There was an error!"     else       $("#content").tex...
Whitespace$(function() {  var success;  success = function(data) {     if (data.errors != null) {       return alert("Ther...
RUBYSCRIPT?
Conditionals
Conditionalsif true  doSomething()unless true  doSomething()
Conditionalsif true                doSomething() if true  doSomething()                       doSomething() unless trueunl...
Conditionalsif true                    doSomething() if true  doSomething()                           doSomething() unless...
Objects/HashessomeObject = {conf: "RailsConf", talk: "CoffeeScript"}someObject =  conf: "RailsConf"  talk: "CoffeeScript"s...
Objects/Hashesvar someObject;someObject = {   conf: "RailsConf",   talk: "CoffeeScript"};someObject = {   conf: "RailsConf...
Rangesa = [1..5]b = [1...5]c = [1..100]d = [100..1]
Rangesa = [1..5]     var a, b, c, d, _i, _j, _results, _results1;               a = [1, 2, 3, 4, 5];b = [1...5]           ...
String Interpolationname = "RailsConf 2012"console.log "Hello #{name}"# Hello RailsConf 2012console.log Hello #{name}# Hel...
String Interpolationname = "RailsConf 2012"       var name;console.log "Hello #{name}"   name = "RailsConf 2012";# Hello R...
Heredocshtml = """  <div class="comment" id="tweet-#{tweet.id_str}">    <hr>    <div class=tweet>      <span class="imgr">...
Heredocsvar html;html = "<div class="comment" id="tweet-" + tweet.id_str+ "">n <hr>n <div class=tweet>n      <span class="...
Functionsp = (name) ->  console.log "Hello #{name}"p(RailsConf 2012)
Functionsvar p;p = function(name) {   return console.log("Hello " + name);};p(RailsConf 2012);
Functionsp = (name)->  console.log "Hello #{name}"p(RailsConf 2012)
Functionsp = (name)->  console.log "Hello #{name}"     CoffeeScriptp(RailsConf 2012)
Functionsp = (name)->  console.log "Hello #{name}"     CoffeeScriptp(RailsConf 2012)p = ->(name) {  puts "Hello #{name}"} ...
Default ArgumentscreateElement = (name, attributes = {}) ->  obj = document.createElement name  for key, val of attributes...
Default Argumentsvar createElement;createElement = function(name, attributes) {   var key, obj, val;   if (attributes == n...
Splats*splatter = (first, second, others...) ->  console.log "First: #{first}"  console.log "Second: #{second}"  console.l...
Splats*var splatter,  __slice = [].slice;splatter = function() {   var first, others, second;   first = arguments[0], seco...
Loops & Comprehensionsfor someName in someArray  console.log someNamefor key, value of someObject  console.log "#{key}: #{...
Loops & Comprehensionsvar key, someName, value, _i, _len;for (_i = 0, _len = someArray.length; _i < _len; _i++) {  someNam...
Loops & Comprehensionsnumbers = [1..5]console.log number for number in numbers
Loops & Comprehensionsvar number, numbers, _i, _len;numbers = [1, 2, 3, 4, 5];for (_i = 0, _len = numbers.length; _i < _le...
Loops & Comprehensionsnumbers = [1..5]console.log number for number in numbers when number <= 3
Loops & Comprehensionsvar number, numbers, _i, _len;numbers = [1, 2, 3, 4, 5];for (_i = 0, _len = numbers.length; _i < _le...
Loops & Comprehensionsnumbers = [1, 2, 3, 4, 5]low_numbers = (number * 2 for number in numbers when number <= 3)console.lo...
Loops & Comprehensionsvar low_numbers, number, numbers;numbers = [1, 2, 3, 4, 5];low_numbers = (function() {  var _i, _len...
Classesclass Employeeemp = new Employee()emp.firstName = "Mark"
Classesvar Employee, emp;Employee = (function() {  Employee.name = Employee;  function Employee() {}  return Employee;})()...
Classesclass Employee  constructor: (@options = {}) ->  salary: ->    @options.salary ?= "$250,000"emp = new Employee()con...
Classesvar Employee, emp;Employee = (function() {  Employee.name = Employee;  function Employee(options) {    this.options...
Extending Classesclass Manager extends Employee  constructor: ->    super    @options.salary ?= "$500,000"manager = new Ma...
Extending Classesvar Manager, manager,  __hasProp = {}.hasOwnProperty,  __extends = function(child, parent) { for (var key...
Extending Classesclass Manager extends Employee  constructor: ->    super    @options.salary ?= "$500,000"  salary: ->    ...
Extending Classesvar Manager, manager,  __hasProp = {}.hasOwnProperty,  __extends = function(child, parent) { for (var key...
Bound Functionsclass User  constructor: (@name) ->  sayHi: ->    console.log "Hello #{@name}"bob = new User(bob)mary = new...
Bound Functionsabout to execute callback...Hello undefined...executed callbackabout to execute callback...Hello undefined....
Bound Functionsclass User  constructor: (@name) ->  sayHi: ->    console.log "Hello #{@name}"bob = new User(bob)mary = new...
Bound Functionsclass User  constructor: (@name) ->  sayHi: ->    console.log "Hello #{@name}"bob = new User(bob)mary = new...
Bound Functionsclass User  constructor: (@name) ->  sayHi: =>    console.log "Hello #{@name}"bob = new User(bob)mary = new...
Bound Functionsabout to execute callback...Hello bob...executed callbackabout to execute callback...Hello mary...executed ...
Bound Functionsclass User  constructor: (@name) ->  sayHi: =>    console.log "Hello #{@name}"
Bound Functionsvar User,  __bind = function(fn, me){ return function(){ return fn.apply(me,arguments); }; };User = (functi...
FINALLYOne of my favorite features
Existential Operatorif foo?  console.log "foo"console.log "foo" if foo?
Existential Operatorif (typeof foo !== "undefined" && foo !== null) {  console.log("foo");}if (typeof foo !== "undefined" ...
WAIT! IT GETS BETTER!
Existential Operatorconsole?.log "foo"
Existential Operatorconsole?.log "foo"if (typeof console !== "undefined" && console !== null) {  console.log("foo");}
Existential Operatorif currentUser?.firstName?  console.log currentUser.firstName
Existential Operatorif currentUser?.firstName?  console.log currentUser.firstNameif ((typeof currentUser !== "undefined" &...
What Didn’t I Cover?ScopingSecurityStrict ModeFixes common ‘mistakes’OperatorsThe `do` keywordPlenty more!
Thank You
Thank YoumyName = "Mark Bates"you.should buyBook("Programming in CoffeeScript") .at("http://books.markbates.com")you.shoul...
CoffeeScript for the Rubyist
CoffeeScript for the Rubyist
CoffeeScript for the Rubyist
Upcoming SlideShare
Loading in...5
×

CoffeeScript for the Rubyist

4,638

Published on

Presented at RailsConf 2012 on April 23rd, 2012. This talk is an intro to the CoffeeScript language from a Rubyists perspective.

Published in: Technology
1 Comment
7 Likes
Statistics
Notes
No Downloads
Views
Total Views
4,638
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
66
Comments
1
Likes
7
Embeds 0
No embeds

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
  • CoffeeScript for the Rubyist

    1. 1. COFFEESCRIPT A Rubyist’s Love Affair
    2. 2. Mark Bates
    3. 3. DistributedProgramming with Ruby Addison-Wesley 2009http://books.markbates.com
    4. 4. Programming in CoffeeScript Addison-Wesley 2012 http://books.markbates.com
    5. 5. A (BRIEF) HISTORY LESSON
    6. 6. “I need to come up with a scripting languagefor web browsers. I know! Ill make it cool and Lispy! ” Dramatic Re-enactment (1995)
    7. 7. “ 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)
    8. 8. 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; };});
    9. 9. FAST FORWARD About 15 Years
    10. 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. 11. 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
    12. 12. WHAT IS COFFEESCRIPT?
    13. 13. What is CoffeeScript?
    14. 14. What is CoffeeScript?“A little language that compiles into JavaScript.”
    15. 15. What is CoffeeScript?“A little language that compiles into JavaScript.”Easily integrates with your current JavaScript
    16. 16. What is CoffeeScript?“A little language that compiles into JavaScript.”Easily integrates with your current JavaScriptEasier to read, write, maintain, refactor, etc...
    17. 17. 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.
    18. 18. 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.
    19. 19. What CoffeeScript Is Not?Not Magic!Limited by what JavaScript can already do
    20. 20. “I’m happy writing JavaScript.I don’t need to learn another language. ”
    21. 21. FINE WITH ME
    22. 22. BUT...
    23. 23. .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
    24. 24. .MODEL SMALL DISP: Assembly 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
    25. 25. #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;}
    26. 26. 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; }}
    27. 27. def fibonacci Ruby a = 0 b = 1 100.times do printf("%dn", a) a, b = b, a + b endend
    28. 28. “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! ”
    29. 29. SAME GOES FORCOFFEESCRIPT
    30. 30. SYNTAX
    31. 31. $(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
    32. 32. Syntax RulesNo semi-colons (ever!)No curly braces*No ‘function’ keywordRelaxed parenthesesWhitespace significant formatting
    33. 33. 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"
    34. 34. Parentheses Rulesvar noArg1, noArg2, withArg;noArg1 = function() {};noArg2 = function() {};withArg = function(arg) {};noArg1();noArg2();withArg("bar");withArg("bar");
    35. 35. Parentheses Rules# Bad:$ "#some_id" .text()# $("#some_id".text());# Good:$("#some_id").text()# $("#some_id").text();
    36. 36. Whitespace
    37. 37. Whitespace$(function() {success = function(data) {if (data.errors != null) {alert("There was an error!");} else {$("#content").text(data.message);}};$.get(/users, success, json);});
    38. 38. 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);});
    39. 39. 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);});
    40. 40. Whitespace$ -> success = (data) -> if data.errors? alert "There was an error!" else $("#content").text(data.message) $.get(/users, success, json)
    41. 41. Whitespace$(function() { var success; success = function(data) { if (data.errors != null) { return alert("There was an error!"); } else { return $("#content").text(data.message); } }; return $.get(/users, success, json);});
    42. 42. RUBYSCRIPT?
    43. 43. Conditionals
    44. 44. Conditionalsif true doSomething()unless true doSomething()
    45. 45. Conditionalsif true doSomething() if true doSomething() doSomething() unless trueunless true doSomething()
    46. 46. Conditionalsif true doSomething() if true doSomething() doSomething() unless trueunless true doSomething() if true doSomething() else doSomethingElse()
    47. 47. Objects/HashessomeObject = {conf: "RailsConf", talk: "CoffeeScript"}someObject = conf: "RailsConf" talk: "CoffeeScript"someFunction(conf: "RailsConf", talk: "CoffeeScript")
    48. 48. Objects/Hashesvar someObject;someObject = { conf: "RailsConf", talk: "CoffeeScript"};someObject = { conf: "RailsConf", talk: "CoffeeScript"};someFunction({ conf: "RailsConf", talk: "CoffeeScript"});
    49. 49. Rangesa = [1..5]b = [1...5]c = [1..100]d = [100..1]
    50. 50. Rangesa = [1..5] var a, b, c, d, _i, _j, _results, _results1; a = [1, 2, 3, 4, 5];b = [1...5] b = [1, 2, 3, 4];c = [1..100] c = (function() { _results = [];d = [100..1] for (_i = 1; _i <= 100; _i++){ _results.push(_i); } return _results; }).apply(this); d = (function() { _results1 = []; for (_j = 100; _j >= 1; _j--){ _results1.push(_j); } return _results1; }).apply(this);
    51. 51. String Interpolationname = "RailsConf 2012"console.log "Hello #{name}"# Hello RailsConf 2012console.log Hello #{name}# Hello #{name}
    52. 52. String Interpolationname = "RailsConf 2012" var name;console.log "Hello #{name}" name = "RailsConf 2012";# Hello RailsConf 2012 console.log("Hello " + name);console.log Hello #{name}# Hello #{name} console.log(Hello #{name});
    53. 53. 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>"""
    54. 54. 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>";
    55. 55. Functionsp = (name) -> console.log "Hello #{name}"p(RailsConf 2012)
    56. 56. Functionsvar p;p = function(name) { return console.log("Hello " + name);};p(RailsConf 2012);
    57. 57. Functionsp = (name)-> console.log "Hello #{name}"p(RailsConf 2012)
    58. 58. Functionsp = (name)-> console.log "Hello #{name}" CoffeeScriptp(RailsConf 2012)
    59. 59. Functionsp = (name)-> console.log "Hello #{name}" CoffeeScriptp(RailsConf 2012)p = ->(name) { puts "Hello #{name}"} Ruby 1.9p.call(RailsConf 2012)
    60. 60. Default ArgumentscreateElement = (name, attributes = {}) -> obj = document.createElement name for key, val of attributes obj.setAttribute key, val obj
    61. 61. Default Argumentsvar createElement;createElement = function(name, attributes) { var key, obj, val; if (attributes == null) { attributes = {}; } obj = document.createElement(name); for (key in attributes) { val = attributes[key]; obj.setAttribute(key, val); } return obj;};
    62. 62. Splats*splatter = (first, second, others...) -> console.log "First: #{first}" console.log "Second: #{second}" console.log "Others: #{others.join(, )}"splatter [1..5]...
    63. 63. Splats*var splatter, __slice = [].slice;splatter = function() { var first, others, second; first = arguments[0], second = arguments[1], others = 3<= arguments.length ? __slice.call(arguments, 2) : []; console.log("First: " + first); console.log("Second: " + second); return console.log("Others: " + (others.join(, )));};splatter.apply(null, [1, 2, 3, 4, 5]);
    64. 64. Loops & Comprehensionsfor someName in someArray console.log someNamefor key, value of someObject console.log "#{key}: #{value}"
    65. 65. 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);}
    66. 66. Loops & Comprehensionsnumbers = [1..5]console.log number for number in numbers
    67. 67. 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);}
    68. 68. Loops & Comprehensionsnumbers = [1..5]console.log number for number in numbers when number <= 3
    69. 69. 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); }}
    70. 70. 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 ]
    71. 71. 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);
    72. 72. Classesclass Employeeemp = new Employee()emp.firstName = "Mark"
    73. 73. Classesvar Employee, emp;Employee = (function() { Employee.name = Employee; function Employee() {} return Employee;})();emp = new Employee();emp.firstName = "Mark";
    74. 74. 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"
    75. 75. 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());
    76. 76. Extending Classesclass Manager extends Employee constructor: -> super @options.salary ?= "$500,000"manager = new Manager()console.log manager.salary() # "$500,000"
    77. 77. 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); if ((_base = this.options).salary == null) { _base.salary = "$500,000"; } } return Manager;})(Employee);manager = new Manager();console.log(manager.salary());
    78. 78. Extending Classesclass Manager extends Employee constructor: -> super @options.salary ?= "$500,000" salary: -> "#{super} + $10k"manager = new Manager()console.log manager.salary() # "$500,000 + $10k"
    79. 79. 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); if ((_base = this.options).salary == null) { _base.salary = "$500,000"; } } Manager.prototype.salary = function() { return "" + Manager.__super__.salary.apply(this, arguments) + " + $10k"; }; return Manager;})(Employee);manager = new Manager();console.log(manager.salary());
    80. 80. 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)
    81. 81. Bound Functionsabout to execute callback...Hello undefined...executed callbackabout to execute callback...Hello undefined...executed callback
    82. 82. 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)
    83. 83. 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)
    84. 84. 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)
    85. 85. Bound Functionsabout to execute callback...Hello bob...executed callbackabout to execute callback...Hello mary...executed callback
    86. 86. Bound Functionsclass User constructor: (@name) -> sayHi: => console.log "Hello #{@name}"
    87. 87. 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;})();
    88. 88. FINALLYOne of my favorite features
    89. 89. Existential Operatorif foo? console.log "foo"console.log "foo" if foo?
    90. 90. Existential Operatorif (typeof foo !== "undefined" && foo !== null) { console.log("foo");}if (typeof foo !== "undefined" && foo !== null) { console.log("foo");}
    91. 91. WAIT! IT GETS BETTER!
    92. 92. Existential Operatorconsole?.log "foo"
    93. 93. Existential Operatorconsole?.log "foo"if (typeof console !== "undefined" && console !== null) { console.log("foo");}
    94. 94. Existential Operatorif currentUser?.firstName? console.log currentUser.firstName
    95. 95. Existential Operatorif currentUser?.firstName? console.log currentUser.firstNameif ((typeof currentUser !== "undefined" && currentUser !==null ? currentUser.firstName : void 0) != null) { console.log(currentUser.firstName);}
    96. 96. What Didn’t I Cover?ScopingSecurityStrict ModeFixes common ‘mistakes’OperatorsThe `do` keywordPlenty more!
    97. 97. Thank You
    98. 98. Thank YoumyName = "Mark Bates"you.should buyBook("Programming in CoffeeScript") .at("http://books.markbates.com")you.should followMe(@markbates)
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×