Seattle.rb 6.4

Post on 15-Jan-2015

305 views 0 download

Tags:

description

 

Transcript of Seattle.rb 6.4

5 things I learned about coffeescript

(in my year with it)

Wednesday, June 5, 13

Dean Hudson, @deaneroSenior Engineer, Super Secret Music Start Up

(and hiring!)

Who Am I?

Wednesday, June 5, 13

1. coffee -cp

Wednesday, June 5, 13

dean@hdh:~/Devel/coffee$ coffee --help

Usage: coffee [options] path/to/script.coffee -- [args]

[...] -c, --compile compile to JavaScript and save as .js files -p, --print print out the compiled JavaScript [...]

Wednesday, June 5, 13

to see that this...

Wednesday, June 5, 13

qsort = (ar) -> return ar unless ar.length > 1 pivot = ar.pop() less = [] more = [] for val in ar if val < pivot less.push(val) else more.push(val) qsort(less).concat([pivot], qsort(more))

module.exports = qsort

Wednesday, June 5, 13

...compiles to this:

Wednesday, June 5, 13

dean@hdh:~/Devel/coffee$ coffee -cp qsort.coffee // Generated by CoffeeScript 1.4.0(function() { var qsort;

qsort = function(ar) { var less, more, pivot, val, _i, _len; if (!(ar.length > 1)) { return ar; } pivot = ar.pop(); less = []; more = []; for (_i = 0, _len = ar.length; _i < _len; _i++) { val = ar[_i]; if (val < pivot) { less.push(val); } else { more.push(val); } } return qsort(less).concat([pivot], qsort(more)); };

module.exports = qsort;

}).call(this);dean@hdh:~/Devel/coffee$

Wednesday, June 5, 13

2. Program with class

Wednesday, June 5, 13

Wednesday, June 5, 13

(me, 16 months ago)

Wednesday, June 5, 13

There’s only one way to do it.

It reduces mental overhead for devs.

It just works.

Because! With class...

Wednesday, June 5, 13

__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;};

Wednesday, June 5, 13

__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;};

Tricksy! And...

Wednesday, June 5, 13

// Generated by CoffeeScript 1.4.0(function() { var Greet, Hello, __hasProp = {}.hasOwnProperty;

Greet = (function() {

function Greet() {}

Greet.prototype.greet = function() { return 'hi'; };

return Greet;

})();

Hello = (function(_super) {

__extends(Hello, _super);

function Hello() { return Hello.__super__.constructor.apply(this, arguments); }

Hello.prototype.hello = function() { return 'hello'; };

return Hello;

})(Greet);

}).call(this);

Wednesday, June 5, 13

// Generated by CoffeeScript 1.4.0(function() { var Greet, Hello, __hasProp = {}.hasOwnProperty;

Greet = (function() {

function Greet() {}

Greet.prototype.greet = function() { return 'hi'; };

return Greet;

})();

Hello = (function(_super) {

__extends(Hello, _super);

function Hello() { return Hello.__super__.constructor.apply(this, arguments); }

Hello.prototype.hello = function() { return 'hello'; };

return Hello;

})(Greet);

}).call(this); ...verbose

Wednesday, June 5, 13

vs.

Wednesday, June 5, 13

class Greet greet: -> 'hi'

class Hello extends Greet hello: -> 'hello'

Wednesday, June 5, 13

3. Use comprehension

idioms!!!!!

Wednesday, June 5, 13

# what's wrong with this code?_ = require 'underscore'

ar = [1,2,3,4,5,6,7,8,9]

doubled = _.map(ar, (x) -> x * 2)

Wednesday, June 5, 13

doubled = i * 2 for i in ar

YOU DON’T NEEDA LIBRARY!!!

Wednesday, June 5, 13

// Generated by CoffeeScript 1.4.0(function() { var ar, i, map, _i, _len;

ar = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

for (_i = 0, _len = ar.length; _i < _len; _i++) { i = ar[_i]; map = i * 2; }

}).call(this);

Wednesday, June 5, 13

// Generated by CoffeeScript 1.4.0(function() { var ar, i, map, _i, _len;

ar = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

for (_i = 0, _len = ar.length; _i < _len; _i++) { i = ar[_i]; map = i * 2; }

}).call(this);

This is also faster.

Wednesday, June 5, 13

ar = [1,2,3,4,5,6,7,8,9,10]

aSelect = i for i in ar when (i % 2) == 0aMap = i * 2 for i in araFind = (i for i in ar when i == 0)[0]

Similarly...

Wednesday, June 5, 13

4. One class per file

Wednesday, June 5, 13

Node.js provides a synchronous require

Stitch and browserify use node semantics

Require.js does AMD

How? A library.

Wednesday, June 5, 13

5. Watch your return values.

Wednesday, June 5, 13

dontRunInATightLoop = (object) -> # I meant to mutate this object and return void... object[k] = "#{v}-derp" for k, v of object

This...

Wednesday, June 5, 13

dontRunInATightLoop = function(object) { var k, v, _results; _results = []; for (k in object) { v = object[k]; _results.push(object[k] = "" + v + "-derp"); } return _results;};

...compiles to this.

Wednesday, June 5, 13

Comprehensions+

Implicit returns

Wednesday, June 5, 13

=many allocations

Wednesday, June 5, 13

okayToRunInATightLoop = (object) -> object[k] = "#{v}-derp" for k, v of object # I need to do it explicitly return

Wednesday, June 5, 13

Questions?

Wednesday, June 5, 13

Thanks!@deanero

http://ranch.ero.com(I’m hiring Rubyists!)

Wednesday, June 5, 13