From 0ad9fd0af835ffe5415392ebfcb04eca5495ddc5 Mon Sep 17 00:00:00 2001 From: Eugene Fedin Date: Sat, 12 Feb 2011 05:44:48 +0300 Subject: [PATCH] Using local function each() Using local function each() to prevent consequenses of Array.prototype.each() replacing. It happens when prototype.js is using with mootools.js for example. Basic situation when there is an error: This problem arise from Array.prototype.each = Array.prototype.forEach; in mootools.js and from using this property in Enumerable: local one handles exceptions, native does not do it. Thus all(), every(), any(), some(), detect(), include() properties are broken when they throw exception. This patch solve the problem by using local each(). --- src/prototype/lang/enumerable.js | 28 ++++++++++++++-------------- test/unit/enumerable_test.js | 29 +++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/prototype/lang/enumerable.js b/src/prototype/lang/enumerable.js index 4d17e6219..63a4177e1 100644 --- a/src/prototype/lang/enumerable.js +++ b/src/prototype/lang/enumerable.js @@ -5,7 +5,7 @@ * objects that act as collections of values. It is a cornerstone of * Prototype. * - * [[Enumerable]] is a _mixin_: a set of methods intended not for standaone + * [[Enumerable]] is a _mixin_: a set of methods intended not for standalone * use, but for incorporation into other objects. * * Prototype mixes [[Enumerable]] into several classes. The most visible cases @@ -185,7 +185,7 @@ var Enumerable = (function() { function all(iterator, context) { iterator = iterator || Prototype.K; var result = true; - this.each(function(value, index) { + each.call(this, function(value, index) { result = result && !!iterator.call(context, value, index); if (!result) throw $break; }); @@ -217,7 +217,7 @@ var Enumerable = (function() { function any(iterator, context) { iterator = iterator || Prototype.K; var result = false; - this.each(function(value, index) { + each.call(this, function(value, index) { if (result = !!iterator.call(context, value, index)) throw $break; }); @@ -250,7 +250,7 @@ var Enumerable = (function() { function collect(iterator, context) { iterator = iterator || Prototype.K; var results = []; - this.each(function(value, index) { + each.call(this, function(value, index) { results.push(iterator.call(context, value, index)); }); return results; @@ -273,7 +273,7 @@ var Enumerable = (function() { **/ function detect(iterator, context) { var result; - this.each(function(value, index) { + each.call(this, function(value, index) { if (iterator.call(context, value, index)) { result = value; throw $break; @@ -298,7 +298,7 @@ var Enumerable = (function() { **/ function findAll(iterator, context) { var results = []; - this.each(function(value, index) { + each.call(this, function(value, index) { if (iterator.call(context, value, index)) results.push(value); }); @@ -343,7 +343,7 @@ var Enumerable = (function() { if (Object.isString(filter)) filter = new RegExp(RegExp.escape(filter)); - this.each(function(value, index) { + each.call(this, function(value, index) { if (filter.match(value)) results.push(iterator.call(context, value, index)); }); @@ -374,7 +374,7 @@ var Enumerable = (function() { if (this.indexOf(object) != -1) return true; var found = false; - this.each(function(value) { + each.call(this, function(value) { if (value == object) { found = true; throw $break; @@ -448,7 +448,7 @@ var Enumerable = (function() { * // -> 'ace' **/ function inject(memo, iterator, context) { - this.each(function(value, index) { + each.call(this, function(value, index) { memo = iterator.call(context, memo, value, index); }); return memo; @@ -513,7 +513,7 @@ var Enumerable = (function() { function max(iterator, context) { iterator = iterator || Prototype.K; var result; - this.each(function(value, index) { + each.call(this, function(value, index) { value = iterator.call(context, value, index); if (result == null || value >= result) result = value; @@ -553,7 +553,7 @@ var Enumerable = (function() { function min(iterator, context) { iterator = iterator || Prototype.K; var result; - this.each(function(value, index) { + each.call(this, function(value, index) { value = iterator.call(context, value, index); if (result == null || value < result) result = value; @@ -591,7 +591,7 @@ var Enumerable = (function() { function partition(iterator, context) { iterator = iterator || Prototype.K; var trues = [], falses = []; - this.each(function(value, index) { + each.call(this, function(value, index) { (iterator.call(context, value, index) ? trues : falses).push(value); }); @@ -613,7 +613,7 @@ var Enumerable = (function() { **/ function pluck(property) { var results = []; - this.each(function(value) { + each.call(this, function(value) { results.push(value[property]); }); return results; @@ -635,7 +635,7 @@ var Enumerable = (function() { **/ function reject(iterator, context) { var results = []; - this.each(function(value, index) { + each.call(this, function(value, index) { if (!iterator.call(context, value, index)) results.push(value); }); diff --git a/test/unit/enumerable_test.js b/test/unit/enumerable_test.js index 3e0d00bd8..2489202dc 100644 --- a/test/unit/enumerable_test.js +++ b/test/unit/enumerable_test.js @@ -1,5 +1,5 @@ function prime(value) { - for (var i = 2; i < value; i++) + for (var i = 2; i <= value/2; i++) if (value % i == 0) return false; return true; } @@ -267,5 +267,30 @@ new Test.Unit.Runner({ this.assertEqual(4, Fixtures.Nicknames.size()); this.assertEqual(26, Fixtures.Primes.size()); this.assertEqual(0, [].size()); + }, + + testAfterEachReplacing: function() { + Array.prototype.each = Array.prototype.forEach; + var basicArray = Fixtures.Basic; + var check = function(value) { + return value === basicArray[1]; + }; + this.assert(!basicArray.all(check)); + this.assert(!basicArray.every(check)); + this.assert(basicArray.any(check)); + this.assert(basicArray.some(check)); + this.assert(basicArray.some(check)); + this.assertEnumEqual([false, true, false], basicArray.collect(check)); + this.assertEnumEqual([false, true, false], basicArray.map(check)); + this.assertEqual(2, basicArray.detect(check)); + this.assertEnumEqual([2], basicArray.findAll(check)); + this.assertEnumEqual([2], basicArray.select(check)); + this.assertEnumEqual([2], basicArray.filter(check)); + this.assertEnumEqual([2], basicArray.grep(/2/)); + this.assert(basicArray.include(2)); + this.assert(basicArray.member(2)); + this.assertEqual(1, basicArray.min()); + this.assertEqual(3, basicArray.max()); + this.assertEnumEqual([1, 3], basicArray.reject(check)); } -}); \ No newline at end of file +});