underscore-source 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  module Underscore
2
2
  module Source
3
- VERSION = "0.5.0"
3
+ VERSION = "0.5.1"
4
4
  end
5
5
  end
@@ -30,8 +30,15 @@
30
30
  // Export the Underscore object for CommonJS.
31
31
  if (typeof exports !== 'undefined') exports._ = _;
32
32
 
33
+ // Create quick reference variables for speed access to core prototypes.
34
+ var slice = Array.prototype.slice,
35
+ unshift = Array.prototype.unshift,
36
+ toString = Object.prototype.toString,
37
+ hasOwnProperty = Object.prototype.hasOwnProperty,
38
+ propertyIsEnumerable = Object.prototype.propertyIsEnumerable;
39
+
33
40
  // Current version.
34
- _.VERSION = '0.5.0';
41
+ _.VERSION = '0.5.1';
35
42
 
36
43
  /*------------------------ Collection Functions: ---------------------------*/
37
44
 
@@ -42,7 +49,7 @@
42
49
  try {
43
50
  if (obj.forEach) {
44
51
  obj.forEach(iterator, context);
45
- } else if (obj.length) {
52
+ } else if (_.isArray(obj) || _.isArguments(obj)) {
46
53
  for (var i=0, l=obj.length; i<l; i++) iterator.call(context, obj[i], i, obj);
47
54
  } else {
48
55
  var keys = _.keys(obj), l = keys.length;
@@ -57,7 +64,7 @@
57
64
  // Return the results of applying the iterator to each element. Use JavaScript
58
65
  // 1.6's version of map, if possible.
59
66
  _.map = function(obj, iterator, context) {
60
- if (obj && obj.map) return obj.map(iterator, context);
67
+ if (obj && _.isFunction(obj.map)) return obj.map(iterator, context);
61
68
  var results = [];
62
69
  _.each(obj, function(value, index, list) {
63
70
  results.push(iterator.call(context, value, index, list));
@@ -68,7 +75,7 @@
68
75
  // Reduce builds up a single result from a list of values. Also known as
69
76
  // inject, or foldl. Uses JavaScript 1.8's version of reduce, if possible.
70
77
  _.reduce = function(obj, memo, iterator, context) {
71
- if (obj && obj.reduce) return obj.reduce(_.bind(iterator, context), memo);
78
+ if (obj && _.isFunction(obj.reduce)) return obj.reduce(_.bind(iterator, context), memo);
72
79
  _.each(obj, function(value, index, list) {
73
80
  memo = iterator.call(context, memo, value, index, list);
74
81
  });
@@ -78,7 +85,7 @@
78
85
  // The right-associative version of reduce, also known as foldr. Uses
79
86
  // JavaScript 1.8's version of reduceRight, if available.
80
87
  _.reduceRight = function(obj, memo, iterator, context) {
81
- if (obj && obj.reduceRight) return obj.reduceRight(_.bind(iterator, context), memo);
88
+ if (obj && _.isFunction(obj.reduceRight)) return obj.reduceRight(_.bind(iterator, context), memo);
82
89
  var reversed = _.clone(_.toArray(obj)).reverse();
83
90
  _.each(reversed, function(value, index) {
84
91
  memo = iterator.call(context, memo, value, index, obj);
@@ -101,7 +108,7 @@
101
108
  // Return all the elements that pass a truth test. Use JavaScript 1.6's
102
109
  // filter(), if it exists.
103
110
  _.select = function(obj, iterator, context) {
104
- if (obj.filter) return obj.filter(iterator, context);
111
+ if (obj && _.isFunction(obj.filter)) return obj.filter(iterator, context);
105
112
  var results = [];
106
113
  _.each(obj, function(value, index, list) {
107
114
  iterator.call(context, value, index, list) && results.push(value);
@@ -122,7 +129,7 @@
122
129
  // JavaScript 1.6's every(), if it is present.
123
130
  _.all = function(obj, iterator, context) {
124
131
  iterator = iterator || _.identity;
125
- if (obj.every) return obj.every(iterator, context);
132
+ if (obj && _.isFunction(obj.every)) return obj.every(iterator, context);
126
133
  var result = true;
127
134
  _.each(obj, function(value, index, list) {
128
135
  if (!(result = result && iterator.call(context, value, index, list))) _.breakLoop();
@@ -134,7 +141,7 @@
134
141
  // JavaScript 1.6's some(), if it exists.
135
142
  _.any = function(obj, iterator, context) {
136
143
  iterator = iterator || _.identity;
137
- if (obj.some) return obj.some(iterator, context);
144
+ if (obj && _.isFunction(obj.some)) return obj.some(iterator, context);
138
145
  var result = false;
139
146
  _.each(obj, function(value, index, list) {
140
147
  if (result = iterator.call(context, value, index, list)) _.breakLoop();
@@ -215,9 +222,10 @@
215
222
 
216
223
  // Convert anything iterable into a real, live array.
217
224
  _.toArray = function(iterable) {
218
- if (!iterable) return [];
219
- if (iterable.toArray) return iterable.toArray();
220
- if (_.isArray(iterable)) return iterable;
225
+ if (!iterable) return [];
226
+ if (iterable.toArray) return iterable.toArray();
227
+ if (_.isArray(iterable)) return iterable;
228
+ if (_.isArguments(iterable)) return slice.call(iterable);
221
229
  return _.map(iterable, function(val){ return val; });
222
230
  };
223
231
 
@@ -229,16 +237,18 @@
229
237
  /*-------------------------- Array Functions: ------------------------------*/
230
238
 
231
239
  // Get the first element of an array. Passing "n" will return the first N
232
- // values in the array. Aliased as "head".
233
- _.first = function(array, n) {
234
- return n ? Array.prototype.slice.call(array, 0, n) : array[0];
240
+ // values in the array. Aliased as "head". The "guard" check allows it to work
241
+ // with _.map.
242
+ _.first = function(array, n, guard) {
243
+ return n && !guard ? slice.call(array, 0, n) : array[0];
235
244
  };
236
245
 
237
246
  // Returns everything but the first entry of the array. Aliased as "tail".
238
247
  // Especially useful on the arguments object. Passing an "index" will return
239
- // the rest of the values in the array from that index onward.
240
- _.rest = function(array, index) {
241
- return Array.prototype.slice.call(array, _.isUndefined(index) ? 1 : index);
248
+ // the rest of the values in the array from that index onward. The "guard"
249
+ //check allows it to work with _.map.
250
+ _.rest = function(array, index, guard) {
251
+ return slice.call(array, _.isUndefined(index) || guard ? 1 : index);
242
252
  };
243
253
 
244
254
  // Get the last element of an array.
@@ -270,7 +280,7 @@
270
280
  // been sorted, you have the option of using a faster algorithm.
271
281
  _.uniq = function(array, isSorted) {
272
282
  return _.reduce(array, [], function(memo, el, i) {
273
- if (0 == i || (isSorted ? _.last(memo) != el : !_.include(memo, el))) memo.push(el);
283
+ if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo.push(el);
274
284
  return memo;
275
285
  });
276
286
  };
@@ -392,7 +402,7 @@
392
402
  _.keys = function(obj) {
393
403
  if(_.isArray(obj)) return _.range(0, obj.length);
394
404
  var keys = [];
395
- for (var key in obj) if (Object.prototype.hasOwnProperty.call(obj, key)) keys.push(key);
405
+ for (var key in obj) if (hasOwnProperty.call(obj, key)) keys.push(key);
396
406
  return keys;
397
407
  };
398
408
 
@@ -401,6 +411,11 @@
401
411
  return _.map(obj, _.identity);
402
412
  };
403
413
 
414
+ // Return a sorted list of the function names available in Underscore.
415
+ _.functions = function(obj) {
416
+ return _.select(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort();
417
+ };
418
+
404
419
  // Extend a given object with all of the properties in a source object.
405
420
  _.extend = function(destination, source) {
406
421
  for (var property in source) destination[property] = source[property];
@@ -422,6 +437,8 @@
422
437
  if (atype != btype) return false;
423
438
  // Basic equality test (watch out for coercions).
424
439
  if (a == b) return true;
440
+ // One is falsy and the other truthy.
441
+ if ((!a && b) || (a && !b)) return false;
425
442
  // One of them implements an isEqual()?
426
443
  if (a.isEqual) return a.isEqual(b);
427
444
  // Check dates' integer values.
@@ -457,6 +474,11 @@
457
474
  return !!(obj && obj.nodeType == 1);
458
475
  };
459
476
 
477
+ // Is a given variable an arguments object?
478
+ _.isArguments = function(obj) {
479
+ return obj && _.isNumber(obj.length) && !_.isArray(obj) && !propertyIsEnumerable.call(obj, 'length');
480
+ };
481
+
460
482
  // Is the given value NaN -- this one is interesting. NaN != NaN, and
461
483
  // isNaN(undefined) == true, so we make sure it's a number first.
462
484
  _.isNaN = function(obj) {
@@ -473,13 +495,15 @@
473
495
  return typeof obj == 'undefined';
474
496
  };
475
497
 
476
- // Define the isArray, isDate, isFunction, isNumber, isRegExp, and
477
- // isString functions based on their toString identifiers.
478
- _.each(['Array', 'Date', 'Function', 'Number', 'RegExp', 'String'], function(type) {
479
- _['is' + type] = function(obj) {
480
- return Object.prototype.toString.call(obj) == '[object ' + type + ']';
481
- };
482
- });
498
+ // Define the isArray, isDate, isFunction, isNumber, isRegExp, and isString
499
+ // functions based on their toString identifiers.
500
+ var types = ['Array', 'Date', 'Function', 'Number', 'RegExp', 'String'];
501
+ for (var i=0, l=types.length; i<l; i++) {
502
+ (function() {
503
+ var identifier = '[object ' + types[i] + ']';
504
+ _['is' + types[i]] = function(obj) { return toString.call(obj) == identifier; };
505
+ })();
506
+ }
483
507
 
484
508
  /* -------------------------- Utility Functions: -------------------------- */
485
509
 
@@ -508,11 +532,6 @@
508
532
  return prefix ? prefix + id : id;
509
533
  };
510
534
 
511
- // Return a sorted list of the function names available in Underscore.
512
- _.functions = function(obj) {
513
- return _.select(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort();
514
- };
515
-
516
535
  // JavaScript templating a-la ERB, pilfered from John Resig's
517
536
  // "Secrets of the JavaScript Ninja", page 83.
518
537
  _.template = function(str, data) {
@@ -552,24 +571,27 @@
552
571
 
553
572
  // Add all of the Underscore functions to the wrapper object.
554
573
  _.each(_.functions(_), function(name) {
574
+ var method = _[name];
555
575
  wrapper.prototype[name] = function() {
556
- Array.prototype.unshift.call(arguments, this._wrapped);
557
- return result(_[name].apply(_, arguments), this._chain);
576
+ unshift.call(arguments, this._wrapped);
577
+ return result(method.apply(_, arguments), this._chain);
558
578
  };
559
579
  });
560
580
 
561
581
  // Add all mutator Array functions to the wrapper.
562
582
  _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
583
+ var method = Array.prototype[name];
563
584
  wrapper.prototype[name] = function() {
564
- Array.prototype[name].apply(this._wrapped, arguments);
585
+ method.apply(this._wrapped, arguments);
565
586
  return result(this._wrapped, this._chain);
566
587
  };
567
588
  });
568
589
 
569
590
  // Add all accessor Array functions to the wrapper.
570
591
  _.each(['concat', 'join', 'slice'], function(name) {
592
+ var method = Array.prototype[name];
571
593
  wrapper.prototype[name] = function() {
572
- return result(Array.prototype[name].apply(this._wrapped, arguments), this._chain);
594
+ return result(method.apply(this._wrapped, arguments), this._chain);
573
595
  };
574
596
  });
575
597
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: underscore-source
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.5.0
5
+ version: 0.5.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Daniel X. Moore