coffee-script 0.2.6 → 0.3.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.2.6' # Keep version in sync with coffee-script.rb
4
- s.date = '2010-1-17'
3
+ s.version = '0.3.0' # Keep version in sync with coffee-script.rb
4
+ s.date = '2010-1-26'
5
5
 
6
6
  s.homepage = "http://jashkenas.github.com/coffee-script/"
7
7
  s.summary = "The CoffeeScript Compiler"
@@ -22,5 +22,6 @@ 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', 'package.json']
25
+ s.files = Dir['bin/*', 'examples/*', 'extras/**/*', 'lib/**/*',
26
+ 'coffee-script.gemspec', 'LICENSE', 'README', 'package.json']
26
27
  end
data/examples/code.coffee CHANGED
@@ -1,14 +1,14 @@
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 isnt 0
7
7
 
8
- even: x => x % 2 isnt 0
8
+ even: (x) -> x % 2 is 0
9
9
 
10
- run_loop: =>
11
- fire_events(e => e.stopPropagation())
10
+ run_loop: ->
11
+ fire_events((e) -> e.stopPropagation())
12
12
  listen()
13
13
  wait()
14
14
 
@@ -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
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
 
@@ -54,7 +54,7 @@ decoration: medal_of_honor if war_hero
54
54
  go_to_sleep() unless coffee
55
55
 
56
56
  # Returning early:
57
- race: =>
57
+ race: ->
58
58
  run()
59
59
  walk()
60
60
  crawl()
@@ -103,7 +103,7 @@ while true
103
103
 
104
104
  # Lexical scoping.
105
105
  v_1: 5
106
- change_a_and_set_b: =>
106
+ change_a_and_set_b: ->
107
107
  v_1: 10
108
108
  v_2: 15
109
109
  v_2: 20
@@ -128,7 +128,7 @@ activity: switch day
128
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,19 +140,19 @@ 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: =>
144
- Animal::move: meters =>
143
+ Animal: ->
144
+ Animal::move: (meters) ->
145
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
- Snake::move: =>
149
+ Snake::move: ->
150
150
  alert('Slithering...')
151
151
  super(5)
152
152
 
153
- Horse: name => this.name: name
153
+ Horse: (name) -> this.name: name
154
154
  Horse extends Animal
155
- Horse::move: =>
155
+ Horse::move: ->
156
156
  alert('Galloping...')
157
157
  super(45)
158
158
 
@@ -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,43 @@
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
+ }
22
+
23
+
24
+
25
+ # class << LotteryDraw
26
+ # def play
27
+ # result = LotteryTicket.new_random
28
+ # winners = {}
29
+ # @@tickets.each do |buyer, ticket_list|
30
+ # ticket_list.each do |ticket|
31
+ # score = ticket.score( result )
32
+ # next if score.zero?
33
+ # winners[buyer] ||= []
34
+ # winners[buyer] << [ ticket, score ]
35
+ # end
36
+ # end
37
+ # @@tickets.clear
38
+ # winners
39
+ # end
40
+ # end
41
+
42
+ LotteryDraw: {
43
+ play: ->
44
+ result: LotteryTicket.new_random()
45
+ winners: {}
46
+ this.tickets.each (buyer, ticket_list) ->
47
+ ticket_list.each (ticket) ->
48
+ score: ticket.score(result)
49
+ return if score is 0
50
+ winners[buyer] ||= []
51
+ winners[buyer].push([ticket, score])
52
+ this.tickets: {}
53
+ winners
21
54
  }
22
55
 
23
56
 
@@ -32,8 +65,8 @@ LotteryTicket: {
32
65
  # end
33
66
 
34
67
  WishScanner: {
35
- scan_for_a_wish: =>
36
- wish: this.read().detect(thought => thought.index('wish: ') is 0)
68
+ scan_for_a_wish: ->
69
+ wish: this.read().detect((thought) -> thought.index('wish: ') is 0)
37
70
  wish.replace('wish: ', '')
38
71
  }
39
72
 
@@ -78,7 +111,7 @@ WishScanner: {
78
111
  Creature : {
79
112
 
80
113
  # This method applies a hit taken during a fight.
81
- hit: damage =>
114
+ hit: (damage) ->
82
115
  p_up: Math.rand(this.charisma)
83
116
  if p_up % 9 is 7
84
117
  this.life += p_up / 4
@@ -87,7 +120,7 @@ Creature : {
87
120
  if this.life <= 0 then puts("[" + this.name + " has died.]")
88
121
 
89
122
  # This method takes one turn in a fight.
90
- fight: enemy, weapon =>
123
+ fight: (enemy, weapon) ->
91
124
  if this.life <= 0 then return puts("[" + this.name + "is too dead to fight!]")
92
125
 
93
126
  # Attack the opponent.
@@ -123,12 +156,12 @@ Creature : {
123
156
  # Get evil idea and swap in code words
124
157
  print("Enter your new idea: ")
125
158
  idea: gets()
126
- code_words.each(real, code => idea.replace(real, code))
159
+ code_words.each((real, code) -> idea.replace(real, code))
127
160
 
128
161
  # Save the jibberish to a new file
129
162
  print("File encoded. Please enter a name for this idea: ")
130
163
  idea_name: gets().strip()
131
- File.open("idea-" + idea_name + '.txt', 'w', file => file.write(idea))
164
+ File.open("idea-" + idea_name + '.txt', 'w', (file) -> file.write(idea))
132
165
 
133
166
 
134
167
 
@@ -144,7 +177,7 @@ File.open("idea-" + idea_name + '.txt', 'w', file => file.write(idea))
144
177
  # end
145
178
  # end
146
179
 
147
- wipe_mutterings_from: sentence =>
180
+ wipe_mutterings_from: (sentence) ->
148
181
  throw new Error("cannot wipe mutterings") unless sentence.indexOf
149
182
  while sentence.indexOf('(') >= 0
150
183
  open: sentence.indexOf('(') - 1
@@ -8,7 +8,7 @@ print("Odelay!") for i in [1..5]
8
8
  # add = (x, y): x + y.
9
9
  # add(2, 4) string print
10
10
 
11
- add: x, y => x + y
11
+ add: (x, y) -> x + y
12
12
  print(add(2, 4))
13
13
 
14
14
 
@@ -31,7 +31,7 @@ print({language: 'Potion', pointless: true}['language'])
31
31
  # minus = (x, y): x - y.
32
32
  # minus (y=10, x=6)
33
33
 
34
- minus: x, y => x - y
34
+ minus: (x, y) -> x - y
35
35
  minus(6, 10)
36
36
 
37
37
 
@@ -53,8 +53,8 @@ for key, val of {dog: 'canine', cat: 'feline', fox: 'vulpine'}
53
53
  # Person print = ():
54
54
  # ('My name is ', /name, '.') join print.
55
55
 
56
- Person: =>
57
- Person::print: =>
56
+ Person: ->
57
+ Person::print: ->
58
58
  print('My name is ' + this.name + '.')
59
59
 
60
60
 
@@ -71,9 +71,9 @@ print(p.name)
71
71
  #
72
72
  # Policeman ('Constable') print
73
73
 
74
- Policeman: rank => this.rank: rank
74
+ Policeman: (rank) -> this.rank: rank
75
75
  Policeman extends Person
76
- Policeman::print: =>
76
+ Policeman::print: ->
77
77
  print('My name is ' + this.name + " and I'm a " + this.rank + '.')
78
78
 
79
79
  print(new Policeman('Constable'))
@@ -115,13 +115,13 @@ table: {
115
115
  # String length = (): 10.
116
116
 
117
117
  # this foul business...
118
- String::length: => 10
118
+ String::length: -> 10
119
119
 
120
120
 
121
121
  # block = :
122
122
  # 'potion' print.
123
123
 
124
- block: =>
124
+ block: ->
125
125
  print('potion')
126
126
 
127
127
 
@@ -178,7 +178,7 @@ if (3).gender?
178
178
  # HomePage get = (url):
179
179
  # session = url query ? at ('session').
180
180
 
181
- HomePage::get: url =>
181
+ HomePage::get: (url) ->
182
182
  session: url.query.session if url.query?
183
183
 
184
184
 
@@ -187,7 +187,7 @@ HomePage::get: url =>
187
187
  # b /left = BTree ()
188
188
  # b /right = BTree ()
189
189
 
190
- BTree: =>
190
+ BTree: ->
191
191
  b: new BTree()
192
192
  b.left: new BTree()
193
193
  b.right: new BTree()
@@ -199,7 +199,7 @@ b.right: new BTree()
199
199
  # if (b ? /left):
200
200
  # 'left path found!' print.
201
201
 
202
- BTree: =>
202
+ BTree: ->
203
203
  b: new BTree()
204
204
 
205
205
  print('left path found!') if b.left?
@@ -1,6 +1,6 @@
1
1
 
2
2
  # Underscore.coffee
3
- # (c) 2009 Jeremy Ashkenas, DocumentCloud Inc.
3
+ # (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
4
4
  # Underscore is freely distributable under the terms of the MIT license.
5
5
  # Portions of Underscore are inspired by or borrowed from Prototype.js,
6
6
  # Oliver Steele's Functional, and John Resig's Micro-Templating.
@@ -21,7 +21,7 @@
21
21
  # If Underscore is called as a function, it returns a wrapped object that
22
22
  # can be used OO-style. This wrapper holds altered versions of all the
23
23
  # underscore functions. Wrapped objects may be chained.
24
- wrapper: obj =>
24
+ wrapper: (obj) ->
25
25
  this._wrapped: obj
26
26
  this
27
27
 
@@ -31,7 +31,7 @@
31
31
 
32
32
 
33
33
  # Create a safe reference to the Underscore object forreference below.
34
- _: root._: obj => new wrapper(obj)
34
+ _: root._: (obj) -> new wrapper(obj)
35
35
 
36
36
 
37
37
  # Export the Underscore object for CommonJS.
@@ -47,14 +47,14 @@
47
47
 
48
48
 
49
49
  # Current version.
50
- _.VERSION: '0.5.5'
50
+ _.VERSION: '0.5.7'
51
51
 
52
52
 
53
53
  # ------------------------ Collection Functions: ---------------------------
54
54
 
55
55
  # The cornerstone, an each implementation.
56
56
  # Handles objects implementing forEach, arrays, and raw objects.
57
- _.each: obj, iterator, context =>
57
+ _.each: (obj, iterator, context) ->
58
58
  index: 0
59
59
  try
60
60
  return obj.forEach(iterator, context) if obj.forEach
@@ -68,36 +68,36 @@
68
68
 
69
69
  # Return the results of applying the iterator to each element. Use JavaScript
70
70
  # 1.6's version of map, if possible.
71
- _.map: obj, iterator, context =>
71
+ _.map: (obj, iterator, context) ->
72
72
  return obj.map(iterator, context) if (obj and _.isFunction(obj.map))
73
73
  results: []
74
- _.each(obj) value, index, list =>
74
+ _.each obj, (value, index, list) ->
75
75
  results.push(iterator.call(context, value, index, list))
76
76
  results
77
77
 
78
78
 
79
79
  # Reduce builds up a single result from a list of values. Also known as
80
80
  # inject, or foldl. Uses JavaScript 1.8's version of reduce, if possible.
81
- _.reduce: obj, memo, iterator, context =>
81
+ _.reduce: (obj, memo, iterator, context) ->
82
82
  return obj.reduce(_.bind(iterator, context), memo) if (obj and _.isFunction(obj.reduce))
83
- _.each(obj) value, index, list =>
83
+ _.each obj, (value, index, list) ->
84
84
  memo: iterator.call(context, memo, value, index, list)
85
85
  memo
86
86
 
87
87
 
88
88
  # The right-associative version of reduce, also known as foldr. Uses
89
89
  # JavaScript 1.8's version of reduceRight, if available.
90
- _.reduceRight: obj, memo, iterator, context =>
90
+ _.reduceRight: (obj, memo, iterator, context) ->
91
91
  return obj.reduceRight(_.bind(iterator, context), memo) if (obj and _.isFunction(obj.reduceRight))
92
- _.each(_.clone(_.toArray(obj)).reverse()) value, index =>
92
+ _.each _.clone(_.toArray(obj)).reverse(), (value, index) ->
93
93
  memo: iterator.call(context, memo, value, index, obj)
94
94
  memo
95
95
 
96
96
 
97
97
  # Return the first value which passes a truth test.
98
- _.detect: obj, iterator, context =>
98
+ _.detect: (obj, iterator, context) ->
99
99
  result: null
100
- _.each(obj) value, index, list =>
100
+ _.each obj, (value, index, list) ->
101
101
  if iterator.call(context, value, index, list)
102
102
  result: value
103
103
  _.breakLoop()
@@ -106,47 +106,47 @@
106
106
 
107
107
  # Return all the elements that pass a truth test. Use JavaScript 1.6's
108
108
  # filter(), if it exists.
109
- _.select: obj, iterator, context =>
109
+ _.select: (obj, iterator, context) ->
110
110
  if obj and _.isFunction(obj.filter) then return obj.filter(iterator, context)
111
111
  results: []
112
- _.each(obj) value, index, list =>
112
+ _.each obj, (value, index, list) ->
113
113
  results.push(value) if iterator.call(context, value, index, list)
114
114
  results
115
115
 
116
116
 
117
117
  # Return all the elements for which a truth test fails.
118
- _.reject: obj, iterator, context =>
118
+ _.reject: (obj, iterator, context) ->
119
119
  results: []
120
- _.each(obj) value, index, list =>
120
+ _.each obj, (value, index, list) ->
121
121
  results.push(value) if not iterator.call(context, value, index, list)
122
122
  results
123
123
 
124
124
 
125
125
  # Determine whether all of the elements match a truth test. Delegate to
126
126
  # JavaScript 1.6's every(), if it is present.
127
- _.all: obj, iterator, context =>
127
+ _.all: (obj, iterator, context) ->
128
128
  iterator ||= _.identity
129
129
  return obj.every(iterator, context) if obj and _.isFunction(obj.every)
130
130
  result: true
131
- _.each(obj) value, index, list =>
131
+ _.each obj, (value, index, list) ->
132
132
  _.breakLoop() unless (result: result and iterator.call(context, value, index, list))
133
133
  result
134
134
 
135
135
 
136
136
  # Determine if at least one element in the object matches a truth test. Use
137
137
  # JavaScript 1.6's some(), if it exists.
138
- _.any: obj, iterator, context =>
138
+ _.any: (obj, iterator, context) ->
139
139
  iterator ||= _.identity
140
140
  return obj.some(iterator, context) if obj and _.isFunction(obj.some)
141
141
  result: false
142
- _.each(obj) value, index, list =>
142
+ _.each obj, (value, index, list) ->
143
143
  _.breakLoop() if (result: iterator.call(context, value, index, list))
144
144
  result
145
145
 
146
146
 
147
147
  # Determine if a given value is included in the array or object,
148
148
  # based on '==='.
149
- _.include: obj, target =>
149
+ _.include: (obj, target) ->
150
150
  return _.indexOf(obj, target) isnt -1 if _.isArray(obj)
151
151
  for key, val of obj
152
152
  return true if val is target
@@ -154,49 +154,49 @@
154
154
 
155
155
 
156
156
  # Invoke a method with arguments on every item in a collection.
157
- _.invoke: obj, method =>
157
+ _.invoke: (obj, method) ->
158
158
  args: _.rest(arguments, 2)
159
159
  (if method then val[method] else val).apply(val, args) for val in obj
160
160
 
161
161
 
162
162
  # Convenience version of a common use case of map: fetching a property.
163
- _.pluck: obj, key =>
164
- _.map(obj, (val => val[key]))
163
+ _.pluck: (obj, key) ->
164
+ _.map(obj, ((val) -> val[key]))
165
165
 
166
166
 
167
167
  # Return the maximum item or (item-based computation).
168
- _.max: obj, iterator, context =>
168
+ _.max: (obj, iterator, context) ->
169
169
  return Math.max.apply(Math, obj) if not iterator and _.isArray(obj)
170
170
  result: {computed: -Infinity}
171
- _.each(obj) value, index, list =>
171
+ _.each obj, (value, index, list) ->
172
172
  computed: if iterator then iterator.call(context, value, index, list) else value
173
173
  computed >= result.computed and (result: {value: value, computed: computed})
174
174
  result.value
175
175
 
176
176
 
177
177
  # Return the minimum element (or element-based computation).
178
- _.min: obj, iterator, context =>
178
+ _.min: (obj, iterator, context) ->
179
179
  return Math.min.apply(Math, obj) if not iterator and _.isArray(obj)
180
180
  result: {computed: Infinity}
181
- _.each(obj) value, index, list =>
181
+ _.each obj, (value, index, list) ->
182
182
  computed: if iterator then iterator.call(context, value, index, list) else value
183
183
  computed < result.computed and (result: {value: value, computed: computed})
184
184
  result.value
185
185
 
186
186
 
187
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 =>
188
+ _.sortBy: (obj, iterator, context) ->
189
+ _.pluck(((_.map obj, (value, index, list) ->
190
190
  {value: value, criteria: iterator.call(context, value, index, list)}
191
- ).sort() left, right =>
191
+ ).sort((left, right) ->
192
192
  a: left.criteria; b: right.criteria
193
193
  if a < b then -1 else if a > b then 1 else 0
194
- ), 'value')
194
+ )), 'value')
195
195
 
196
196
 
197
197
  # Use a comparator function to figure out at what index an object should
198
198
  # be inserted so as to maintain order. Uses binary search.
199
- _.sortedIndex: array, obj, iterator =>
199
+ _.sortedIndex: (array, obj, iterator) ->
200
200
  iterator ||= _.identity
201
201
  low: 0; high: array.length
202
202
  while low < high
@@ -206,7 +206,7 @@
206
206
 
207
207
 
208
208
  # Convert anything iterable into a real, live array.
209
- _.toArray: iterable =>
209
+ _.toArray: (iterable) ->
210
210
  return [] if (!iterable)
211
211
  return iterable.toArray() if (iterable.toArray)
212
212
  return iterable if (_.isArray(iterable))
@@ -215,7 +215,7 @@
215
215
 
216
216
 
217
217
  # Return the number of elements in an object.
218
- _.size: obj => _.toArray(obj).length
218
+ _.size: (obj) -> _.toArray(obj).length
219
219
 
220
220
 
221
221
  # -------------------------- Array Functions: ------------------------------
@@ -223,7 +223,7 @@
223
223
  # Get the first element of an array. Passing "n" will return the first N
224
224
  # values in the array. Aliased as "head". The "guard" check allows it to work
225
225
  # with _.map.
226
- _.first: array, n, guard =>
226
+ _.first: (array, n, guard) ->
227
227
  if n and not guard then slice.call(array, 0, n) else array[0]
228
228
 
229
229
 
@@ -231,35 +231,35 @@
231
231
  # Especially useful on the arguments object. Passing an "index" will return
232
232
  # the rest of the values in the array from that index onward. The "guard"
233
233
  # check allows it to work with _.map.
234
- _.rest: array, index, guard =>
234
+ _.rest: (array, index, guard) ->
235
235
  slice.call(array, if _.isUndefined(index) or guard then 1 else index)
236
236
 
237
237
 
238
238
  # Get the last element of an array.
239
- _.last: array => array[array.length - 1]
239
+ _.last: (array) -> array[array.length - 1]
240
240
 
241
241
 
242
242
  # Trim out all falsy values from an array.
243
- _.compact: array => array[i] for i in [0...array.length] when array[i]
243
+ _.compact: (array) -> array[i] for i in [0...array.length] when array[i]
244
244
 
245
245
 
246
246
  # Return a completely flattened version of an array.
247
- _.flatten: array =>
248
- _.reduce(array, []) memo, value =>
247
+ _.flatten: (array) ->
248
+ _.reduce array, [], (memo, value) ->
249
249
  return memo.concat(_.flatten(value)) if _.isArray(value)
250
250
  memo.push(value)
251
251
  memo
252
252
 
253
253
 
254
254
  # Return a version of the array that does not contain the specified value(s).
255
- _.without: array =>
255
+ _.without: (array) ->
256
256
  values: _.rest(arguments)
257
257
  val for val in _.toArray(array) when not _.include(values, val)
258
258
 
259
259
 
260
260
  # Produce a duplicate-free version of the array. If the array has already
261
261
  # been sorted, you have the option of using a faster algorithm.
262
- _.uniq: array, isSorted =>
262
+ _.uniq: (array, isSorted) ->
263
263
  memo: []
264
264
  for el, i in _.toArray(array)
265
265
  memo.push(el) if i is 0 || (if isSorted is true then _.last(memo) isnt el else not _.include(memo, el))
@@ -268,28 +268,27 @@
268
268
 
269
269
  # Produce an array that contains every item shared between all the
270
270
  # passed-in arrays.
271
- _.intersect: array =>
271
+ _.intersect: (array) ->
272
272
  rest: _.rest(arguments)
273
- _.select(_.uniq(array)) item =>
274
- _.all(rest) other =>
273
+ _.select _.uniq(array), (item) ->
274
+ _.all rest, (other) ->
275
275
  _.indexOf(other, item) >= 0
276
276
 
277
277
 
278
278
  # Zip together multiple lists into a single array -- elements that share
279
279
  # an index go together.
280
- _.zip: =>
281
- args: _.toArray(arguments)
282
- length: _.max(_.pluck(args, 'length'))
280
+ _.zip: ->
281
+ length: _.max(_.pluck(arguments, 'length'))
283
282
  results: new Array(length)
284
283
  for i in [0...length]
285
- results[i]: _.pluck(args, String(i))
284
+ results[i]: _.pluck(arguments, String(i))
286
285
  results
287
286
 
288
287
 
289
288
  # If the browser doesn't supply us with indexOf (I'm looking at you, MSIE),
290
289
  # we need this function. Return the position of the first occurence of an
291
290
  # item in an array, or -1 if the item is not included in the array.
292
- _.indexOf: array, item =>
291
+ _.indexOf: (array, item) ->
293
292
  return array.indexOf(item) if array.indexOf
294
293
  i: 0; l: array.length
295
294
  while l - i
@@ -299,7 +298,7 @@
299
298
 
300
299
  # Provide JavaScript 1.6's lastIndexOf, delegating to the native function,
301
300
  # if possible.
302
- _.lastIndexOf: array, item =>
301
+ _.lastIndexOf: (array, item) ->
303
302
  return array.lastIndexOf(item) if array.lastIndexOf
304
303
  i: array.length
305
304
  while i
@@ -310,8 +309,8 @@
310
309
  # Generate an integer Array containing an arithmetic progression. A port of
311
310
  # the native Python range() function. See:
312
311
  # http://docs.python.org/library/functions.html#range
313
- _.range: start, stop, step =>
314
- a: _.toArray(arguments)
312
+ _.range: (start, stop, step) ->
313
+ a: arguments
315
314
  solo: a.length <= 1
316
315
  i: start: if solo then 0 else a[0];
317
316
  stop: if solo then a[0] else a[1];
@@ -331,45 +330,45 @@
331
330
 
332
331
  # Create a function bound to a given object (assigning 'this', and arguments,
333
332
  # optionally). Binding with arguments is also known as 'curry'.
334
- _.bind: func, obj =>
333
+ _.bind: (func, obj) ->
335
334
  args: _.rest(arguments, 2)
336
- => func.apply(obj or root, args.concat(_.toArray(arguments)))
335
+ -> func.apply(obj or root, args.concat(arguments))
337
336
 
338
337
 
339
338
  # Bind all of an object's methods to that object. Useful for ensuring that
340
339
  # all callbacks defined on an object belong to it.
341
- _.bindAll: obj =>
340
+ _.bindAll: (obj) ->
342
341
  funcs: if arguments.length > 1 then _.rest(arguments) else _.functions(obj)
343
- _.each(funcs, (f => obj[f]: _.bind(obj[f], obj)))
342
+ _.each(funcs, (f) -> obj[f]: _.bind(obj[f], obj))
344
343
  obj
345
344
 
346
345
 
347
346
  # Delays a function for the given number of milliseconds, and then calls
348
347
  # it with the arguments supplied.
349
- _.delay: func, wait =>
348
+ _.delay: (func, wait) ->
350
349
  args: _.rest(arguments, 2)
351
- setTimeout((=> func.apply(func, args)), wait)
350
+ setTimeout((-> func.apply(func, args)), wait)
352
351
 
353
352
 
354
353
  # Defers a function, scheduling it to run after the current call stack has
355
354
  # cleared.
356
- _.defer: func =>
355
+ _.defer: (func) ->
357
356
  _.delay.apply(_, [func, 1].concat(_.rest(arguments)))
358
357
 
359
358
 
360
359
  # Returns the first function passed as an argument to the second,
361
360
  # allowing you to adjust arguments, run code before and after, and
362
361
  # conditionally execute the original function.
363
- _.wrap: func, wrapper =>
364
- => wrapper.apply(wrapper, [func].concat(_.toArray(arguments)))
362
+ _.wrap: (func, wrapper) ->
363
+ -> wrapper.apply(wrapper, [func].concat(arguments))
365
364
 
366
365
 
367
366
  # Returns a function that is the composition of a list of functions, each
368
367
  # consuming the return value of the function that follows.
369
- _.compose: =>
370
- funcs: _.toArray(arguments)
371
- =>
372
- args: _.toArray(arguments)
368
+ _.compose: ->
369
+ funcs: arguments
370
+ ->
371
+ args: arguments
373
372
  for i in [(funcs.length - 1)..0]
374
373
  args: [funcs[i].apply(this, args)]
375
374
  args[0]
@@ -378,43 +377,43 @@
378
377
  # ------------------------- Object Functions: ----------------------------
379
378
 
380
379
  # Retrieve the names of an object's properties.
381
- _.keys: obj =>
380
+ _.keys: (obj) ->
382
381
  return _.range(0, obj.length) if _.isArray(obj)
383
382
  key for key, val of obj
384
383
 
385
384
 
386
385
  # Retrieve the values of an object's properties.
387
- _.values: obj =>
386
+ _.values: (obj) ->
388
387
  _.map(obj, _.identity)
389
388
 
390
389
 
391
390
  # Return a sorted list of the function names available in Underscore.
392
- _.functions: obj =>
393
- _.select(_.keys(obj), key => _.isFunction(obj[key])).sort()
391
+ _.functions: (obj) ->
392
+ _.select(_.keys(obj), (key) -> _.isFunction(obj[key])).sort()
394
393
 
395
394
 
396
395
  # Extend a given object with all of the properties in a source object.
397
- _.extend: destination, source =>
396
+ _.extend: (destination, source) ->
398
397
  for key, val of source
399
398
  destination[key]: val
400
399
  destination
401
400
 
402
401
 
403
402
  # Create a (shallow-cloned) duplicate of an object.
404
- _.clone: obj =>
403
+ _.clone: (obj) ->
405
404
  return obj.slice(0) if _.isArray(obj)
406
405
  _.extend({}, obj)
407
406
 
408
407
 
409
408
  # Invokes interceptor with the obj, and then returns obj.
410
409
  # 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 =>
410
+ _.tap: (obj, interceptor) ->
412
411
  interceptor(obj)
413
412
  obj
414
413
 
415
414
 
416
415
  # Perform a deep comparison to check if two objects are equal.
417
- _.isEqual: a, b =>
416
+ _.isEqual: (a, b) ->
418
417
  # Check object identity.
419
418
  return true if a is b
420
419
  # Different types?
@@ -450,93 +449,104 @@
450
449
 
451
450
 
452
451
  # Is a given array or object empty?
453
- _.isEmpty: obj => _.keys(obj).length is 0
452
+ _.isEmpty: (obj) -> _.keys(obj).length is 0
454
453
 
455
454
 
456
455
  # Is a given value a DOM element?
457
- _.isElement: obj => obj and obj.nodeType is 1
456
+ _.isElement: (obj) -> obj and obj.nodeType is 1
458
457
 
459
458
 
460
459
  # Is a given value an array?
461
- _.isArray: obj => !!(obj and obj.concat and obj.unshift)
460
+ _.isArray: (obj) -> !!(obj and obj.concat and obj.unshift)
462
461
 
463
462
 
464
463
  # Is a given variable an arguments object?
465
- _.isArguments: obj => obj and _.isNumber(obj.length) and !_.isArray(obj) and !propertyIsEnumerable.call(obj, 'length')
464
+ _.isArguments: (obj) -> obj and _.isNumber(obj.length) and not obj.concat and
465
+ not obj.substr and not obj.apply and not propertyIsEnumerable.call(obj, 'length')
466
466
 
467
467
 
468
468
  # Is the given value a function?
469
- _.isFunction: obj => !!(obj and obj.constructor and obj.call and obj.apply)
469
+ _.isFunction: (obj) -> !!(obj and obj.constructor and obj.call and obj.apply)
470
470
 
471
471
 
472
472
  # Is the given value a string?
473
- _.isString: obj => !!(obj is '' or (obj and obj.charCodeAt and obj.substr))
473
+ _.isString: (obj) -> !!(obj is '' or (obj and obj.charCodeAt and obj.substr))
474
474
 
475
475
 
476
476
  # Is a given value a number?
477
- _.isNumber: obj => toString.call(obj) is '[object Number]'
477
+ _.isNumber: (obj) -> (obj is +obj) or toString.call(obj) is '[object Number]'
478
478
 
479
479
 
480
480
  # Is a given value a Date?
481
- _.isDate: obj => !!(obj and obj.getTimezoneOffset and obj.setUTCFullYear)
481
+ _.isDate: (obj) -> !!(obj and obj.getTimezoneOffset and obj.setUTCFullYear)
482
482
 
483
483
 
484
484
  # Is the given value a regular expression?
485
- _.isRegExp: obj => !!(obj and obj.exec and (obj.ignoreCase or obj.ignoreCase is false))
485
+ _.isRegExp: (obj) -> !!(obj and obj.exec and (obj.ignoreCase or obj.ignoreCase is false))
486
486
 
487
487
 
488
488
  # Is the given value NaN -- this one is interesting. NaN != NaN, and
489
489
  # isNaN(undefined) == true, so we make sure it's a number first.
490
- _.isNaN: obj => _.isNumber(obj) and window.isNaN(obj)
490
+ _.isNaN: (obj) -> _.isNumber(obj) and window.isNaN(obj)
491
491
 
492
492
 
493
493
  # Is a given value equal to null?
494
- _.isNull: obj => obj is null
494
+ _.isNull: (obj) -> obj is null
495
495
 
496
496
 
497
497
  # Is a given variable undefined?
498
- _.isUndefined: obj => typeof obj is 'undefined'
498
+ _.isUndefined: (obj) -> typeof obj is 'undefined'
499
499
 
500
500
 
501
501
  # -------------------------- Utility Functions: --------------------------
502
502
 
503
503
  # Run Underscore.js in noConflict mode, returning the '_' variable to its
504
504
  # previous owner. Returns a reference to the Underscore object.
505
- _.noConflict: =>
505
+ _.noConflict: ->
506
506
  root._: previousUnderscore
507
507
  this
508
508
 
509
509
 
510
510
  # Keep the identity function around for default iterators.
511
- _.identity: value => value
511
+ _.identity: (value) -> value
512
512
 
513
513
 
514
514
  # Break out of the middle of an iteration.
515
- _.breakLoop: => throw breaker
515
+ _.breakLoop: -> throw breaker
516
516
 
517
517
 
518
518
  # Generate a unique integer id (unique within the entire client session).
519
519
  # Useful for temporary DOM ids.
520
520
  idCounter: 0
521
- _.uniqueId: prefix =>
521
+ _.uniqueId: (prefix) ->
522
522
  (prefix or '') + idCounter++
523
523
 
524
524
 
525
+ # By default, Underscore uses ERB-style template delimiters, change the
526
+ # following template settings to use alternative delimiters.
527
+ _.templateSettings: {
528
+ start: '<%'
529
+ end: '%>'
530
+ interpolate: /<%=(.+?)%>/g
531
+ }
532
+
533
+
525
534
  # JavaScript templating a-la ERB, pilfered from John Resig's
526
535
  # "Secrets of the JavaScript Ninja", page 83.
527
- _.template: str, data =>
528
- `var fn = new Function('obj',
536
+ # Single-quotea fix from Rick Strahl's version.
537
+ _.template: (str, data) ->
538
+ c: _.templateSettings
539
+ fn: new Function 'obj',
529
540
  'var p=[],print=function(){p.push.apply(p,arguments);};' +
530
541
  '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('');")`
542
+ str.replace(/[\r\t\n]/g, " ")
543
+ .replace(new RegExp("'(?=[^"+c.end[0]+"]*"+c.end+")","g"),"\t")
544
+ .split("'").join("\\'")
545
+ .split("\t").join("'")
546
+ .replace(c.interpolate, "',$1,'")
547
+ .split(c.start).join("');")
548
+ .split(c.end).join("p.push('") +
549
+ "');}return p.join('');"
540
550
  if data then fn(data) else fn
541
551
 
542
552
 
@@ -556,39 +566,38 @@
556
566
  # /*------------------------ Setup the OOP Wrapper: --------------------------*/
557
567
 
558
568
  # Helper function to continue chaining intermediate results.
559
- result: obj, chain =>
569
+ result: (obj, chain) ->
560
570
  if chain then _(obj).chain() else obj
561
571
 
562
572
 
563
573
  # Add all of the Underscore functions to the wrapper object.
564
- _.each(_.functions(_)) name =>
574
+ _.each _.functions(_), (name) ->
565
575
  method: _[name]
566
- wrapper.prototype[name]: =>
567
- args: _.toArray(arguments)
568
- unshift.call(args, this._wrapped)
569
- result(method.apply(_, args), this._chain)
576
+ wrapper.prototype[name]: ->
577
+ unshift.call(arguments, this._wrapped)
578
+ result(method.apply(_, arguments), this._chain)
570
579
 
571
580
 
572
581
  # Add all mutator Array functions to the wrapper.
573
- _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift']) name =>
582
+ _.each ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], (name) ->
574
583
  method: Array.prototype[name]
575
- wrapper.prototype[name]: =>
584
+ wrapper.prototype[name]: ->
576
585
  method.apply(this._wrapped, arguments)
577
586
  result(this._wrapped, this._chain)
578
587
 
579
588
 
580
589
  # Add all accessor Array functions to the wrapper.
581
- _.each(['concat', 'join', 'slice']) name =>
590
+ _.each ['concat', 'join', 'slice'], (name) ->
582
591
  method: Array.prototype[name]
583
- wrapper.prototype[name]: =>
592
+ wrapper.prototype[name]: ->
584
593
  result(method.apply(this._wrapped, arguments), this._chain)
585
594
 
586
595
 
587
596
  # Start chaining a wrapped Underscore object.
588
- wrapper::chain: =>
597
+ wrapper::chain: ->
589
598
  this._chain: true
590
599
  this
591
600
 
592
601
 
593
602
  # Extracts the result from a wrapped and chained object.
594
- wrapper::value: => this._wrapped
603
+ wrapper::value: -> this._wrapped