SlideShare a Scribd company logo
CoffeeScript Design Patterns

 Presented by Trevor Burnham at Øredev 2011
Preface
The Compleat History of JavaScript
1995 to 2003: Ancient JavaScript
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)
2004-2008: Medieval JavaScript
Ajax!
Solid libraries!




...And probably others!
2009-: Modern JavaScript
The New First Language?
JavaScript is Now FAST!
JavaScript on the Server
Everyone Who Knows JavaScript
     Feels Like Superman!
https://github.com/rails/rails/commit/9f09aeb8273177fc2d09ebdafcc76ee8eb56fe33
“A Little Language”
David Heinemeier Hansson
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
Brendan Eich (!)



         CoffeeScript user
Eich + Ashkenas at JsConf 2011
I
CoffeeScript: A Bird’s-Eye View
Things CoffeeScript Isn’t:

Ruby/Python
jQuery
GWT
Dart

alert	
  'Hello	
  World!'	
  	
  #	
  1	
  line!!!
“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!
More Syntactic Sugar

f()	
  if	
  z	
  	
  #	
  if	
  (z)	
  {	
  f();	
  }
f?()	
  	
  	
  	
  	
  	
  #	
  if	
  (...)	
  {	
  f();	
  }
obj?	
  	
  	
  	
  	
  	
  #	
  obj	
  !=	
  null;
key:	
  val	
  	
  #	
  {key:	
  val};
Plus, significant whitespace...
The Beauty of Indentation
            source: https://github.com/TrevorBurnham/connect-assets


for	
  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)
The Curly-Braced Equivalent
var	
  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)	
  {}
}
II
Baked-In Patterns
The Wrapper
CoffeeScript in:
console.log	
  i	
  for	
  i	
  in	
  arr
JavaScript out:
(function()	
  {
	
  	
  var	
  i,	
  _i,	
  _len;
	
  	
  for	
  (_i	
  =	
  0,	
  _len	
  =	
  arr.length;	
  _i	
  <	
  _len;	
  _i++)	
  {
	
  	
  	
  	
  i	
  =	
  arr[_i];
	
  	
  	
  	
  console.log(i);
	
  	
  }
}).call(this);
Why Use The Wrapper?
  source: http://stackoverflow.com/questions/5211638/
Things That Don’t Create Scope
         in JavaScript
Conditionals
Parentheses
Objects
Loops
Files (!)
Don’t Let This Happen to You!




http://blog.meloncard.com/post/12175941935
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);
JS Best Practices,
     CoffeeScript Defaults!

Parappa the Wrapper
Proper Indentation
Avoiding ==
Packaging extensible objects as “classes”
Plain, Ordinary JavaScript Objects

  lifeEtAl =
    answer: 42
    showAnswer: ->
      console.log @answer #	
  @	
  ==	
  this

  lifeEtAl.showAnswer()

  setTimeout	
  lifeEtAl.showAnswer,	
  10
Classes to the Rescue!

class LifeEtAl
  answer: 42
  showAnswer: => # fat ->
    console.log @answer

myLife = new LifeEtAl

setTimeout myLife.showAnswer, 10
How About a Little Privacy?

class LifeEtAl
  answer = 42
  showAnswer: ->
    console.log answer

myLife = new LifeEtAl

setTimeout myLife.showAnswer, 10
Using a Constructor
class Circle
  twoPi = Math.PI * 2
  constructor: (@radius) ->
    @radiusSqr = Math.pow @radius, 2
  diameter: => twoPi * @radius
  area: => Math.PI * @radiusSqr

c = new Circle(5)
console.log c.diameter() # 31.4159
console.log c.area()     # 78.5398
Let’s Try a Little Inheritance


class	
  Document	
  extends	
  Backbone.Model
	
  	
  defaults:
	
  	
  	
  	
  title:	
  'Untitled'
Doing Inheritance via a
       JavaScript Library

var	
  Document	
  =	
  Backbone.Model.extend({
	
  	
  defaults:	
  {
	
  	
  	
  	
  title:	
  'Untitled'
	
  	
  }
});
I. The Prototype Chain
class	
  Document	
  extends	
  Backbone.Model
	
  	
  defaults:
	
  	
  	
  	
  title:	
  'Untitled'

doc	
  =	
  new	
  Document

Document::	
  is	
  Document.prototype

doc.defaults	
  is	
  Document::defaults

doc.validate	
  is	
  Backbone.Model::validate

doc.hasOwnProperty	
  is	
  Object::hasOwnProperty
II. Superclass Methods Can Be
      Invoked With super
class	
  AppleDevice
	
  	
  constructor:	
  (cost)	
  -­‐>
	
  	
  	
  	
  bankAccount.deduct	
  cost
	
  	
  	
  	
  bankAccount.deduct	
  cost	
  /	
  4	
  #	
  AppleCare

class	
  iPhone	
  extends	
  AppleDevice
	
  	
  constructor:	
  (cost)	
  -­‐>
	
  	
  	
  	
  super	
  	
  #	
  equivalent	
  to	
  super(cost)
	
  	
  	
  	
  setInterval	
  (-­‐>
	
  	
  	
  	
  	
  	
  bankAccount.deduct	
  cost	
  /	
  4
	
  	
  	
  	
  ),	
  ONE_MONTH
III. Superclass Properties are Copied


   class	
  Primate
   	
  	
  @thumbs	
  =	
  'opposable'

   class	
  Human	
  extends	
  Primate

   Human.thumbs	
  is	
  Primate.thumbs	
  is	
  'opposable'
MVC
III
Project Patterns
Compiling

Rails 3.1 / other web frameworks
Middleman / other static web frameworks
LiveReload / CodeKit (Mac)
coffee -w
Write a Cakefile
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 0

task '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']
Another Piece of Cake
             source: https://github.com/TrevorBurnham/connect-assets

task '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())
Documenting
source: http://coffeescript.org/documentation/docs/grammar.html
Testing

QUnit
Nodeunit
Jasmine BDD
js-test-driver
IV
The Future
A New Area of Confusion...




   http://stackoverflow.com/questions/7996883/
Where is Your Code?




http://stackoverflow.com/questions/7996883/
Breaking the Client-Server
         Boundaries

Stitch (37signals)
browserify
jsdom
“This book helps
                        readers become better
                        JavaScripters in the
                        process of learning
                        CoffeeScript. What’s
                        more, this book is a
                        blast to read.”
                        —Brendan Eich



http://pragprog.com/book/tbcoffee/coffeescript
Search KickStarter for “Rethink”
Thanks! Questions?
Follow me @trevorburnham and @coffeescript

More Related Content

What's hot

Understand & develop ember addons
Understand & develop ember addonsUnderstand & develop ember addons
Understand & develop ember addonsDilip Kushwaha
 
Back to the future: Isomorphic javascript applications
Back to the future:  Isomorphic javascript applicationsBack to the future:  Isomorphic javascript applications
Back to the future: Isomorphic javascript applicationsLuciano Colosio
 
Drupal + selenium
Drupal + seleniumDrupal + selenium
Drupal + seleniumhernanibf
 
Automating Your Daily Tasks with Scripting - RubyConf 2015 Taiwan
Automating Your Daily Tasks with Scripting - RubyConf 2015 TaiwanAutomating Your Daily Tasks with Scripting - RubyConf 2015 Taiwan
Automating Your Daily Tasks with Scripting - RubyConf 2015 TaiwanAdler Hsieh
 
JavaScript Language Update 2016 (LLoT)
JavaScript Language Update 2016 (LLoT)JavaScript Language Update 2016 (LLoT)
JavaScript Language Update 2016 (LLoT)Teppei Sato
 
JRuby on Rails, Flying Saucer
JRuby on Rails, Flying SaucerJRuby on Rails, Flying Saucer
JRuby on Rails, Flying Sauceralexandermalfait
 
Concurrent Ruby Application Servers
Concurrent Ruby Application ServersConcurrent Ruby Application Servers
Concurrent Ruby Application ServersLin Jen-Shin
 
Ruby On Rails Introduction
Ruby On Rails IntroductionRuby On Rails Introduction
Ruby On Rails IntroductionThomas Fuchs
 
Introduction to Coffeescript
Introduction to CoffeescriptIntroduction to Coffeescript
Introduction to CoffeescriptIndies Services
 
Server-side JavaScript for the rest of us
Server-side JavaScript for the rest of usServer-side JavaScript for the rest of us
Server-side JavaScript for the rest of usKyle Simpson
 
CukeUp! 2012: Michael Nacos on Just enough infrastructure for product develop...
CukeUp! 2012: Michael Nacos on Just enough infrastructure for product develop...CukeUp! 2012: Michael Nacos on Just enough infrastructure for product develop...
CukeUp! 2012: Michael Nacos on Just enough infrastructure for product develop...Skills Matter Talks
 
Using Puppet in Small Infrastructures
Using Puppet in Small InfrastructuresUsing Puppet in Small Infrastructures
Using Puppet in Small InfrastructuresRachel Andrew
 
Bundler is the Best
Bundler is the BestBundler is the Best
Bundler is the Bestdead_arm
 
Cachopo - Scalable Stateful Services - Madrid Elixir Meetup
Cachopo - Scalable Stateful Services - Madrid Elixir MeetupCachopo - Scalable Stateful Services - Madrid Elixir Meetup
Cachopo - Scalable Stateful Services - Madrid Elixir MeetupAbel Muíño
 
Building Javascript Apps with the WordPress JSON API – LoopConf 2015
Building Javascript Apps with the WordPress JSON API – LoopConf 2015Building Javascript Apps with the WordPress JSON API – LoopConf 2015
Building Javascript Apps with the WordPress JSON API – LoopConf 2015Jake Spurlock
 
Backbone the Good Parts
Backbone the Good PartsBackbone the Good Parts
Backbone the Good PartsRenan Carvalho
 
Project development - preparing hell dish together – Oleksii Dashkevych
Project development - preparing hell dish together – Oleksii DashkevychProject development - preparing hell dish together – Oleksii Dashkevych
Project development - preparing hell dish together – Oleksii DashkevychRuby Meditation
 
What the WordPress REST API Means for Javascript Developers
What the WordPress REST API Means for Javascript DevelopersWhat the WordPress REST API Means for Javascript Developers
What the WordPress REST API Means for Javascript DevelopersJake Spurlock
 

What's hot (20)

Understand & develop ember addons
Understand & develop ember addonsUnderstand & develop ember addons
Understand & develop ember addons
 
Back to the future: Isomorphic javascript applications
Back to the future:  Isomorphic javascript applicationsBack to the future:  Isomorphic javascript applications
Back to the future: Isomorphic javascript applications
 
Drupal + selenium
Drupal + seleniumDrupal + selenium
Drupal + selenium
 
Ruby on Rails Presentation
Ruby on Rails PresentationRuby on Rails Presentation
Ruby on Rails Presentation
 
Automating Your Daily Tasks with Scripting - RubyConf 2015 Taiwan
Automating Your Daily Tasks with Scripting - RubyConf 2015 TaiwanAutomating Your Daily Tasks with Scripting - RubyConf 2015 Taiwan
Automating Your Daily Tasks with Scripting - RubyConf 2015 Taiwan
 
JavaScript Language Update 2016 (LLoT)
JavaScript Language Update 2016 (LLoT)JavaScript Language Update 2016 (LLoT)
JavaScript Language Update 2016 (LLoT)
 
JRuby on Rails, Flying Saucer
JRuby on Rails, Flying SaucerJRuby on Rails, Flying Saucer
JRuby on Rails, Flying Saucer
 
Concurrent Ruby Application Servers
Concurrent Ruby Application ServersConcurrent Ruby Application Servers
Concurrent Ruby Application Servers
 
Ruby On Rails Introduction
Ruby On Rails IntroductionRuby On Rails Introduction
Ruby On Rails Introduction
 
Introduction to Coffeescript
Introduction to CoffeescriptIntroduction to Coffeescript
Introduction to Coffeescript
 
Server-side JavaScript for the rest of us
Server-side JavaScript for the rest of usServer-side JavaScript for the rest of us
Server-side JavaScript for the rest of us
 
CukeUp! 2012: Michael Nacos on Just enough infrastructure for product develop...
CukeUp! 2012: Michael Nacos on Just enough infrastructure for product develop...CukeUp! 2012: Michael Nacos on Just enough infrastructure for product develop...
CukeUp! 2012: Michael Nacos on Just enough infrastructure for product develop...
 
Using Puppet in Small Infrastructures
Using Puppet in Small InfrastructuresUsing Puppet in Small Infrastructures
Using Puppet in Small Infrastructures
 
Bundler is the Best
Bundler is the BestBundler is the Best
Bundler is the Best
 
Cachopo - Scalable Stateful Services - Madrid Elixir Meetup
Cachopo - Scalable Stateful Services - Madrid Elixir MeetupCachopo - Scalable Stateful Services - Madrid Elixir Meetup
Cachopo - Scalable Stateful Services - Madrid Elixir Meetup
 
Building Javascript Apps with the WordPress JSON API – LoopConf 2015
Building Javascript Apps with the WordPress JSON API – LoopConf 2015Building Javascript Apps with the WordPress JSON API – LoopConf 2015
Building Javascript Apps with the WordPress JSON API – LoopConf 2015
 
Backbone the Good Parts
Backbone the Good PartsBackbone the Good Parts
Backbone the Good Parts
 
Project development - preparing hell dish together – Oleksii Dashkevych
Project development - preparing hell dish together – Oleksii DashkevychProject development - preparing hell dish together – Oleksii Dashkevych
Project development - preparing hell dish together – Oleksii Dashkevych
 
What the WordPress REST API Means for Javascript Developers
What the WordPress REST API Means for Javascript DevelopersWhat the WordPress REST API Means for Javascript Developers
What the WordPress REST API Means for Javascript Developers
 
Ansible 202 - sysarmy
Ansible 202 - sysarmyAnsible 202 - sysarmy
Ansible 202 - sysarmy
 

Viewers also liked (16)

Unidad pagina web
Unidad  pagina webUnidad  pagina web
Unidad pagina web
 
Estructura de una pagina web 2
Estructura de una pagina web  2Estructura de una pagina web  2
Estructura de una pagina web 2
 
Estructura pagina web (1)
Estructura pagina web  (1)Estructura pagina web  (1)
Estructura pagina web (1)
 
Diseño web
Diseño webDiseño web
Diseño web
 
Marlon CV Updated
Marlon CV UpdatedMarlon CV Updated
Marlon CV Updated
 
Web
WebWeb
Web
 
6. Page Structure
6. Page Structure6. Page Structure
6. Page Structure
 
Que es un sitioweb
Que es un sitiowebQue es un sitioweb
Que es un sitioweb
 
Seo básico para non seo
Seo básico para non seoSeo básico para non seo
Seo básico para non seo
 
Best Practices for Structuring Your Web Content
Best Practices for Structuring Your  Web ContentBest Practices for Structuring Your  Web Content
Best Practices for Structuring Your Web Content
 
Espring
EspringEspring
Espring
 
Los Dominios de Internet
Los Dominios de InternetLos Dominios de Internet
Los Dominios de Internet
 
Pag. web
Pag. webPag. web
Pag. web
 
Shopline and Crafties Seminar
Shopline and Crafties SeminarShopline and Crafties Seminar
Shopline and Crafties Seminar
 
Diseño pagina web- html
Diseño pagina web- html Diseño pagina web- html
Diseño pagina web- html
 
Manuales de HTML
Manuales de HTMLManuales de HTML
Manuales de HTML
 

Similar to CoffeeScript Design Patterns

[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVCAlive Kuo
 
JavaScript performance patterns
JavaScript performance patternsJavaScript performance patterns
JavaScript performance patternsStoyan Stefanov
 
Everything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the WebEverything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the WebJames Rakich
 
FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...
FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...
FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...Zhenzhong Xu
 
Slides
SlidesSlides
Slidesvti
 
Solving the Riddle of Search: Using Sphinx with Rails
Solving the Riddle of Search: Using Sphinx with RailsSolving the Riddle of Search: Using Sphinx with Rails
Solving the Riddle of Search: Using Sphinx with Railsfreelancing_god
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreEngineor
 
node.js, javascript and the future
node.js, javascript and the futurenode.js, javascript and the future
node.js, javascript and the futureJeff Miccolis
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyDavid Padbury
 
Keeping Spark on Track: Productionizing Spark for ETL
Keeping Spark on Track: Productionizing Spark for ETLKeeping Spark on Track: Productionizing Spark for ETL
Keeping Spark on Track: Productionizing Spark for ETLDatabricks
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011Nick Sieger
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescriptDavid Furber
 
Good practices for PrestaShop code security and optimization
Good practices for PrestaShop code security and optimizationGood practices for PrestaShop code security and optimization
Good practices for PrestaShop code security and optimizationPrestaShop
 
Sinatra and JSONQuery Web Service
Sinatra and JSONQuery Web ServiceSinatra and JSONQuery Web Service
Sinatra and JSONQuery Web Servicevvatikiotis
 
CoffeeScript-Ruby-Tuesday
CoffeeScript-Ruby-TuesdayCoffeeScript-Ruby-Tuesday
CoffeeScript-Ruby-TuesdayEddie Kao
 

Similar to CoffeeScript Design Patterns (20)

[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC
 
Sprockets
SprocketsSprockets
Sprockets
 
JavaScript performance patterns
JavaScript performance patternsJavaScript performance patterns
JavaScript performance patterns
 
Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
 
"Javascript" por Tiago Rodrigues
"Javascript" por Tiago Rodrigues"Javascript" por Tiago Rodrigues
"Javascript" por Tiago Rodrigues
 
Everything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the WebEverything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the Web
 
FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...
FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...
FlinkForward Asia 2019 - Evolving Keystone to an Open Collaborative Real Time...
 
Slides
SlidesSlides
Slides
 
Solving the Riddle of Search: Using Sphinx with Rails
Solving the Riddle of Search: Using Sphinx with RailsSolving the Riddle of Search: Using Sphinx with Rails
Solving the Riddle of Search: Using Sphinx with Rails
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack Encore
 
node.js, javascript and the future
node.js, javascript and the futurenode.js, javascript and the future
node.js, javascript and the future
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
Keeping Spark on Track: Productionizing Spark for ETL
Keeping Spark on Track: Productionizing Spark for ETLKeeping Spark on Track: Productionizing Spark for ETL
Keeping Spark on Track: Productionizing Spark for ETL
 
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescript
 
Good practices for PrestaShop code security and optimization
Good practices for PrestaShop code security and optimizationGood practices for PrestaShop code security and optimization
Good practices for PrestaShop code security and optimization
 
Play framework
Play frameworkPlay framework
Play framework
 
Sinatra and JSONQuery Web Service
Sinatra and JSONQuery Web ServiceSinatra and JSONQuery Web Service
Sinatra and JSONQuery Web Service
 
Node.js
Node.jsNode.js
Node.js
 
CoffeeScript-Ruby-Tuesday
CoffeeScript-Ruby-TuesdayCoffeeScript-Ruby-Tuesday
CoffeeScript-Ruby-Tuesday
 

Recently uploaded

"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor TurskyiFwdays
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...UiPathCommunity
 
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCustom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCzechDreamin
 
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlPeter Udo Diehl
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Product School
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxDavid Michel
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesThousandEyes
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3DianaGray10
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoTAnalytics
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...Product School
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Tobias Schneck
 
UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1DianaGray10
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Product School
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaRTTS
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonDianaGray10
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualityInflectra
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Product School
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Thierry Lestable
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesBhaskar Mitra
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...Product School
 

Recently uploaded (20)

"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCustom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
 
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 

CoffeeScript Design Patterns

  • 1. CoffeeScript Design Patterns Presented by Trevor Burnham at Øredev 2011
  • 3. 1995 to 2003: Ancient JavaScript
  • 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)
  • 9. The New First Language?
  • 12. Everyone Who Knows JavaScript Feels Like Superman!
  • 13.
  • 17. 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
  • 18. Brendan Eich (!) CoffeeScript user
  • 19. Eich + Ashkenas at JsConf 2011
  • 21. Things CoffeeScript Isn’t: Ruby/Python jQuery GWT Dart alert  'Hello  World!'    #  1  line!!!
  • 22. “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!
  • 23. More Syntactic Sugar f()  if  z    #  if  (z)  {  f();  } f?()            #  if  (...)  {  f();  } obj?            #  obj  !=  null; key:  val    #  {key:  val}; Plus, significant whitespace...
  • 24. The Beauty of Indentation source: https://github.com/TrevorBurnham/connect-assets for  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)
  • 25. The Curly-Braced Equivalent var  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)  {} }
  • 26.
  • 28. The Wrapper CoffeeScript in: console.log  i  for  i  in  arr JavaScript out: (function()  {    var  i,  _i,  _len;    for  (_i  =  0,  _len  =  arr.length;  _i  <  _len;  _i++)  {        i  =  arr[_i];        console.log(i);    } }).call(this);
  • 29. Why Use The Wrapper? source: http://stackoverflow.com/questions/5211638/
  • 30.
  • 31. Things That Don’t Create Scope in JavaScript Conditionals Parentheses Objects Loops Files (!)
  • 32.
  • 33. Don’t Let This Happen to You! http://blog.meloncard.com/post/12175941935
  • 34. 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);
  • 35. JS Best Practices, CoffeeScript Defaults! Parappa the Wrapper Proper Indentation Avoiding == Packaging extensible objects as “classes”
  • 36. Plain, Ordinary JavaScript Objects lifeEtAl = answer: 42 showAnswer: -> console.log @answer #  @  ==  this lifeEtAl.showAnswer() setTimeout  lifeEtAl.showAnswer,  10
  • 37.
  • 38. Classes to the Rescue! class LifeEtAl answer: 42 showAnswer: => # fat -> console.log @answer myLife = new LifeEtAl setTimeout myLife.showAnswer, 10
  • 39. How About a Little Privacy? class LifeEtAl answer = 42 showAnswer: -> console.log answer myLife = new LifeEtAl setTimeout myLife.showAnswer, 10
  • 40. Using a Constructor class Circle twoPi = Math.PI * 2 constructor: (@radius) -> @radiusSqr = Math.pow @radius, 2 diameter: => twoPi * @radius area: => Math.PI * @radiusSqr c = new Circle(5) console.log c.diameter() # 31.4159 console.log c.area() # 78.5398
  • 41. Let’s Try a Little Inheritance class  Document  extends  Backbone.Model    defaults:        title:  'Untitled'
  • 42. Doing Inheritance via a JavaScript Library var  Document  =  Backbone.Model.extend({    defaults:  {        title:  'Untitled'    } });
  • 43.
  • 44. I. The Prototype Chain class  Document  extends  Backbone.Model    defaults:        title:  'Untitled' doc  =  new  Document Document::  is  Document.prototype doc.defaults  is  Document::defaults doc.validate  is  Backbone.Model::validate doc.hasOwnProperty  is  Object::hasOwnProperty
  • 45. II. Superclass Methods Can Be Invoked With super class  AppleDevice    constructor:  (cost)  -­‐>        bankAccount.deduct  cost        bankAccount.deduct  cost  /  4  #  AppleCare class  iPhone  extends  AppleDevice    constructor:  (cost)  -­‐>        super    #  equivalent  to  super(cost)        setInterval  (-­‐>            bankAccount.deduct  cost  /  4        ),  ONE_MONTH
  • 46. III. Superclass Properties are Copied class  Primate    @thumbs  =  'opposable' class  Human  extends  Primate Human.thumbs  is  Primate.thumbs  is  'opposable'
  • 47.
  • 48. MVC
  • 50. Compiling Rails 3.1 / other web frameworks Middleman / other static web frameworks LiveReload / CodeKit (Mac) coffee -w Write a Cakefile
  • 51. 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 0 task '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']
  • 52. Another Piece of Cake source: https://github.com/TrevorBurnham/connect-assets task '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())
  • 53.
  • 57. A New Area of Confusion... http://stackoverflow.com/questions/7996883/
  • 58. Where is Your Code? http://stackoverflow.com/questions/7996883/
  • 59. Breaking the Client-Server Boundaries Stitch (37signals) browserify jsdom
  • 60.
  • 61.
  • 62. “This book helps readers become better JavaScripters in the process of learning CoffeeScript. What’s more, this book is a blast to read.” —Brendan Eich http://pragprog.com/book/tbcoffee/coffeescript
  • 63. Search KickStarter for “Rethink”
  • 64. Thanks! Questions? Follow me @trevorburnham and @coffeescript