coffee-script 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'coffee-script'
3
- s.version = '0.1.6' # Keep version in sync with coffee-script.rb
4
- s.date = '2009-12-27'
3
+ s.version = '0.2.0' # Keep version in sync with coffee-script.rb
4
+ s.date = '2010-1-5'
5
5
 
6
6
  s.homepage = "http://jashkenas.github.com/coffee-script/"
7
7
  s.summary = "The CoffeeScript Compiler"
@@ -22,5 +22,5 @@ Gem::Specification.new do |s|
22
22
  s.require_paths = ['lib']
23
23
  s.executables = ['coffee']
24
24
 
25
- s.files = Dir['bin/*', 'examples/*', 'lib/**/*', 'coffee-script.gemspec', 'LICENSE', 'README']
25
+ s.files = Dir['bin/*', 'examples/*', 'lib/**/*', 'coffee-script.gemspec', 'LICENSE', 'README', 'package.json']
26
26
  end
data/examples/code.coffee CHANGED
@@ -1,16 +1,16 @@
1
1
  # Functions:
2
- square: x => x * x.
2
+ square: x => x * x
3
3
 
4
- sum: x, y => x + y.
4
+ sum: x, y => x + y
5
5
 
6
- odd: x => x % 2 is 0.
6
+ odd: x => x % 2 is 0
7
7
 
8
- even: x => x % 2 isnt 0.
8
+ even: x => x % 2 isnt 0
9
9
 
10
10
  run_loop: =>
11
- fire_events( e => e.stopPropagation(). )
11
+ fire_events(e => e.stopPropagation())
12
12
  listen()
13
- wait().
13
+ wait()
14
14
 
15
15
  # Objects:
16
16
  dense_object_literal: {one: 1, two: 2, three: 3}
@@ -22,14 +22,14 @@ spaced_out_multiline_object: {
22
22
  three: new Idea()
23
23
 
24
24
  inner_obj: {
25
- freedom: => _.freedom().
25
+ freedom: => _.freedom()
26
26
  }
27
27
  }
28
28
 
29
29
  # Arrays:
30
- stooges : [{moe: 45}, {curly: 43}, {larry: 46}]
30
+ stooges: [{moe: 45}, {curly: 43}, {larry: 46}]
31
31
 
32
- exponents : [x => x., x => x * x., x => x * x * x.]
32
+ exponents: [(x => x), (x => x * x), (x => x * x * x)]
33
33
 
34
34
  empty: []
35
35
 
@@ -45,9 +45,9 @@ if submarine.shields_up
45
45
  else if submarine.sinking
46
46
  abandon_ship()
47
47
  else
48
- run_away().
48
+ run_away()
49
49
 
50
- eldest: if 25 > 21 then liz else marge.
50
+ eldest: if 25 > 21 then liz else marge
51
51
 
52
52
  decoration: medal_of_honor if war_hero
53
53
 
@@ -58,8 +58,8 @@ race: =>
58
58
  run()
59
59
  walk()
60
60
  crawl()
61
- if tired then return sleep().
62
- race().
61
+ if tired then return sleep()
62
+ race()
63
63
 
64
64
  # Conditional assignment:
65
65
  good ||= evil
@@ -81,54 +81,54 @@ try
81
81
  dogs_and_cats_living_together()
82
82
  throw "up"
83
83
  catch error
84
- print( error )
84
+ print(error)
85
85
  finally
86
- clean_up().
86
+ clean_up()
87
87
 
88
- try all_hell_breaks_loose() catch error print(error) finally clean_up().
88
+ try all_hell_breaks_loose() catch error then print(error) finally clean_up()
89
89
 
90
90
  # While loops, break and continue.
91
91
  while demand > supply
92
92
  sell()
93
- restock().
93
+ restock()
94
94
 
95
- while supply > demand then buy().
95
+ while supply > demand then buy()
96
96
 
97
97
  while true
98
98
  break if broken
99
- continue if continuing.
99
+ continue if continuing
100
100
 
101
101
  # Unary operators.
102
102
  !!true
103
103
 
104
104
  # Lexical scoping.
105
- a: 5
105
+ v_1: 5
106
106
  change_a_and_set_b: =>
107
- a: 10
108
- b: 15.
109
- b: 20
107
+ v_1: 10
108
+ v_2: 15
109
+ v_2: 20
110
110
 
111
111
  # Array comprehensions.
112
- supper: food.capitalize() for food in ['toast', 'cheese', 'wine'].
112
+ supper: food.capitalize() for food in ['toast', 'cheese', 'wine']
113
113
 
114
- drink(bottle) for bottle, i in ['soda', 'wine', 'lemonade'] if even(i).
114
+ drink(bottle) for bottle, i in ['soda', 'wine', 'lemonade'] when even(i)
115
115
 
116
116
  # Switch statements ("else" serves as a default).
117
117
  activity: switch day
118
- when "Tuesday" then eat_breakfast()
119
- when "Sunday" then go_to_church()
120
- when "Saturday" then go_to_the_park()
121
- when "Wednesday"
122
- if day is bingo_day
123
- go_to_bingo()
124
- else
125
- eat_breakfast()
126
- go_to_work()
127
- eat_dinner().
128
- else go_to_work().
118
+ when "Tuesday" then eat_breakfast()
119
+ when "Sunday" then go_to_church()
120
+ when "Saturday" then go_to_the_park()
121
+ when "Wednesday"
122
+ if day is bingo_day
123
+ go_to_bingo()
124
+ else
125
+ eat_breakfast()
126
+ go_to_work()
127
+ eat_dinner()
128
+ else go_to_work()
129
129
 
130
130
  # Semicolons can optionally be used instead of newlines.
131
- wednesday: => eat_breakfast(); go_to_work(); eat_dinner(); .
131
+ wednesday: => eat_breakfast(); go_to_work(); eat_dinner()
132
132
 
133
133
  # Array slice literals.
134
134
  zero_to_nine: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
@@ -140,21 +140,21 @@ sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna
140
140
  aliquam erat volutpat. Ut wisi enim ad."
141
141
 
142
142
  # Inheritance and calling super.
143
- Animal: => .
143
+ Animal: =>
144
144
  Animal.prototype.move: meters =>
145
- alert(this.name + " moved " + meters + "m.").
145
+ alert(this.name + " moved " + meters + "m.")
146
146
 
147
- Snake: name => this.name: name.
147
+ Snake: name => this.name: name
148
148
  Snake extends Animal
149
149
  Snake.prototype.move: =>
150
150
  alert('Slithering...')
151
- super(5).
151
+ super(5)
152
152
 
153
- Horse: name => this.name: name.
153
+ Horse: name => this.name: name
154
154
  Horse extends Animal
155
155
  Horse.prototype.move: =>
156
156
  alert('Galloping...')
157
- super(45).
157
+ super(45)
158
158
 
159
159
  sam: new Snake("Sammy the Snake")
160
160
  tom: new Horse("Tommy the Horse")
@@ -1,7 +1,7 @@
1
1
  # Document Model
2
2
  dc.model.Document: dc.Model.extend({
3
3
 
4
- constructor: attributes => this.base(attributes).
4
+ constructor: attributes => this.base(attributes)
5
5
 
6
6
  # For display, show either the highlighted search results, or the summary,
7
7
  # if no highlights are available.
@@ -9,22 +9,22 @@ dc.model.Document: dc.Model.extend({
9
9
  # version of the summary has all runs of whitespace squeezed out.
10
10
  displaySummary: =>
11
11
  text: this.get('highlight') or this.get('summary') or ''
12
- text and text.replace(/\s+/g, ' ').
12
+ text and text.replace(/\s+/g, ' ')
13
13
 
14
14
  # Return a list of the document's metadata. Think about caching this on the
15
15
  # document by binding to Metadata, instead of on-the-fly.
16
16
  metadata: =>
17
17
  docId: this.id
18
- _.select(Metadata.models()
19
- meta => _.any(meta.get('instances')
20
- instance => instance.document_id is docId.).).
18
+ _.select(Metadata.models(), (meta =>
19
+ _.any(meta.get('instances'), instance =>
20
+ instance.document_id is docId)))
21
21
 
22
22
  bookmark: pageNumber =>
23
23
  bookmark: new dc.model.Bookmark({title: this.get('title'), page_number: pageNumber, document_id: this.id})
24
- Bookmarks.create(bookmark).
24
+ Bookmarks.create(bookmark)
25
25
 
26
26
  # Inspect.
27
- toString: => 'Document ' + this.id + ' "' + this.get('title') + '"'.
27
+ toString: => 'Document ' + this.id + ' "' + this.get('title') + '"'
28
28
 
29
29
  })
30
30
 
@@ -37,31 +37,31 @@ dc.model.DocumentSet: dc.model.RESTfulSet.extend({
37
37
 
38
38
  constructor: options =>
39
39
  this.base(options)
40
- _.bindAll(this, 'downloadSelectedViewers', 'downloadSelectedPDF', 'downloadSelectedFullText').
40
+ _.bindAll(this, 'downloadSelectedViewers', 'downloadSelectedPDF', 'downloadSelectedFullText')
41
41
 
42
- selected: => _.select(this.models(), m => m.get('selected').).
42
+ selected: => _.select(this.models(), m => m.get('selected'))
43
43
 
44
- selectedIds: => _.pluck(this.selected(), 'id').
44
+ selectedIds: => _.pluck(this.selected(), 'id')
45
45
 
46
- countSelected: => this.selected().length.
46
+ countSelected: => this.selected().length
47
47
 
48
48
  downloadSelectedViewers: =>
49
- dc.app.download('/download/' + this.selectedIds().join('/') + '/document_viewer.zip').
49
+ dc.app.download('/download/' + this.selectedIds().join('/') + '/document_viewer.zip')
50
50
 
51
51
  downloadSelectedPDF: =>
52
- if this.countSelected() <= 1 then return window.open(this.selected()[0].get('pdf_url')).
53
- dc.app.download('/download/' + this.selectedIds().join('/') + '/document_pdfs.zip').
52
+ if this.countSelected() <= 1 then return window.open(this.selected()[0].get('pdf_url'))
53
+ dc.app.download('/download/' + this.selectedIds().join('/') + '/document_pdfs.zip')
54
54
 
55
55
  downloadSelectedFullText: =>
56
- if this.countSelected() <= 1 then return window.open(this.selected()[0].get('full_text_url')).
57
- dc.app.download('/download/' + this.selectedIds().join('/') + '/document_text.zip').
56
+ if this.countSelected() <= 1 then return window.open(this.selected()[0].get('full_text_url'))
57
+ dc.app.download('/download/' + this.selectedIds().join('/') + '/document_text.zip')
58
58
 
59
59
  # We override "_onModelEvent" to fire selection changed events when documents
60
60
  # change their selected state.
61
61
  _onModelEvent: e, model =>
62
62
  this.base(e, model)
63
63
  fire: e == dc.Model.CHANGED and model.hasChanged('selected')
64
- if fire then _.defer(_(this.fire).bind(this, this.SELECTION_CHANGED, this))..
64
+ if fire then _.defer(_(this.fire).bind(this, this.SELECTION_CHANGED, this))
65
65
 
66
66
  })
67
67
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # ['toast', 'cheese', 'wine'].each { |food| print food.capitalize }
4
4
 
5
- ['toast', 'wine', 'cheese'].each( food => print(food.capitalize()). )
5
+ ['toast', 'wine', 'cheese'].each(food => print(food.capitalize()))
6
6
 
7
7
 
8
8
 
@@ -14,10 +14,10 @@
14
14
  # end
15
15
 
16
16
  LotteryTicket: {
17
- get_picks: => this.picks.
18
- set_picks: nums => this.picks: nums.
19
- get_purchase: => this.purchase.
20
- set_purchase: amount => this.purchase: amount.
17
+ get_picks: => this.picks
18
+ set_picks: nums => this.picks: nums
19
+ get_purchase: => this.purchase
20
+ set_purchase: amount => this.purchase: amount
21
21
  }
22
22
 
23
23
 
@@ -33,8 +33,8 @@ LotteryTicket: {
33
33
 
34
34
  WishScanner: {
35
35
  scan_for_a_wish: =>
36
- wish: this.read().detect( thought => thought.index('wish: ') is 0. )
37
- wish.replace('wish: ', '').
36
+ wish: this.read().detect(thought => thought.index('wish: ') is 0)
37
+ wish.replace('wish: ', '')
38
38
  }
39
39
 
40
40
 
@@ -79,28 +79,28 @@ Creature : {
79
79
 
80
80
  # This method applies a hit taken during a fight.
81
81
  hit: damage =>
82
- p_up: Math.rand( this.charisma )
82
+ p_up: Math.rand(this.charisma)
83
83
  if p_up % 9 is 7
84
84
  this.life += p_up / 4
85
- puts( "[" + this.name + " magick powers up " + p_up + "!]" ).
85
+ puts("[" + this.name + " magick powers up " + p_up + "!]")
86
86
  this.life -= damage
87
- if this.life <= 0 then puts( "[" + this.name + " has died.]" )..
87
+ if this.life <= 0 then puts("[" + this.name + " has died.]")
88
88
 
89
89
  # This method takes one turn in a fight.
90
90
  fight: enemy, weapon =>
91
- if this.life <= 0 then return puts( "[" + this.name + "is too dead to fight!]" ).
91
+ if this.life <= 0 then return puts("[" + this.name + "is too dead to fight!]")
92
92
 
93
93
  # Attack the opponent.
94
- your_hit: Math.rand( this.strength + weapon )
95
- puts( "[You hit with " + your_hit + "points of damage!]" )
96
- enemy.hit( your_hit )
94
+ your_hit: Math.rand(this.strength + weapon)
95
+ puts("[You hit with " + your_hit + "points of damage!]")
96
+ enemy.hit(your_hit)
97
97
 
98
98
  # Retaliation.
99
- puts( enemy )
99
+ puts(enemy)
100
100
  if enemy.life > 0
101
- enemy_hit: Math.rand( enemy.strength + enemy.weapon )
102
- puts( "[Your enemy hit with " + enemy_hit + "points of damage!]" )
103
- this.hit( enemy_hit )..
101
+ enemy_hit: Math.rand(enemy.strength + enemy.weapon)
102
+ puts("[Your enemy hit with " + enemy_hit + "points of damage!]")
103
+ this.hit(enemy_hit)
104
104
 
105
105
  }
106
106
 
@@ -123,12 +123,12 @@ Creature : {
123
123
  # Get evil idea and swap in code words
124
124
  print("Enter your new idea: ")
125
125
  idea: gets()
126
- code_words.each( real, code => idea.replace(real, code). )
126
+ code_words.each(real, code => idea.replace(real, code))
127
127
 
128
128
  # Save the jibberish to a new file
129
129
  print("File encoded. Please enter a name for this idea: ")
130
130
  idea_name: gets().strip()
131
- File.open("idea-" + idea_name + '.txt', 'w', file => file.write(idea). )
131
+ File.open("idea-" + idea_name + '.txt', 'w', file => file.write(idea))
132
132
 
133
133
 
134
134
 
@@ -149,5 +149,5 @@ wipe_mutterings_from: sentence =>
149
149
  while sentence.indexOf('(') >= 0
150
150
  open: sentence.indexOf('(') - 1
151
151
  close: sentence.indexOf(')') + 1
152
- sentence: sentence[0..open] + sentence[close..sentence.length].
153
- sentence.
152
+ sentence: sentence[0..open] + sentence[close..sentence.length]
153
+ sentence
@@ -1,107 +1,126 @@
1
- # Underscore.js
2
- # (c) 2009 Jeremy Ashkenas, DocumentCloud Inc.
3
- # Underscore is freely distributable under the terms of the MIT license.
4
- # Portions of Underscore are inspired by or borrowed from Prototype.js,
5
- # Oliver Steele's Functional, and John Resig's Micro-Templating.
6
- # For all details and documentation:
7
- # http://documentcloud.github.com/underscore/
8
-
9
- # ------------------------- Baseline setup ---------------------------------
10
-
11
- # Establish the root object, "window" in the browser, or "global" on the server.
12
- root: this
13
-
14
- # Save the previous value of the "_" variable.
15
- previousUnderscore: root._
16
-
17
- # If Underscore is called as a function, it returns a wrapped object that
18
- # can be used OO-style. This wrapper holds altered versions of all the
19
- # underscore functions. Wrapped objects may be chained.
20
- wrapper: obj => this._wrapped: obj.
21
-
22
- # Establish the object that gets thrown to break out of a loop iteration.
23
- breaker: if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration.
24
-
25
- # Create a safe reference to the Underscore object for reference below.
26
- _: root._: obj => new wrapper(obj).
27
-
28
- # Export the Underscore object for CommonJS.
29
- if typeof(exports) != 'undefined' then exports._: _.
30
-
31
- # Create quick reference variables for speed access to core prototypes.
32
- slice: Array.prototype.slice
33
- unshift: Array.prototype.unshift
34
- toString: Object.prototype.toString
35
- hasOwnProperty: Object.prototype.hasOwnProperty
36
- propertyIsEnumerable: Object.prototype.propertyIsEnumerable
37
-
38
- # Current version.
39
- _.VERSION: '0.5.1'
40
-
41
- # ------------------------ Collection Functions: ---------------------------
42
-
43
- # The cornerstone, an each implementation.
44
- # Handles objects implementing forEach, arrays, and raw objects.
45
- _.each: obj, iterator, context =>
46
- index: 0
47
- try
48
- return obj.forEach(iterator, context) if obj.forEach
49
- return iterator.call(context, item, i, obj) for item, i in obj. if _.isArray(obj) or _.isArguments(obj)
50
- iterator.call(context, obj[key], key, obj) for key in _.keys(obj).
51
- catch e
52
- throw e if e isnt breaker.
53
- obj.
54
-
55
- # Return the results of applying the iterator to each element. Use JavaScript
56
- # 1.6's version of map, if possible.
57
- _.map: obj, iterator, context =>
58
- return obj.map(iterator, context) if (obj and _.isFunction(obj.map))
59
- results: []
60
- mapper: value, index, list => results.push(iterator.call(context, value, index, list)).
61
- _.each(obj, mapper)
62
- results.
63
-
64
- # Reduce builds up a single result from a list of values. Also known as
65
- # inject, or foldl. Uses JavaScript 1.8's version of reduce, if possible.
66
- _.reduce: obj, memo, iterator, context =>
67
- return obj.reduce(_.bind(iterator, context), memo) if (obj and _.isFunction(obj.reduce))
68
- reducer: value, index, list => memo: iterator.call(context, memo, value, index, list).
69
- _.each(obj, reducer)
70
- memo.
71
-
72
- # The right-associative version of reduce, also known as foldr. Uses
73
- # JavaScript 1.8's version of reduceRight, if available.
74
- _.reduceRight: obj, memo, iterator, context =>
75
- return obj.reduceRight(_.bind(iterator, context), memo) if (obj and _.isFunction(obj.reduceRight))
76
- reversed: _.clone(_.toArray(obj)).reverse()
77
- reverser: value, index => memo: iterator.call(context, memo, value, index, obj).
78
- _.each(reversed, reverser)
79
- memo.
1
+
2
+ # Underscore.coffee
3
+ # (c) 2009 Jeremy Ashkenas, DocumentCloud Inc.
4
+ # Underscore is freely distributable under the terms of the MIT license.
5
+ # Portions of Underscore are inspired by or borrowed from Prototype.js,
6
+ # Oliver Steele's Functional, and John Resig's Micro-Templating.
7
+ # For all details and documentation:
8
+ # http://documentcloud.github.com/underscore/
9
+
10
+
11
+ # ------------------------- Baseline setup ---------------------------------
12
+
13
+ # Establish the root object, "window" in the browser, or "global" on the server.
14
+ root: this
15
+
16
+
17
+ # Save the previous value of the "_" variable.
18
+ previousUnderscore: root._
19
+
20
+
21
+ # If Underscore is called as a function, it returns a wrapped object that
22
+ # can be used OO-style. This wrapper holds altered versions of all the
23
+ # underscore functions. Wrapped objects may be chained.
24
+ wrapper: obj =>
25
+ this._wrapped: obj
26
+ this
27
+
28
+
29
+ # Establish the object that gets thrown to break out of a loop iteration.
30
+ breaker: if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration
31
+
32
+
33
+ # Create a safe reference to the Underscore object for reference below.
34
+ _: root._: obj => new wrapper(obj)
35
+
36
+
37
+ # Export the Underscore object for CommonJS.
38
+ if typeof(exports) != 'undefined' then exports._: _
39
+
40
+
41
+ # Create quick reference variables for speed access to core prototypes.
42
+ slice: Array.prototype.slice
43
+ unshift: Array.prototype.unshift
44
+ toString: Object.prototype.toString
45
+ hasOwnProperty: Object.prototype.hasOwnProperty
46
+ propertyIsEnumerable: Object.prototype.propertyIsEnumerable
47
+
48
+
49
+ # Current version.
50
+ _.VERSION: '0.5.3'
51
+
52
+
53
+ # ------------------------ Collection Functions: ---------------------------
54
+
55
+ # The cornerstone, an each implementation.
56
+ # Handles objects implementing forEach, arrays, and raw objects.
57
+ _.each: obj, iterator, context =>
58
+ index: 0
59
+ try
60
+ return obj.forEach(iterator, context) if obj.forEach
61
+ if _.isArray(obj) or _.isArguments(obj)
62
+ return iterator.call(context, obj[i], i, obj) for i in [0...obj.length]
63
+ iterator.call(context, val, key, obj) for val, key in obj
64
+ catch e
65
+ throw e if e isnt breaker
66
+ obj
67
+
68
+
69
+ # Return the results of applying the iterator to each element. Use JavaScript
70
+ # 1.6's version of map, if possible.
71
+ _.map: obj, iterator, context =>
72
+ return obj.map(iterator, context) if (obj and _.isFunction(obj.map))
73
+ results: []
74
+ _.each(obj) value, index, list =>
75
+ results.push(iterator.call(context, value, index, list))
76
+ results
77
+
78
+
79
+ # Reduce builds up a single result from a list of values. Also known as
80
+ # inject, or foldl. Uses JavaScript 1.8's version of reduce, if possible.
81
+ _.reduce: obj, memo, iterator, context =>
82
+ return obj.reduce(_.bind(iterator, context), memo) if (obj and _.isFunction(obj.reduce))
83
+ _.each(obj) value, index, list =>
84
+ memo: iterator.call(context, memo, value, index, list)
85
+ memo
86
+
87
+
88
+ # The right-associative version of reduce, also known as foldr. Uses
89
+ # JavaScript 1.8's version of reduceRight, if available.
90
+ _.reduceRight: obj, memo, iterator, context =>
91
+ return obj.reduceRight(_.bind(iterator, context), memo) if (obj and _.isFunction(obj.reduceRight))
92
+ _.each(_.clone(_.toArray(obj)).reverse()) value, index =>
93
+ memo: iterator.call(context, memo, value, index, obj)
94
+ memo
95
+
80
96
 
81
97
  # Return the first value which passes a truth test.
82
98
  _.detect: obj, iterator, context =>
83
99
  result: null
84
- _.each(obj, (value, index, list =>
100
+ _.each(obj) value, index, list =>
85
101
  if iterator.call(context, value, index, list)
86
102
  result: value
87
- _.breakLoop()..))
88
- result.
103
+ _.breakLoop()
104
+ result
105
+
89
106
 
90
107
  # Return all the elements that pass a truth test. Use JavaScript 1.6's
91
108
  # filter(), if it exists.
92
109
  _.select: obj, iterator, context =>
93
- if obj and _.isFunction(obj.filter) then return obj.filter(iterator, context).
110
+ if obj and _.isFunction(obj.filter) then return obj.filter(iterator, context)
94
111
  results: []
95
- _.each(obj, (value, index, list =>
96
- results.push(value) if iterator.call(context, value, index, list).))
97
- results.
112
+ _.each(obj) value, index, list =>
113
+ results.push(value) if iterator.call(context, value, index, list)
114
+ results
115
+
98
116
 
99
117
  # Return all the elements for which a truth test fails.
100
118
  _.reject: obj, iterator, context =>
101
119
  results: []
102
- _.each(obj, (value, index, list =>
103
- results.push(value) if not iterator.call(context, value, index, list).))
104
- results.
120
+ _.each(obj) value, index, list =>
121
+ results.push(value) if not iterator.call(context, value, index, list)
122
+ results
123
+
105
124
 
106
125
  # Determine whether all of the elements match a truth test. Delegate to
107
126
  # JavaScript 1.6's every(), if it is present.
@@ -109,9 +128,10 @@ _.reduceRight: obj, memo, iterator, context =>
109
128
  iterator ||= _.identity
110
129
  return obj.every(iterator, context) if obj and _.isFunction(obj.every)
111
130
  result: true
112
- _.each(obj, (value, index, list =>
113
- _.breakLoop() unless result: result and iterator.call(context, value, index, list).))
114
- result.
131
+ _.each(obj) value, index, list =>
132
+ _.breakLoop() unless (result: result and iterator.call(context, value, index, list))
133
+ result
134
+
115
135
 
116
136
  # Determine if at least one element in the object matches a truth test. Use
117
137
  # JavaScript 1.6's some(), if it exists.
@@ -119,193 +139,193 @@ _.reduceRight: obj, memo, iterator, context =>
119
139
  iterator ||= _.identity
120
140
  return obj.some(iterator, context) if obj and _.isFunction(obj.some)
121
141
  result: false
122
- _.each(obj, (value, index, list =>
123
- _.breakLoop() if (result: iterator.call(context, value, index, list)).))
124
- result.
142
+ _.each(obj) value, index, list =>
143
+ _.breakLoop() if (result: iterator.call(context, value, index, list))
144
+ result
145
+
125
146
 
126
147
  # Determine if a given value is included in the array or object,
127
148
  # based on '==='.
128
149
  _.include: obj, target =>
129
150
  return _.indexOf(obj, target) isnt -1 if _.isArray(obj)
130
- found: false
131
- _.each(obj, (value =>
132
- _.breakLoop() if (found: value is target).))
133
- found.
151
+ for val in obj
152
+ return true if val is target
153
+ false
154
+
134
155
 
135
156
  # Invoke a method with arguments on every item in a collection.
136
157
  _.invoke: obj, method =>
137
158
  args: _.rest(arguments, 2)
138
- _.map(obj, (value =>
139
- (if method then value[method] else value.).apply(value, args).)).
159
+ (if method then val[method] else val).apply(val, args) for val in obj
160
+
140
161
 
141
162
  # Convenience version of a common use case of map: fetching a property.
142
163
  _.pluck: obj, key =>
143
- _.map(obj, (value => value[key].)).
164
+ _.map(obj, (val => val[key]))
165
+
144
166
 
145
167
  # Return the maximum item or (item-based computation).
146
168
  _.max: obj, iterator, context =>
147
- return Math.max.apply(Math, obj) if !iterator and _.isArray(obj)
169
+ return Math.max.apply(Math, obj) if not iterator and _.isArray(obj)
148
170
  result: {computed: -Infinity}
149
- _.each(obj, (value, index, list =>
150
- computed: if iterator then iterator.call(context, value, index, list) else value.
151
- computed >= result.computed and (result: {value: value, computed: computed}).))
152
- result.value.
153
- #
154
- # # Return the minimum element (or element-based computation).
155
- # _.min = function(obj, iterator, context) {
156
- # if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
157
- # var result = {computed : Infinity};
158
- # _.each(obj, function(value, index, list) {
159
- # var computed = iterator ? iterator.call(context, value, index, list) : value;
160
- # computed < result.computed && (result = {value : value, computed : computed});
161
- # });
162
- # return result.value;
163
- # };
164
- #
165
- # # Sort the object's values by a criteria produced by an iterator.
166
- # _.sortBy = function(obj, iterator, context) {
167
- # return _.pluck(_.map(obj, function(value, index, list) {
168
- # return {
169
- # value : value,
170
- # criteria : iterator.call(context, value, index, list)
171
- # };
172
- # }).sort(function(left, right) {
173
- # var a = left.criteria, b = right.criteria;
174
- # return a < b ? -1 : a > b ? 1 : 0;
175
- # }), 'value');
176
- # };
177
- #
178
- # # Use a comparator function to figure out at what index an object should
179
- # # be inserted so as to maintain order. Uses binary search.
180
- # _.sortedIndex = function(array, obj, iterator) {
181
- # iterator = iterator || _.identity;
182
- # var low = 0, high = array.length;
183
- # while (low < high) {
184
- # var mid = (low + high) >> 1;
185
- # iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
186
- # }
187
- # return low;
188
- # };
189
- #
190
- # # Convert anything iterable into a real, live array.
191
- # _.toArray = function(iterable) {
192
- # if (!iterable) return [];
193
- # if (iterable.toArray) return iterable.toArray();
194
- # if (_.isArray(iterable)) return iterable;
195
- # if (_.isArguments(iterable)) return slice.call(iterable);
196
- # return _.map(iterable, function(val){ return val; });
197
- # };
198
- #
199
- # # Return the number of elements in an object.
200
- # _.size = function(obj) {
201
- # return _.toArray(obj).length;
202
- # };
203
- #
204
- # /*-------------------------- Array Functions: ------------------------------*/
205
- #
206
- # # Get the first element of an array. Passing "n" will return the first N
207
- # # values in the array. Aliased as "head". The "guard" check allows it to work
208
- # # with _.map.
209
- # _.first = function(array, n, guard) {
210
- # return n && !guard ? slice.call(array, 0, n) : array[0];
211
- # };
212
- #
213
- # # Returns everything but the first entry of the array. Aliased as "tail".
214
- # # Especially useful on the arguments object. Passing an "index" will return
215
- # # the rest of the values in the array from that index onward. The "guard"
216
- # //check allows it to work with _.map.
217
- # _.rest = function(array, index, guard) {
218
- # return slice.call(array, _.isUndefined(index) || guard ? 1 : index);
219
- # };
220
- #
221
- # # Get the last element of an array.
222
- # _.last = function(array) {
223
- # return array[array.length - 1];
224
- # };
225
- #
226
- # # Trim out all falsy values from an array.
227
- # _.compact = function(array) {
228
- # return _.select(array, function(value){ return !!value; });
229
- # };
230
- #
231
- # # Return a completely flattened version of an array.
232
- # _.flatten = function(array) {
233
- # return _.reduce(array, [], function(memo, value) {
234
- # if (_.isArray(value)) return memo.concat(_.flatten(value));
235
- # memo.push(value);
236
- # return memo;
237
- # });
238
- # };
239
- #
240
- # # Return a version of the array that does not contain the specified value(s).
241
- # _.without = function(array) {
242
- # var values = _.rest(arguments);
243
- # return _.select(array, function(value){ return !_.include(values, value); });
244
- # };
245
- #
246
- # # Produce a duplicate-free version of the array. If the array has already
247
- # # been sorted, you have the option of using a faster algorithm.
248
- # _.uniq = function(array, isSorted) {
249
- # return _.reduce(array, [], function(memo, el, i) {
250
- # if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo.push(el);
251
- # return memo;
252
- # });
253
- # };
254
- #
255
- # # Produce an array that contains every item shared between all the
256
- # # passed-in arrays.
257
- # _.intersect = function(array) {
258
- # var rest = _.rest(arguments);
259
- # return _.select(_.uniq(array), function(item) {
260
- # return _.all(rest, function(other) {
261
- # return _.indexOf(other, item) >= 0;
262
- # });
263
- # });
264
- # };
265
- #
266
- # # Zip together multiple lists into a single array -- elements that share
267
- # # an index go together.
268
- # _.zip = function() {
269
- # var args = _.toArray(arguments);
270
- # var length = _.max(_.pluck(args, 'length'));
271
- # var results = new Array(length);
272
- # for (var i=0; i<length; i++) results[i] = _.pluck(args, String(i));
273
- # return results;
274
- # };
275
- #
276
- # # If the browser doesn't supply us with indexOf (I'm looking at you, MSIE),
277
- # # we need this function. Return the position of the first occurence of an
278
- # # item in an array, or -1 if the item is not included in the array.
279
- # _.indexOf = function(array, item) {
280
- # if (array.indexOf) return array.indexOf(item);
281
- # for (var i=0, l=array.length; i<l; i++) if (array[i] === item) return i;
282
- # return -1;
283
- # };
284
- #
285
- # # Provide JavaScript 1.6's lastIndexOf, delegating to the native function,
286
- # # if possible.
287
- # _.lastIndexOf = function(array, item) {
288
- # if (array.lastIndexOf) return array.lastIndexOf(item);
289
- # var i = array.length;
290
- # while (i--) if (array[i] === item) return i;
291
- # return -1;
292
- # };
293
- #
294
- # # Generate an integer Array containing an arithmetic progression. A port of
295
- # # the native Python range() function. See:
296
- # # http://docs.python.org/library/functions.html#range
297
- # _.range = function(start, stop, step) {
298
- # var a = _.toArray(arguments);
299
- # var solo = a.length <= 1;
300
- # var start = solo ? 0 : a[0], stop = solo ? a[0] : a[1], step = a[2] || 1;
301
- # var len = Math.ceil((stop - start) / step);
302
- # if (len <= 0) return [];
303
- # var range = new Array(len);
304
- # for (var i = start, idx = 0; true; i += step) {
305
- # if ((step > 0 ? i - stop : stop - i) >= 0) return range;
306
- # range[idx++] = i;
307
- # }
308
- # };
171
+ _.each(obj) value, index, list =>
172
+ computed: if iterator then iterator.call(context, value, index, list) else value
173
+ computed >= result.computed and (result: {value: value, computed: computed})
174
+ result.value
175
+
176
+
177
+ # Return the minimum element (or element-based computation).
178
+ _.min: obj, iterator, context =>
179
+ return Math.min.apply(Math, obj) if not iterator and _.isArray(obj)
180
+ result: {computed: Infinity}
181
+ _.each(obj) value, index, list =>
182
+ computed: if iterator then iterator.call(context, value, index, list) else value
183
+ computed < result.computed and (result: {value: value, computed: computed})
184
+ result.value
185
+
186
+
187
+ # Sort the object's values by a criteria produced by an iterator.
188
+ _.sortBy: obj, iterator, context =>
189
+ _.pluck(((_.map(obj) value, index, list =>
190
+ {value: value, criteria: iterator.call(context, value, index, list)}
191
+ ).sort() left, right =>
192
+ a: left.criteria; b: right.criteria
193
+ if a < b then -1 else if a > b then 1 else 0
194
+ ), 'value')
195
+
196
+
197
+ # Use a comparator function to figure out at what index an object should
198
+ # be inserted so as to maintain order. Uses binary search.
199
+ _.sortedIndex: array, obj, iterator =>
200
+ iterator ||= _.identity
201
+ low: 0; high: array.length
202
+ while low < high
203
+ mid: (low + high) >> 1
204
+ if iterator(array[mid]) < iterator(obj) then low: mid + 1 else high: mid
205
+ low
206
+
207
+
208
+ # Convert anything iterable into a real, live array.
209
+ _.toArray: iterable =>
210
+ return [] if (!iterable)
211
+ return iterable.toArray() if (iterable.toArray)
212
+ return iterable if (_.isArray(iterable))
213
+ return slice.call(iterable) if (_.isArguments(iterable))
214
+ _.values(iterable)
215
+
216
+
217
+ # Return the number of elements in an object.
218
+ _.size: obj => _.toArray(obj).length
219
+
220
+
221
+ # -------------------------- Array Functions: ------------------------------
222
+
223
+ # Get the first element of an array. Passing "n" will return the first N
224
+ # values in the array. Aliased as "head". The "guard" check allows it to work
225
+ # with _.map.
226
+ _.first: array, n, guard =>
227
+ if n and not guard then slice.call(array, 0, n) else array[0]
228
+
229
+
230
+ # Returns everything but the first entry of the array. Aliased as "tail".
231
+ # Especially useful on the arguments object. Passing an "index" will return
232
+ # the rest of the values in the array from that index onward. The "guard"
233
+ # check allows it to work with _.map.
234
+ _.rest: array, index, guard =>
235
+ slice.call(array, if _.isUndefined(index) or guard then 1 else index)
236
+
237
+
238
+ # Get the last element of an array.
239
+ _.last: array => array[array.length - 1]
240
+
241
+
242
+ # Trim out all falsy values from an array.
243
+ _.compact: array => array[i] for i in [0...array.length] when array[i]
244
+
245
+
246
+ # Return a completely flattened version of an array.
247
+ _.flatten: array =>
248
+ _.reduce(array, []) memo, value =>
249
+ return memo.concat(_.flatten(value)) if _.isArray(value)
250
+ memo.push(value)
251
+ memo
252
+
253
+
254
+ # Return a version of the array that does not contain the specified value(s).
255
+ _.without: array =>
256
+ values: _.rest(arguments)
257
+ val for val in _.toArray(array) when not _.include(values, val)
258
+
259
+
260
+ # Produce a duplicate-free version of the array. If the array has already
261
+ # been sorted, you have the option of using a faster algorithm.
262
+ _.uniq: array, isSorted =>
263
+ memo: []
264
+ for el, i in _.toArray(array)
265
+ memo.push(el) if i is 0 || (if isSorted is true then _.last(memo) isnt el else not _.include(memo, el))
266
+ memo
267
+
268
+
269
+ # Produce an array that contains every item shared between all the
270
+ # passed-in arrays.
271
+ _.intersect: array =>
272
+ rest: _.rest(arguments)
273
+ _.select(_.uniq(array)) item =>
274
+ _.all(rest) other =>
275
+ _.indexOf(other, item) >= 0
276
+
277
+
278
+ # Zip together multiple lists into a single array -- elements that share
279
+ # an index go together.
280
+ _.zip: =>
281
+ args: _.toArray(arguments)
282
+ length: _.max(_.pluck(args, 'length'))
283
+ results: new Array(length)
284
+ for i in [0...length]
285
+ results[i]: _.pluck(args, String(i))
286
+ results
287
+
288
+
289
+ # If the browser doesn't supply us with indexOf (I'm looking at you, MSIE),
290
+ # we need this function. Return the position of the first occurence of an
291
+ # item in an array, or -1 if the item is not included in the array.
292
+ _.indexOf: array, item =>
293
+ return array.indexOf(item) if array.indexOf
294
+ i: 0; l: array.length
295
+ while l - i
296
+ if array[i] is item then return i else i++
297
+ -1
298
+
299
+
300
+ # Provide JavaScript 1.6's lastIndexOf, delegating to the native function,
301
+ # if possible.
302
+ _.lastIndexOf: array, item =>
303
+ return array.lastIndexOf(item) if array.lastIndexOf
304
+ i: array.length
305
+ while i
306
+ if array[i] is item then return i else i--
307
+ -1
308
+
309
+
310
+ # Generate an integer Array containing an arithmetic progression. A port of
311
+ # the native Python range() function. See:
312
+ # http://docs.python.org/library/functions.html#range
313
+ _.range: start, stop, step =>
314
+ a: _.toArray(arguments)
315
+ solo: a.length <= 1
316
+ i: start: if solo then 0 else a[0];
317
+ stop: if solo then a[0] else a[1];
318
+ step: a[2] or 1
319
+ len: Math.ceil((stop - start) / step)
320
+ return [] if len <= 0
321
+ range: new Array(len)
322
+ idx: 0
323
+ while true
324
+ return range if (if step > 0 then i - stop else stop - i) >= 0
325
+ range[idx]: i
326
+ idx++
327
+ i+= step
328
+
309
329
 
310
330
  # ----------------------- Function Functions: -----------------------------
311
331
 
@@ -313,34 +333,36 @@ _.reduceRight: obj, memo, iterator, context =>
313
333
  # optionally). Binding with arguments is also known as 'curry'.
314
334
  _.bind: func, obj =>
315
335
  args: _.rest(arguments, 2)
316
- => func.apply(obj or root, args.concat(_.toArray(arguments)))..
317
-
318
- # # Bind all of an object's methods to that object. Useful for ensuring that
319
- # # all callbacks defined on an object belong to it.
320
- # _.bindAll = function(obj) {
321
- # var funcs = _.rest(arguments);
322
- # if (funcs.length == 0) funcs = _.functions(obj);
323
- # _.each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
324
- # return obj;
325
- # };
326
- #
327
- # # Delays a function for the given number of milliseconds, and then calls
328
- # # it with the arguments supplied.
329
- # _.delay = function(func, wait) {
330
- # var args = _.rest(arguments, 2);
331
- # return setTimeout(function(){ return func.apply(func, args); }, wait);
332
- # };
336
+ => func.apply(obj or root, args.concat(_.toArray(arguments)))
337
+
338
+
339
+ # Bind all of an object's methods to that object. Useful for ensuring that
340
+ # all callbacks defined on an object belong to it.
341
+ _.bindAll: obj =>
342
+ funcs: if arguments.length > 1 then _.rest(arguments) else _.functions(obj)
343
+ _.each(funcs, (f => obj[f]: _.bind(obj[f], obj)))
344
+ obj
345
+
346
+
347
+ # Delays a function for the given number of milliseconds, and then calls
348
+ # it with the arguments supplied.
349
+ _.delay: func, wait =>
350
+ args: _.rest(arguments, 2)
351
+ setTimeout((=> func.apply(func, args)), wait)
352
+
333
353
 
334
354
  # Defers a function, scheduling it to run after the current call stack has
335
355
  # cleared.
336
356
  _.defer: func =>
337
- _.delay.apply(_, [func, 1].concat(_.rest(arguments))).
357
+ _.delay.apply(_, [func, 1].concat(_.rest(arguments)))
358
+
338
359
 
339
360
  # Returns the first function passed as an argument to the second,
340
361
  # allowing you to adjust arguments, run code before and after, and
341
362
  # conditionally execute the original function.
342
363
  _.wrap: func, wrapper =>
343
- => wrapper.apply(wrapper, [func].concat(_.toArray(arguments)))..
364
+ => wrapper.apply(wrapper, [func].concat(_.toArray(arguments)))
365
+
344
366
 
345
367
  # Returns a function that is the composition of a list of functions, each
346
368
  # consuming the return value of the function that follows.
@@ -348,40 +370,48 @@ _.reduceRight: obj, memo, iterator, context =>
348
370
  funcs: _.toArray(arguments)
349
371
  =>
350
372
  args: _.toArray(arguments)
351
- args: [funcs[i]].apply(this, args) for i in [(funcs.length - 1)..0].
352
- args[0]..
353
-
354
- # /* ------------------------- Object Functions: ---------------------------- */
355
- #
356
- # # Retrieve the names of an object's properties.
357
- # _.keys = function(obj) {
358
- # if(_.isArray(obj)) return _.range(0, obj.length);
359
- # var keys = [];
360
- # for (var key in obj) if (hasOwnProperty.call(obj, key)) keys.push(key);
361
- # return keys;
362
- # };
363
- #
364
- # # Retrieve the values of an object's properties.
365
- # _.values = function(obj) {
366
- # return _.map(obj, _.identity);
367
- # };
368
- #
369
- # # Return a sorted list of the function names available in Underscore.
370
- # _.functions = function(obj) {
371
- # return _.select(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort();
372
- # };
373
- #
374
- # # Extend a given object with all of the properties in a source object.
375
- # _.extend = function(destination, source) {
376
- # for (var property in source) destination[property] = source[property];
377
- # return destination;
378
- # };
379
- #
380
- # # Create a (shallow-cloned) duplicate of an object.
381
- # _.clone = function(obj) {
382
- # if (_.isArray(obj)) return obj.slice(0);
383
- # return _.extend({}, obj);
384
- # };
373
+ for i in [(funcs.length - 1)..0]
374
+ args: [funcs[i].apply(this, args)]
375
+ args[0]
376
+
377
+
378
+ # ------------------------- Object Functions: ----------------------------
379
+
380
+ # Retrieve the names of an object's properties.
381
+ _.keys: obj =>
382
+ return _.range(0, obj.length) if _.isArray(obj)
383
+ key for val, key in obj
384
+
385
+
386
+ # Retrieve the values of an object's properties.
387
+ _.values: obj =>
388
+ _.map(obj, _.identity)
389
+
390
+
391
+ # Return a sorted list of the function names available in Underscore.
392
+ _.functions: obj =>
393
+ _.select(_.keys(obj), key => _.isFunction(obj[key])).sort()
394
+
395
+
396
+ # Extend a given object with all of the properties in a source object.
397
+ _.extend: destination, source =>
398
+ for val, key in source
399
+ destination[key]: val
400
+ destination
401
+
402
+
403
+ # Create a (shallow-cloned) duplicate of an object.
404
+ _.clone: obj =>
405
+ return obj.slice(0) if _.isArray(obj)
406
+ _.extend({}, obj)
407
+
408
+
409
+ # Invokes interceptor with the obj, and then returns obj.
410
+ # The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain.
411
+ _.tap: obj, interceptor =>
412
+ interceptor(obj)
413
+ obj
414
+
385
415
 
386
416
  # Perform a deep comparison to check if two objects are equal.
387
417
  _.isEqual: a, b =>
@@ -402,10 +432,10 @@ _.reduceRight: obj, memo, iterator, context =>
402
432
  return true if _.isNaN(a) and _.isNaN(b)
403
433
  # Compare regular expressions.
404
434
  if _.isRegExp(a) and _.isRegExp(b)
405
- return a.source is b.source and \
406
- a.global is b.global and \
407
- a.ignoreCase is b.ignoreCase and \
408
- a.multiline is b.multiline.
435
+ return a.source is b.source and
436
+ a.global is b.global and
437
+ a.ignoreCase is b.ignoreCase and
438
+ a.multiline is b.multiline
409
439
  # If a is not an object by this point, we can't handle it.
410
440
  return false if atype isnt 'object'
411
441
  # Check for different array lengths before comparing contents.
@@ -416,42 +446,57 @@ _.reduceRight: obj, memo, iterator, context =>
416
446
  return false if aKeys.length isnt bKeys.length
417
447
  # Recursive comparison of contents.
418
448
  # for (var key in a) if (!_.isEqual(a[key], b[key])) return false;
419
- return true.
449
+ return true
450
+
420
451
 
421
452
  # Is a given array or object empty?
422
- _.isEmpty: obj => _.keys(obj).length is 0.
453
+ _.isEmpty: obj => _.keys(obj).length is 0
454
+
423
455
 
424
456
  # Is a given value a DOM element?
425
- _.isElement: obj => !!(obj and obj.nodeType is 1).
457
+ _.isElement: obj => obj and obj.nodeType is 1
458
+
459
+
460
+ # Is a given value an array?
461
+ _.isArray: obj => !!(obj and obj.concat and obj.unshift)
462
+
426
463
 
427
464
  # Is a given variable an arguments object?
428
- _.isArguments: obj => obj and _.isNumber(obj.length) and !_.isArray(obj) and !propertyIsEnumerable.call(obj, 'length').
465
+ _.isArguments: obj => obj and _.isNumber(obj.length) and !_.isArray(obj) and !propertyIsEnumerable.call(obj, 'length')
466
+
467
+
468
+ # Is the given value a function?
469
+ _.isFunction: obj => !!(obj and obj.constructor and obj.call and obj.apply)
470
+
471
+
472
+ # Is the given value a string?
473
+ _.isString: obj => !!(obj is '' or (obj and obj.charCodeAt and obj.substr))
474
+
475
+
476
+ # Is a given value a number?
477
+ _.isNumber: obj => toString.call(obj) is '[object Number]'
478
+
479
+
480
+ # Is a given value a Date?
481
+ _.isDate: obj => !!(obj and obj.getTimezoneOffset and obj.setUTCFullYear)
482
+
483
+
484
+ # Is the given value a regular expression?
485
+ _.isRegExp: obj => !!(obj and obj.exec and (obj.ignoreCase or obj.ignoreCase is false))
486
+
429
487
 
430
488
  # Is the given value NaN -- this one is interesting. NaN != NaN, and
431
489
  # isNaN(undefined) == true, so we make sure it's a number first.
432
- _.isNaN: obj => _.isNumber(obj) and isNaN(obj).
490
+ _.isNaN: obj => _.isNumber(obj) and window.isNaN(obj)
491
+
433
492
 
434
493
  # Is a given value equal to null?
435
- _.isNull: obj => obj is null.
494
+ _.isNull: obj => obj is null
495
+
436
496
 
437
497
  # Is a given variable undefined?
438
- _.isUndefined: obj => typeof obj is 'undefined'.
498
+ _.isUndefined: obj => typeof obj is 'undefined'
439
499
 
440
- # Invokes interceptor with the obj, and then returns obj.
441
- # The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain.
442
- _.tap: obj, interceptor =>
443
- interceptor(obj)
444
- obj.
445
-
446
- # # Define the isArray, isDate, isFunction, isNumber, isRegExp, and isString
447
- # # functions based on their toString identifiers.
448
- # var types = ['Array', 'Date', 'Function', 'Number', 'RegExp', 'String'];
449
- # for (var i=0, l=types.length; i<l; i++) {
450
- # (function() {
451
- # var identifier = '[object ' + types[i] + ']';
452
- # _['is' + types[i]] = function(obj) { return toString.call(obj) == identifier; };
453
- # })();
454
- # }
455
500
 
456
501
  # -------------------------- Utility Functions: --------------------------
457
502
 
@@ -459,39 +504,41 @@ _.reduceRight: obj, memo, iterator, context =>
459
504
  # previous owner. Returns a reference to the Underscore object.
460
505
  _.noConflict: =>
461
506
  root._: previousUnderscore
462
- this.
507
+ this
508
+
463
509
 
464
510
  # Keep the identity function around for default iterators.
465
- _.identity: value => value.
511
+ _.identity: value => value
512
+
466
513
 
467
514
  # Break out of the middle of an iteration.
468
- _.breakLoop: => throw breaker.
469
-
470
- # # Generate a unique integer id (unique within the entire client session).
471
- # # Useful for temporary DOM ids.
472
- # var idCounter = 0;
473
- # _.uniqueId = function(prefix) {
474
- # var id = idCounter++;
475
- # return prefix ? prefix + id : id;
476
- # };
477
- #
478
- # # JavaScript templating a-la ERB, pilfered from John Resig's
479
- # # "Secrets of the JavaScript Ninja", page 83.
480
- # _.template = function(str, data) {
481
- # var fn = new Function('obj',
482
- # 'var p=[],print=function(){p.push.apply(p,arguments);};' +
483
- # 'with(obj){p.push(\'' +
484
- # str
485
- # .replace(/[\r\t\n]/g, " ")
486
- # .split("<%").join("\t")
487
- # .replace(/((^|%>)[^\t]*)'/g, "$1\r")
488
- # .replace(/\t=(.*?)%>/g, "',$1,'")
489
- # .split("\t").join("');")
490
- # .split("%>").join("p.push('")
491
- # .split("\r").join("\\'")
492
- # + "');}return p.join('');");
493
- # return data ? fn(data) : fn;
494
- # };
515
+ _.breakLoop: => throw breaker
516
+
517
+
518
+ # Generate a unique integer id (unique within the entire client session).
519
+ # Useful for temporary DOM ids.
520
+ idCounter: 0
521
+ _.uniqueId: prefix =>
522
+ (prefix or '') + idCounter++
523
+
524
+
525
+ # JavaScript templating a-la ERB, pilfered from John Resig's
526
+ # "Secrets of the JavaScript Ninja", page 83.
527
+ _.template: str, data =>
528
+ `var fn = new Function('obj',
529
+ 'var p=[],print=function(){p.push.apply(p,arguments);};' +
530
+ 'with(obj){p.push(\'' +
531
+ str.
532
+ replace(/[\r\t\n]/g, " ").
533
+ split("<%").join("\t").
534
+ replace(/((^|%>)[^\t]*)'/g, "$1\r").
535
+ replace(/\t=(.*?)%>/g, "',$1,'").
536
+ split("\t").join("');").
537
+ split("%>").join("p.push('").
538
+ split("\r").join("\\'") +
539
+ "');}return p.join('');")`
540
+ if data then fn(data) else fn
541
+
495
542
 
496
543
  # ------------------------------- Aliases ----------------------------------
497
544
 
@@ -505,48 +552,42 @@ _.reduceRight: obj, memo, iterator, context =>
505
552
  _.tail: _.rest
506
553
  _.methods: _.functions
507
554
 
508
- # /*------------------------ Setup the OOP Wrapper: --------------------------*/
509
- #
510
- # # Helper function to continue chaining intermediate results.
511
- # var result = function(obj, chain) {
512
- # return chain ? _(obj).chain() : obj;
513
- # };
514
- #
515
- # # Add all of the Underscore functions to the wrapper object.
516
- # _.each(_.functions(_), function(name) {
517
- # var method = _[name];
518
- # wrapper.prototype[name] = function() {
519
- # unshift.call(arguments, this._wrapped);
520
- # return result(method.apply(_, arguments), this._chain);
521
- # };
522
- # });
523
- #
524
- # # Add all mutator Array functions to the wrapper.
525
- # _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
526
- # var method = Array.prototype[name];
527
- # wrapper.prototype[name] = function() {
528
- # method.apply(this._wrapped, arguments);
529
- # return result(this._wrapped, this._chain);
530
- # };
531
- # });
532
- #
533
- # # Add all accessor Array functions to the wrapper.
534
- # _.each(['concat', 'join', 'slice'], function(name) {
535
- # var method = Array.prototype[name];
536
- # wrapper.prototype[name] = function() {
537
- # return result(method.apply(this._wrapped, arguments), this._chain);
538
- # };
539
- # });
540
- #
541
- # # Start chaining a wrapped Underscore object.
542
- # wrapper.prototype.chain = function() {
543
- # this._chain = true;
544
- # return this;
545
- # };
546
- #
547
- # # Extracts the result from a wrapped and chained object.
548
- # wrapper.prototype.value = function() {
549
- # return this._wrapped;
550
- # };
551
- #
552
- # ()
555
+
556
+ # /*------------------------ Setup the OOP Wrapper: --------------------------*/
557
+
558
+ # Helper function to continue chaining intermediate results.
559
+ result: obj, chain =>
560
+ if chain then _(obj).chain() else obj
561
+
562
+
563
+ # Add all of the Underscore functions to the wrapper object.
564
+ _.each(_.functions(_)) name =>
565
+ method: _[name]
566
+ wrapper.prototype[name]: =>
567
+ unshift.call(arguments, this._wrapped)
568
+ result(method.apply(_, arguments), this._chain)
569
+
570
+
571
+ # Add all mutator Array functions to the wrapper.
572
+ _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift']) name =>
573
+ method: Array.prototype[name]
574
+ wrapper.prototype[name]: =>
575
+ method.apply(this._wrapped, arguments)
576
+ result(this._wrapped, this._chain)
577
+
578
+
579
+ # Add all accessor Array functions to the wrapper.
580
+ _.each(['concat', 'join', 'slice']) name =>
581
+ method: Array.prototype[name]
582
+ wrapper.prototype[name]: =>
583
+ result(method.apply(this._wrapped, arguments), this._chain)
584
+
585
+
586
+ # Start chaining a wrapped Underscore object.
587
+ wrapper.prototype.chain: =>
588
+ this._chain: true
589
+ this
590
+
591
+
592
+ # Extracts the result from a wrapped and chained object.
593
+ wrapper.prototype.value: => this._wrapped