Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

CoffeeScript - A Rubyist's Love Affair

3,962 views

Published on

Presented on 8/9/2011 to the Boston Ruby User's Group, this presentation talks about certain aspects of CoffeeScript and how it relates to Ruby.

Published in: Technology, Business
  • Be the first to comment

CoffeeScript - A Rubyist's Love Affair

  1. 1. CoffeeScriptA Rubyist’s Love Affair
  2. 2. Mark BatesRuby/RailsConsultantAuthor of“DistributedProgramming withRuby”
  3. 3. “Insert Book Name Here”
  4. 4. What CoffeeScript is not!
  5. 5. No Just “Lack of Punctuation!
  6. 6. NOT RJS!!!
  7. 7. RJS Examplepage.replace_html(tasks-completed,Task.completed_count)page.replace_html(tasks-remaining,Task.remaining_count)page.replace_html(task-status- + @task.id.to_s,@task.status.description)page.visual_effect(:highlight, task-item- +@task.id.to_s, :duration => 1.0)
  8. 8. So what isCoffeeScript?
  9. 9. CoffeeScript is...“a little language that compiles intoJavaScript”Easier to read and writeA hybrid of Ruby and PythonHelpful
  10. 10. So why should Iembrace (and love) CoffeeScript?
  11. 11. String Interpolation name = Mark "Hello #{name}"
  12. 12. var name;name = Mark;"Hello " + name;
  13. 13. Heredochtml = """ <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>"""
  14. 14. var html;html = "<div class="comment" id="tweet-"+ tweet.id_str + "">n <hr>n <divclass=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>";
  15. 15. Ranges# 1, 2, 3, 4, 5[1..5]# 1,..., 4[1...5]#1,...,500[1..500]#5, 4, 3, 2, 1[5..1]#500,...,1[500..1]
  16. 16. var _i, _j, _results, _results2;[1, 2, 3, 4, 5];[1, 2, 3, 4];(function() { _results = []; for (_i = 1; _i <= 500; _i++){ _results.push(_i); } return _results;}).apply(this, arguments);[5, 4, 3, 2, 1];(function() { _results2 = []; for (_j = 500; _j >= 1; _j--){ _results2.push(_j); } return _results2;}).apply(this, arguments);
  17. 17. Ruby Style ConditionalsUnlessIn-line Conditionals
  18. 18. Conditionalsunless a console.log "a is false"console.log "a is false" unless a
  19. 19. if (!a) { console.log("a is false");}if (!a) { console.log("a is false");}
  20. 20. FunctionsBound FunctionsDefault ArgumentsSplatted Arguments
  21. 21. Regular Functionsp = (name)-> console.log "hello: #{name}"p mark
  22. 22. var p;p = function(name) { return console.log("hello: " + name);};p(mark);
  23. 23. Regular Functionsp = (name)-> console.log "hello: #{name}"p mark
  24. 24. Regular Functionsp = (name)-> console.log "hello: #{name}" CoffeeScriptp markp = ->(name) { puts "hello: #{name}"} Ruby 1.9p.call mark
  25. 25. Bound Functions class Person def initialize(name) @name = name end def bind binding end end p = Person.new(mark) eval "puts @name", p.bind
  26. 26. Bound FunctionsfetchData: => url = "http://search.twitter.com/search.json?q=#{encodeURIComponent(@hash_tag)}&rpp=#{@max_results}&callback=?" $.get url, {}, @handleData, jsonhandleData: (data) => if data[error]? @handleError() if data.results.length is 0 and @fall_back @handleEmptyData() else if data.results.length > 0 setTimeout (=> @fetchData()), 10000 @render data
  27. 27. var __bind = function(fn, me){ return function(){ return fn.apply(me,arguments); }; };({ fetchData: __bind(function() { var url; url = "http://search.twitter.com/search.json?q=" +(encodeURIComponent(this.hash_tag)) + "&rpp=" + this.max_results + "&callback=?"; return $.get(url, {}, this.handleData, json); }, this), handleData: __bind(function(data) { if (data[error] != null) { this.handleError(); } if (data.results.length === 0 && this.fall_back) { return this.handleEmptyData(); } else if (data.results.length > 0) { setTimeout((__bind(function() { return this.fetchData(); }, this)), 10000); return this.render(data); } }, this)});
  28. 28. Default ArgumentscreateElement: (name, attributes = {}) -> obj = document.createElement name for key, val of attributes obj.setAttribute key, val obj
  29. 29. ({ 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; }});
  30. 30. Splatted Argumentssplatter = (first, second, others...) -> console.log "First: #{first}" console.log "Second: #{second}" console.log "Others: #{others.join(, )}"splatter [1..5]...
  31. 31. var splatter;var __slice = Array.prototype.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]);
  32. 32. Array Looparr = [1..5]for num in arr console.log num
  33. 33. var arr, num, _i, _len;arr = [1, 2, 3, 4, 5];for (_i = 0, _len = arr.length; _i < _len; _i++) { num = arr[_i]; console.log(num);}
  34. 34. Hash Loopfor key, val of attributes console.log "key: #{key}" console.log "val: #{val}"
  35. 35. var key, val;for (key in attributes) { val = attributes[key]; console.log("key: " + key); console.log("val: " + val);}
  36. 36. ClassesEasy To DefineEasy To ExtendKeep Code Clean
  37. 37. Classesclass Employee constructor: (@name, @options = {})-> job: -> @options.jobmark = new Employee(Mark, job: Developer)mark.job() # => Developermark.name # => Mark
  38. 38. var Employee, mark;Employee = (function() { function Employee(name, options) { this.name = name; this.options = options != null ? options : {}; } Employee.prototype.job = function() { return this.options.job; }; return Employee;})();mark = new Employee(Mark, { job: Developer});mark.job();mark.name;
  39. 39. Extending Classesclass Manager extends Employee job: -> "$$$ #{super}"steve = new Manager(Steve, job: CEO)steve.job() # => $$$ CEOsteve.name # => Steve
  40. 40. var Manager, steve;var __hasProp = Object.prototype.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() { __extends(Manager, Employee); function Manager() { Manager.__super__.constructor.apply(this, arguments); } Manager.prototype.job = function() { return "$$$ " + Manager.__super__.job.apply(this, arguments); }; return Manager;})();steve = new Manager(Steve, { job: CEO});steve.job();steve.name;
  41. 41. @class User constructor: (@name)-> @new_record = true @find: (id)-> # do some work
  42. 42. @class User constructor: (name)-> @name = name @new_record = true @find: (id)-> # do some work
  43. 43. var User;User = (function() { function User(name) { this.name = name; this.new_record = true; } User.find = function(id) {}; return User;})();
  44. 44. Thank You @markbateshttp://www.markbates.com

×