coffee-script 0.2.6 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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