corelib/enumerable.rb in opal-0.4.4 vs corelib/enumerable.rb in opal-0.5.0

- old
+ new

@@ -1,79 +1,69 @@ module Enumerable def all?(&block) %x{ - var result = true, proc; + var result = true; if (block !== nil) { - proc = function(obj) { - var value; - var args = $slice.call(arguments); + self.$each._p = function() { + var value = $opal.$yieldX(block, arguments); - if ((value = block.apply(#{self}, args)) === $breaker) { - return $breaker.$v; + if (value === $breaker) { + result = $breaker.$v; + return $breaker; } - if (value === false || value === nil) { + if (#{Opal.falsy?(`value`)}) { result = false; - $breaker.$v = nil; - return $breaker; } } } else { - proc = function(obj) { - if ((obj === false || obj === nil) && arguments.length < 2) { - result = false; - $breaker.$v = nil; - + self.$each._p = function(obj) { + if (arguments.length == 1 && #{Opal.falsy?(`obj`)}) { + result = false; return $breaker; } } } - #{self}.$each._p = proc; - #{self}.$each(); + self.$each(); return result; } end def any?(&block) %x{ - var result = false, proc; + var result = false; if (block !== nil) { - proc = function(obj) { - var value; - var args = $slice.call(arguments); + self.$each._p = function() { + var value = $opal.$yieldX(block, arguments); - if ((value = block.apply(#{self}, args)) === $breaker) { - return $breaker.$v; + if (value === $breaker) { + result = $breaker.$v; + return $breaker; } - if (value !== false && value !== nil) { - result = true; - $breaker.$v = nil; - + if (#{Opal.truthy?(`value`)}) { + result = true; return $breaker; } - } + }; } else { - proc = function(obj) { - if ((obj !== false && obj !== nil) || arguments.length >= 2) { - result = true; - $breaker.$v = nil; - + self.$each._p = function(obj) { + if (arguments.length != 1 || #{Opal.truthy?(`obj`)}) { + result = true; return $breaker; } } } - #{self}.$each._p = proc; - #{self}.$each(); + self.$each(); return result; } end @@ -81,46 +71,22 @@ return enum_for :collect unless block_given? %x{ var result = []; - var proc = function() { - var value, args = $slice.call(arguments); + self.$each._p = function() { + var value = $opal.$yieldX(block, arguments); - if ((value = block.apply(null, arguments)) === $breaker) { - return $breaker.$v; - } - - result.push(value); - }; - - #{self}.$each._p = proc; - #{self}.$each(); - - return result; - } - end - - def reduce(object = undefined, &block) - %x{ - var result = #{object} == undefined ? 0 : #{object}; - - var proc = function() { - var obj = $slice.call(arguments), value; - - if ((value = block.apply(nil, [result].concat(obj))) === $breaker) { + if (value === $breaker) { result = $breaker.$v; - $breaker.$v = nil; - return $breaker; } - result = value; + result.push(value); }; - #{self}.$each._p = proc; - #{self}.$each(); + self.$each(); return result; } end @@ -128,543 +94,809 @@ %x{ var result = 0; if (object != null) { block = function() { - var param = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); - - return #{ `param` == `object` }; + return #{Opal.destructure(`arguments`) == `object`}; }; } else if (block === nil) { block = function() { return true; }; } - var proc = function() { - var value, param = $slice.call(arguments); + self.$each._p = function() { + var value = $opal.$yieldX(block, arguments); - if ((value = block.apply(null, param)) === $breaker) { - return $breaker.$v; + if (value === $breaker) { + result = $breaker.$v; + return $breaker; } - if (value !== false && value !== nil) { + if (#{Opal.truthy?(`value`)}) { result++; } } - #{self}.$each._p = proc; - #{self}.$each(); + self.$each(); return result; } end def detect(ifnone = undefined, &block) + return enum_for :detect, ifnone unless block_given? + %x{ - var result = nil; + var result = undefined; - #{self}.$each._p = function() { - var value; - var param = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); + self.$each._p = function() { + var params = #{Opal.destructure(`arguments`)}, + value = $opal.$yield1(block, params); - if ((value = block(param)) === $breaker) { - return $breaker.$v; + if (value === $breaker) { + result = $breaker.$v; + return $breaker; } - if (value !== false && value !== nil) { - result = param; - $breaker.$v = nil; - + if (#{Opal.truthy?(`value`)}) { + result = params; return $breaker; } }; - #{self}.$each(); + self.$each(); - if (result !== nil) { - return result; + if (result === undefined && ifnone !== undefined) { + if (typeof(ifnone) === 'function') { + result = ifnone(); + } + else { + result = ifnone; + } } - if (typeof(ifnone) === 'function') { - return #{ifnone.call}; - } - - return ifnone == null ? nil : ifnone; + return result === undefined ? nil : result; } end def drop(number) + number = Opal.coerce_to number, Integer, :to_int + + if `number < 0` + raise ArgumentError, "attempt to drop negative size" + end + %x{ var result = [], current = 0; - #{self}.$each._p = function() { + self.$each._p = function() { if (number < current) { - result.push(e); + result.push(#{Opal.destructure(`arguments`)}); } current++; }; - #{self}.$each() + self.$each() return result; } end def drop_while(&block) + return enum_for :drop_while unless block_given? + %x{ var result = []; - #{self}.$each._p = function() { - var value; - var param = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}, + value = $opal.$yield1(block, param); - if ((value = block(param)) === $breaker) { + if (value === $breaker) { + result = $breaker.$v; return $breaker; } - if (value === false || value === nil) { - result.push(param); - return value; + if (#{Opal.truthy?(`value`)}) { + return; } - return $breaker; + result.push(param); }; - #{self}.$each(); + self.$each(); return result; } end def each_slice(n, &block) + n = Opal.coerce_to n, Integer, :to_int + + return enum_for :each_slice, n unless block_given? + %x{ - var all = []; + var result, + slice = [] - #{self}.$each._p = function() { - var param = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}; - all.push(param); + slice.push(param); - if (all.length == n) { - block(all.slice(0)); - all = []; + if (slice.length === n) { + if (block(slice) === $breaker) { + result = $breaker.$v; + return $breaker; + } + + slice = []; } }; - #{self}.$each(); + self.$each(); - // our "last" group, if smaller than n then wont have been yielded - if (all.length > 0) { - block(all.slice(0)); + if (result !== undefined) { + return result; } - return nil; + // our "last" group, if smaller than n then won't have been yielded + if (slice.length > 0) { + if (block(slice) === $breaker) { + return $breaker.$v; + } + } } + + nil end def each_with_index(&block) + return enum_for :each_with_index unless block_given? + %x{ - var index = 0; + var result, + index = 0; - #{self}.$each._p = function() { - var value; - var param = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}, + value = block(param, index); - if ((value = block(param, index)) === $breaker) { - return $breaker.$v; + if (value === $breaker) { + result = $breaker.$v; + return $breaker; } index++; }; - #{self}.$each(); - return nil; + self.$each(); + + if (result !== undefined) { + return result; + } } + + nil end def each_with_object(object, &block) + return enum_for :each_with_object, object unless block_given? + %x{ - #{self}.$each._p = function() { - var value; - var param = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); + var result; - if ((value = block(param, object)) === $breaker) { - return $breaker.$v; + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}, + value = block(param, object); + + if (value === $breaker) { + result = $breaker.$v; + return $breaker; } }; - #{self}.$each(); + self.$each(); - return object; + if (result !== undefined) { + return result; + } } + + object end def entries %x{ var result = []; - #{self}.$each._p = function() { - if (arguments.length == 1) { - result.push(arguments[0]); - } - else { - result.push($slice.call(arguments)); - } + self.$each._p = function() { + result.push(#{Opal.destructure(`arguments`)}); }; - #{self}.$each(); + self.$each(); return result; } end alias find detect def find_all(&block) + return enum_for :find_all unless block_given? + %x{ var result = []; - #{self}.$each._p = function() { - var value; - var param = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}, + value = $opal.$yield1(block, param); - if ((value = block(param)) === $breaker) { - return $breaker.$v; + if (value === $breaker) { + result = $breaker.$v; + return $breaker; } - if (value !== false && value !== nil) { + if (#{Opal.truthy?(`value`)}) { result.push(param); } }; - #{self}.$each(); + self.$each(); return result; } end def find_index(object = undefined, &block) + return enum_for :find_index if `object === undefined && block === nil` + %x{ - var proc, result = nil, index = 0; + var result = nil, + index = 0; if (object != null) { - proc = function() { - var param = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}; - if (#{ `param` == `object` }) { + if (#{`param` == `object`}) { result = index; return $breaker; } index += 1; }; } - else { - proc = function() { - var value; - var param = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); + else if (block !== nil) { + self.$each._p = function() { + var value = $opal.$yieldX(block, arguments); - if ((value = block(param)) === $breaker) { - return $breaker.$v; + if (value === $breaker) { + result = $breaker.$v; + return $breaker; } - if (value !== false && value !== nil) { - result = index; - $breaker.$v = index; - + if (#{Opal.truthy?(`value`)}) { + result = index; return $breaker; } index += 1; }; } - #{self}.$each._p = proc; - #{self}.$each(); + self.$each(); return result; } end def first(number = undefined) %x{ - var result = [], - current = 0, - proc; - if (number == null) { - result = nil; - proc = function() { - result = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); + var result = nil; + self.$each._p = function() { + result = #{Opal.destructure(`arguments`)}; return $breaker; }; } else { - proc = function() { + var current = 0, + result = [], + number = #{Opal.coerce_to number, Integer, :to_int}; + + self.$each._p = function() { if (number <= current) { return $breaker; } - var param = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); + result.push(#{Opal.destructure(`arguments`)}); - result.push(param); - current++; }; } - #{self}.$each._p = proc; - #{self}.$each(); + self.$each(); return result; } end def grep(pattern, &block) %x{ - var result = [], - proc; + var result = []; if (block !== nil) { - proc = function() { - var param = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}, + value = #{pattern === `param`}; - var value = #{pattern === `param`}; + if (#{Opal.truthy?(`value`)}) { + value = $opal.$yield1(block, param); - if (value !== false && value !== nil) { - if ((value = block(param)) === $breaker) { - return $breaker.$v; + if (value === $breaker) { + result = $breaker.$v; + return $breaker; } result.push(value); } }; } else { - proc = function() { - var param = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}, + value = #{pattern === `param`}; - var value = #{pattern === `param`}; - - if (value !== false && value !== nil) { + if (#{Opal.truthy?(`value`)}) { result.push(param); } }; } - #{self}.$each._p = proc; - #{self}.$each(); + self.$each(); return result; } end def group_by(&block) + return enum_for :group_by unless block_given? + hash = Hash.new { |h, k| h[k] = [] } - each do |el| - hash[block.call(el)] << el - end + %x{ + var result; + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}, + value = $opal.$yield1(block, param); + + if (value === $breaker) { + result = $breaker.$v; + return $breaker; + } + + #{hash[`value`] << `param`}; + } + + self.$each(); + + if (result !== undefined) { + return result; + } + } + hash end - alias map collect + def include?(obj) + any? { |v| v == obj } + end - def max(&block) + def inject(object = undefined, sym = undefined, &block) %x{ - var proc, result; - var arg_error = false; + var result = object; if (block !== nil) { - proc = function() { - var param = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); + self.$each._p = function() { + var value = #{Opal.destructure(`arguments`)}; - if (result == undefined) { - result = param; + if (result === undefined) { + result = value; + return; } - else if ((value = block(param, result)) === $breaker) { - result = $breaker.$v; + value = $opal.$yieldX(block, [result, value]); + + if (value === $breaker) { + result = $breaker.$v; return $breaker; } - else { - if (value > 0) { - result = param; - } - $breaker.$v = nil; + result = value; + }; + } + else { + if (sym === undefined) { + if (!#{Symbol === object}) { + #{raise TypeError, "#{object.inspect} is not a Symbol"}; } + + sym = object; + result = undefined; } + + self.$each._p = function() { + var value = #{Opal.destructure(`arguments`)}; + + if (result === undefined) { + result = value; + return; + } + + result = #{`result`.__send__ sym, `value`}; + }; } - else { - proc = function() { - var param = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); - var modules = param.$class().$included_modules; + self.$each(); - if (modules == undefined || modules.length == 0 || modules.indexOf(Opal.Comparable) == -1) { - arg_error = true; + return result; + } + end + alias map collect + + def max(&block) + %x{ + var result; + + if (block !== nil) { + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}; + + if (result === undefined) { + result = param; + return; + } + + var value = block(param, result); + + if (value === $breaker) { + result = $breaker.$v; return $breaker; } - if (result == undefined || #{`param` > `result`}) { + if (value > 0) { result = param; } - } + }; } + else { + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}; - #{self}.$each._p = proc; - #{self}.$each(); + if (result === undefined) { + result = param; + return; + } - if (arg_error) { - #{raise ArgumentError, "Array#max"}; + if (#{`param` <=> `result`} > 0) { + result = param; + } + }; } - return (result == undefined ? nil : result); + self.$each(); + + return result === undefined ? nil : result; } end + def max_by(&block) + return enum_for :max_by unless block + + %x{ + var result, + by; + + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}, + value = $opal.$yield1(block, param); + + if (result === undefined) { + result = param; + by = value; + return; + } + + if (value === $breaker) { + result = $breaker.$v; + return $breaker; + } + + if (#{`value` <=> `by`} > 0) { + result = param + by = value; + } + }; + + self.$each(); + + return result === undefined ? nil : result; + } + end + + alias member? include? + def min(&block) %x{ - var proc, - result, - arg_error = false; + var result; if (block !== nil) { - proc = function() { - var param = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}; - if (result == undefined) { + if (result === undefined) { result = param; + return; } - else if ((value = block(param, result)) === $breaker) { - result = $breaker.$v; + var value = block(param, result); + + if (value === $breaker) { + result = $breaker.$v; return $breaker; } - else { - if (value < 0) { - result = param; - } - $breaker.$v = nil; + if (value < 0) { + result = param; } - } + }; } else { - proc = function(obj) { - var param = arguments.length == 1 ? - arguments[0] : $slice.call(arguments); + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}; - var modules = param.$class().$included_modules; - - if (modules == undefined || modules.length == 0 || modules.indexOf(Opal.Comparable) == -1) { - arg_error = true; - - return $breaker; + if (result === undefined) { + result = param; + return; } - if (result == undefined || #{`param` < `result`}) { + if (#{`param` <=> `result`} < 0) { result = param; } - } + }; } - #{self}.$each._p = proc; - #{self}.$each(); + self.$each(); - if (arg_error) { - #{raise ArgumentError, "Array#min"}; - } + return result === undefined ? nil : result; + } + end - return result == undefined ? nil : result; + def min_by(&block) + return enum_for :min_by unless block + + %x{ + var result, + by; + + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}, + value = $opal.$yield1(block, param); + + if (result === undefined) { + result = param; + by = value; + return; + } + + if (value === $breaker) { + result = $breaker.$v; + return $breaker; + } + + if (#{`value` <=> `by`} < 0) { + result = param + by = value; + } + }; + + self.$each(); + + return result === undefined ? nil : result; } end def none?(&block) %x{ - var result = true, - proc; + var result = true; if (block !== nil) { - proc = function(obj) { - var value, - args = $slice.call(arguments); + self.$each._p = function() { + var value = $opal.$yieldX(block, arguments); - if ((value = block.apply(#{self}, args)) === $breaker) { - return $breaker.$v; + if (value === $breaker) { + result = $breaker.$v; + return $breaker; } - if (value !== false && value !== nil) { - result = false; - $breaker.$v = nil; - + if (#{Opal.truthy?(`value`)}) { + result = false; return $breaker; } } } else { - proc = function(obj) { - if (arguments.length == 1 && (obj !== false && obj !== nil)) { - result = false; - $breaker.$v = nil; + self.$each._p = function() { + var value = #{Opal.destructure(`arguments`)}; + if (#{Opal.truthy?(`value`)}) { + result = false; return $breaker; } - else { - for (var i = 0, length = arguments.length; i < length; i++) { - if (arguments[i] !== false && arguments[i] !== nil) { - result = false; - $breaker.$v = nil; + }; + } - return $breaker; - } + self.$each(); + + return result; + } + end + + def one?(&block) + %x{ + var result = false; + + if (block !== nil) { + self.$each._p = function() { + var value = $opal.$yieldX(block, arguments); + + if (value === $breaker) { + result = $breaker.$v; + return $breaker; + } + + if (#{Opal.truthy?(`value`)}) { + if (result === true) { + result = false; + return $breaker; } + + result = true; } - }; + } } + else { + self.$each._p = function() { + var value = #{Opal.destructure(`arguments`)}; - #{self}.$each._p = proc; - #{self}.$each(); + if (#{Opal.truthy?(`value`)}) { + if (result === true) { + result = false; + return $breaker; + } + result = true; + } + } + } + + self.$each(); + return result; } end + def slice_before(pattern = undefined, &block) + if `pattern === undefined && block === nil || arguments.length > 1` + raise ArgumentError, "wrong number of arguments (#{`arguments.length`} for 1)" + end + + Enumerator.new {|e| + %x{ + var slice = []; + + if (block !== nil) { + if (pattern === undefined) { + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}, + value = $opal.$yield1(block, param); + + if (#{Opal.truthy?(`value`)} && slice.length > 0) { + #{e << `slice`}; + slice = []; + } + + slice.push(param); + }; + } + else { + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}, + value = block(param, #{pattern.dup}); + + if (#{Opal.truthy?(`value`)} && slice.length > 0) { + #{e << `slice`}; + slice = []; + } + + slice.push(param); + }; + } + } + else { + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}, + value = #{pattern === `param`}; + + if (#{Opal.truthy?(`value`)} && slice.length > 0) { + #{e << `slice`}; + slice = []; + } + + slice.push(param); + }; + } + + self.$each(); + + if (slice.length > 0) { + #{e << `slice`}; + } + } + } + end + def sort_by(&block) - map { |*f| - # FIXME: this should probably belongs to somewhere more - f = `#{f}.length === 1 ? #{f}[0] : #{f}` - `[#{block.call(f)}, #{f}]` - }.sort.map { |f| `#{f}[1]` } + return enum_for :sort_by unless block_given? + + map { + arg = Opal.destructure(`arguments`) + + [block.call(arg), arg] + }.sort { |a, b| a[0] <=> b[0] }.map { |arg| `arg[1]` } end alias select find_all - alias take first + alias reduce inject - alias to_a entries + def take(num) + first(num) + end - alias inject reduce + def take_while(&block) + return enum_for :take_while unless block + + %x{ + var result = []; + + self.$each._p = function() { + var param = #{Opal.destructure(`arguments`)}, + value = $opal.$yield1(block, param); + + if (value === $breaker) { + result = $breaker.$v; + return $breaker; + } + + if (#{Opal.falsy?(`value`)}) { + return $breaker; + } + + result.push(param); + }; + + self.$each(); + + return result; + } + end + + alias to_a entries end