CoffeeScript Design Patterns

6,519 views

Published on

Talk given at Øredev 2011 by the author of http://pragprog.com/book/tbcoffee/coffeescript

Published in: Technology
1 Comment
19 Likes
Statistics
Notes
No Downloads
Views
Total views
6,519
On SlideShare
0
From Embeds
0
Number of Embeds
61
Actions
Shares
0
Downloads
54
Comments
1
Likes
19
Embeds 0
No embeds

No notes for slide

CoffeeScript Design Patterns

  1. 1. CoffeeScript Design Patterns Presented by Trevor Burnham at Øredev 2011
  2. 2. PrefaceThe Compleat History of JavaScript
  3. 3. 1995 to 2003: Ancient JavaScript
  4. 4. Paul Graham on JavaScript: “I would not even use Javascript, if I were you... Most of the Javascript I see on the Web isn’t necessary, and much of it breaks.” (“The Other Road Ahead,” 2001)
  5. 5. 2004-2008: Medieval JavaScript
  6. 6. Ajax!
  7. 7. Solid libraries!...And probably others!
  8. 8. 2009-: Modern JavaScript
  9. 9. The New First Language?
  10. 10. JavaScript is Now FAST!
  11. 11. JavaScript on the Server
  12. 12. Everyone Who Knows JavaScript Feels Like Superman!
  13. 13. https://github.com/rails/rails/commit/9f09aeb8273177fc2d09ebdafcc76ee8eb56fe33
  14. 14. “A Little Language”
  15. 15. David Heinemeier Hansson
  16. 16. Ward Cunningham “CoffeeScript and the environment will all the powerful browsers is the closest I felt to the power I had twenty years ago in Smalltalk.” —Interview with InfoQ, November 2011
  17. 17. Brendan Eich (!) CoffeeScript user
  18. 18. Eich + Ashkenas at JsConf 2011
  19. 19. ICoffeeScript: A Bird’s-Eye View
  20. 20. Things CoffeeScript Isn’t:Ruby/PythonjQueryGWTDartalert  Hello  World!    #  1  line!!!
  21. 21. “It’s Just JavaScript”a  =  b          #  var  a  =  b;x  is  y        #  x  ===  y;f  arg          #  f(arg);f  =  -­‐>  x#  var  f  =  function()  {return  x;};No standard library. No additional types.Nothing but sweet, sweet syntax!
  22. 22. More Syntactic Sugarf()  if  z    #  if  (z)  {  f();  }f?()            #  if  (...)  {  f();  }obj?            #  obj  !=  null;key:  val    #  {key:  val};Plus, significant whitespace...
  23. 23. The Beauty of Indentation source: https://github.com/TrevorBurnham/connect-assetsfor  ext  in  exts    sourcePath  =  stripExt(route)  +  ".#{ext}"    try        stats  =  fs.statSync  @absPath(sourcePath)        if  ext  is  css            {mtime}  =  stats            if  timeEq  mtime,  @cache.map[route]?.mtime                css  =  @cache.map[route].data            else                css  =  fs.readFileSync  @absPath(sourcePath)
  24. 24. The Curly-Braced Equivalentvar  css,  ext,  mtime,  sourcePath,  stats,  _i,  _len,  _ref;for  (_i  =  0,  _len  =  exts.length;  _i  <  _len;  _i++)  {    ext  =  exts[_i];    sourcePath  =  stripExt(route)  +  ("."  +  ext);    try  {        stats  =  fs.statSync(this.absPath(sourcePath));        if  (ext  ===  css)  {            mtime  =  stats.mtime;            if  (timeEq(mtime,  (_ref  =  this.cache.map[route])  !=  null  ?  _ref.mtime  :  void  0))  {                css  =  this.cache.map[route].data;            }  else  {                css  =  fs.readFileSync(this.absPath(sourcePath));            }        }    }  catch  (_e)  {}}
  25. 25. IIBaked-In Patterns
  26. 26. The WrapperCoffeeScript in:console.log  i  for  i  in  arrJavaScript out:(function()  {    var  i,  _i,  _len;    for  (_i  =  0,  _len  =  arr.length;  _i  <  _len;  _i++)  {        i  =  arr[_i];        console.log(i);    }}).call(this);
  27. 27. Why Use The Wrapper? source: http://stackoverflow.com/questions/5211638/
  28. 28. Things That Don’t Create Scope in JavaScriptConditionalsParenthesesObjectsLoopsFiles (!)
  29. 29. Don’t Let This Happen to You!http://blog.meloncard.com/post/12175941935
  30. 30. CoffeeScripters Need No var!console.log  i  for  i  in  arr(function()  {    var  i,  _i,  _len;    for  (_i  =  0,  _len  =  arr.length;  _i  <  _len;  _i++)  {        i  =  arr[_i];        console.log(i);    }}).call(this);
  31. 31. JS Best Practices, CoffeeScript Defaults!Parappa the WrapperProper IndentationAvoiding ==Packaging extensible objects as “classes”
  32. 32. Plain, Ordinary JavaScript Objects lifeEtAl = answer: 42 showAnswer: -> console.log @answer #  @  ==  this lifeEtAl.showAnswer() setTimeout  lifeEtAl.showAnswer,  10
  33. 33. Classes to the Rescue!class LifeEtAl answer: 42 showAnswer: => # fat -> console.log @answermyLife = new LifeEtAlsetTimeout myLife.showAnswer, 10
  34. 34. How About a Little Privacy?class LifeEtAl answer = 42 showAnswer: -> console.log answermyLife = new LifeEtAlsetTimeout myLife.showAnswer, 10
  35. 35. Using a Constructorclass Circle twoPi = Math.PI * 2 constructor: (@radius) -> @radiusSqr = Math.pow @radius, 2 diameter: => twoPi * @radius area: => Math.PI * @radiusSqrc = new Circle(5)console.log c.diameter() # 31.4159console.log c.area() # 78.5398
  36. 36. Let’s Try a Little Inheritanceclass  Document  extends  Backbone.Model    defaults:        title:  Untitled
  37. 37. Doing Inheritance via a JavaScript Libraryvar  Document  =  Backbone.Model.extend({    defaults:  {        title:  Untitled    }});
  38. 38. I. The Prototype Chainclass  Document  extends  Backbone.Model    defaults:        title:  Untitleddoc  =  new  DocumentDocument::  is  Document.prototypedoc.defaults  is  Document::defaultsdoc.validate  is  Backbone.Model::validatedoc.hasOwnProperty  is  Object::hasOwnProperty
  39. 39. II. Superclass Methods Can Be Invoked With superclass  AppleDevice    constructor:  (cost)  -­‐>        bankAccount.deduct  cost        bankAccount.deduct  cost  /  4  #  AppleCareclass  iPhone  extends  AppleDevice    constructor:  (cost)  -­‐>        super    #  equivalent  to  super(cost)        setInterval  (-­‐>            bankAccount.deduct  cost  /  4        ),  ONE_MONTH
  40. 40. III. Superclass Properties are Copied class  Primate    @thumbs  =  opposable class  Human  extends  Primate Human.thumbs  is  Primate.thumbs  is  opposable
  41. 41. MVC
  42. 42. IIIProject Patterns
  43. 43. CompilingRails 3.1 / other web frameworksMiddleman / other static web frameworksLiveReload / CodeKit (Mac)coffee -wWrite a Cakefile
  44. 44. A Piece of Cake source: https://github.com/sstephenson/node-coffee-project/build = (watch, callback) ->  if typeof watch is function    callback = watch    watch = false  options = [-c, -o, lib, src]  options.unshift -w if watch  coffee = spawn coffee, options  coffee.stdout.on data, (data) -> print data.toString()  coffee.stderr.on data, (data) -> print data.toString()  coffee.on exit, (status) -> callback?() if status is 0task build, Compile CoffeeScript source files, ->  build()task test, Run the test suite, ->  build ->    require.paths.unshift __dirname + "/lib"    {reporters} = require nodeunit    process.chdir __dirname    reporters.default.run [test]
  45. 45. Another Piece of Cake source: https://github.com/TrevorBurnham/connect-assetstask build, Compile CoffeeScript source files, ->  build()task test, Run the test suite (and re-run if anything changes), ->  suite = null  build ->    do runTests = ->      suite?.kill()      suiteNames = [        DevelopmentIntegration        ProductionIntegration      ]      suiteIndex = 0      do runNextTestSuite = ->        return unless suiteName = suiteNames[suiteIndex]        suite = spawn "coffee", ["-e", "{reporters} = require nodeunit;reporters.default.run [#{suiteName}.coffee]"], cwd: test        suite.stdout.on data, (data) -> print data.toString()        suite.stderr.on data, (data) -> print data.toString()        suite.on exit, -> suiteIndex++; runNextTestSuite()      invoke docs # lest I forget    testWatcher = watchTree test, sample-rate: 5    testWatcher.on fileModified, runTests    libWatcher = watchTree src, sample-rate: 5    libWatcher.on fileModified, -> build(-> runTests())
  46. 46. Documentingsource: http://coffeescript.org/documentation/docs/grammar.html
  47. 47. TestingQUnitNodeunitJasmine BDDjs-test-driver
  48. 48. IVThe Future
  49. 49. A New Area of Confusion... http://stackoverflow.com/questions/7996883/
  50. 50. Where is Your Code?http://stackoverflow.com/questions/7996883/
  51. 51. Breaking the Client-Server BoundariesStitch (37signals)browserifyjsdom
  52. 52. “This book helps readers become better JavaScripters in the process of learning CoffeeScript. What’s more, this book is a blast to read.” —Brendan Eichhttp://pragprog.com/book/tbcoffee/coffeescript
  53. 53. Search KickStarter for “Rethink”
  54. 54. Thanks! Questions?Follow me @trevorburnham and @coffeescript

×