diff options
| -rw-r--r-- | mrbgems/mruby-enum-ext/mrblib/enum.rb | 47 | ||||
| -rw-r--r-- | mrblib/array.rb | 12 | ||||
| -rw-r--r-- | mrblib/enum.rb | 48 | ||||
| -rw-r--r-- | test/t/enumerable.rb | 16 | ||||
| -rw-r--r-- | test/t/nil.rb | 9 |
5 files changed, 98 insertions, 34 deletions
diff --git a/mrbgems/mruby-enum-ext/mrblib/enum.rb b/mrbgems/mruby-enum-ext/mrblib/enum.rb index f250d39f1..90f321596 100644 --- a/mrbgems/mruby-enum-ext/mrblib/enum.rb +++ b/mrbgems/mruby-enum-ext/mrblib/enum.rb @@ -161,4 +161,51 @@ module Enumerable h end + ## + # call-seq: + # enum.sort_by { |obj| block } -> array + # + # Sorts <i>enum</i> using a set of keys generated by mapping the + # values in <i>enum</i> through the given block. + def sort_by(&block) + ary = [] + orig = [] + self.each_with_index{|e, i| + orig.push(e) + ary.push([block.call(e), i]) + } + if ary.size > 1 + __sort_sub__(ary, ::Array.new(ary.size), 0, 0, ary.size - 1) do |a,b| + a <=> b + end + end + ary.collect{|e,i| orig[i]} + end + + NONE = Object.new + ## + # call-seq: + # enum.first -> obj or nil + # enum.first(n) -> an_array + # + # Returns the first element, or the first +n+ elements, of the enumerable. + # If the enumerable is empty, the first form returns <code>nil</code>, and the + # second form returns an empty array. + def first(n=NONE) + if n == NONE + self.each do |e| + return e + end + return nil + else + a = [] + i = 0 + self.each do |e| + break if n<=i + a.push e + i += 1 + end + a + end + end end diff --git a/mrblib/array.rb b/mrblib/array.rb index aa50ac181..f3c7967cb 100644 --- a/mrblib/array.rb +++ b/mrblib/array.rb @@ -97,6 +97,18 @@ class Array ret end end + + # internal method to convert multi-value to single value + def __svalue + case self.size + when 0 + return nil + when 1 + self[0] + else + self + end + end end ## diff --git a/mrblib/enum.rb b/mrblib/enum.rb index 59d4b9b0f..5a33ed3c5 100644 --- a/mrblib/enum.rb +++ b/mrblib/enum.rb @@ -75,8 +75,8 @@ module Enumerable return to_enum :collect unless block_given? ary = [] - self.each{|val| - ary.push(block.call(val)) + self.each{|*val| + ary.push(block.call(*val)) } ary end @@ -91,9 +91,9 @@ module Enumerable # ISO 15.3.2.2.4 def detect(ifnone=nil, &block) ret = ifnone - self.each{|val| - if block.call(val) - ret = val + self.each{|*val| + if block.call(*val) + ret = val.__svalue break end } @@ -109,8 +109,8 @@ module Enumerable # ISO 15.3.2.2.5 def each_with_index(&block) i = 0 - self.each{|val| - block.call(val, i) + self.each{|*val| + block.call(val.__svalue, i) i += 1 } self @@ -123,8 +123,9 @@ module Enumerable # ISO 15.3.2.2.6 def entries ary = [] - self.each{|val| - ary.push val + self.each{|*val| + # __svalue is an internal method + ary.push val.__svalue } ary end @@ -144,8 +145,8 @@ module Enumerable # ISO 15.3.2.2.8 def find_all(&block) ary = [] - self.each{|val| - ary.push(val) if block.call(val) + self.each{|*val| + ary.push(val.__svalue) if block.call(*val) } ary end @@ -206,7 +207,8 @@ module Enumerable flag = false result = args[0] end - self.each{|val| + self.each{|*val| + val = val.__svalue if flag # push first element as initial flag = false @@ -235,7 +237,8 @@ module Enumerable def max(&block) flag = true # 1st element? result = nil - self.each{|val| + self.each{|*val| + val = val.__svalue if flag # 1st element result = val @@ -261,7 +264,8 @@ module Enumerable def min(&block) flag = true # 1st element? result = nil - self.each{|val| + self.each{|*val| + val = val.__svalue if flag # 1st element result = val @@ -296,11 +300,11 @@ module Enumerable def partition(&block) ary_T = [] ary_F = [] - self.each{|val| - if block.call(val) - ary_T.push(val) + self.each{|*val| + if block.call(*val) + ary_T.push(val.__svalue) else - ary_F.push(val) + ary_F.push(val.__svalue) end } [ary_T, ary_F] @@ -315,8 +319,8 @@ module Enumerable # ISO 15.3.2.2.17 def reject(&block) ary = [] - self.each{|val| - ary.push(val) unless block.call(val) + self.each{|*val| + ary.push(val.__svalue) unless block.call(*val) } ary end @@ -377,8 +381,8 @@ module Enumerable # ISO 15.3.2.2.19 def sort(&block) ary = [] - self.each{|val| ary.push(val)} - unless ary.empty? + self.each{|*val| ary.push(val.__svalue)} + if ary.size > 1 __sort_sub__(ary, ::Array.new(ary.size), 0, 0, ary.size - 1, &block) end ary diff --git a/test/t/enumerable.rb b/test/t/enumerable.rb index 844251b06..4fa615a8f 100644 --- a/test/t/enumerable.rb +++ b/test/t/enumerable.rb @@ -11,17 +11,13 @@ assert('Enumerable#all?', '15.3.2.2.1') do a = [2,4,6] all = a.all? do |e| - if e % 2 == 0 - true - end + e % 2 == 0 end assert_true(all) a = [2,4,7] all = a.all? do |e| - if e % 2 == 0 - true - end + e % 2 == 0 end assert_false(all) end @@ -32,17 +28,13 @@ assert('Enumerable#any?', '15.3.2.2.2') do a = [1,3,6] any = a.any? do |e| - if e % 2 == 0 - true - end + e % 2 == 0 end assert_true(any) a = [1,3,5] any = a.any? do |e| - if e % 2 == 0 - true - end + e % 2 == 0 end assert_false(any) end diff --git a/test/t/nil.rb b/test/t/nil.rb index 443178c81..971ce2e8e 100644 --- a/test/t/nil.rb +++ b/test/t/nil.rb @@ -5,6 +5,15 @@ assert('NilClass', '15.2.4') do assert_equal Class, NilClass.class end +assert('NilClass', '15.2.4.1') do + assert_equal NilClass, nil.class + assert_false NilClass.method_defined? :new +end + +assert('NilClass superclass', '15.2.4.2') do + assert_equal Object, NilClass.superclass +end + assert('NilClass#&', '15.2.4.3.1') do assert_false nil.&(true) assert_false nil.&(nil) |
