diff options
| -rw-r--r-- | mrbgems/mruby-hash-ext/mrblib/hash.rb | 2 | ||||
| -rw-r--r-- | mrbgems/mruby-hash-ext/test/hash.rb | 4 | ||||
| -rw-r--r-- | mrblib/hash.rb | 2 | ||||
| -rw-r--r-- | src/vm.c | 15 | ||||
| -rw-r--r-- | test/t/hash.rb | 4 | ||||
| -rw-r--r-- | test/t/proc.rb | 23 |
6 files changed, 42 insertions, 8 deletions
diff --git a/mrbgems/mruby-hash-ext/mrblib/hash.rb b/mrbgems/mruby-hash-ext/mrblib/hash.rb index 259b0fa12..71a518238 100644 --- a/mrbgems/mruby-hash-ext/mrblib/hash.rb +++ b/mrbgems/mruby-hash-ext/mrblib/hash.rb @@ -22,7 +22,7 @@ class Hash # def merge!(other, &block) - raise "can't convert argument into Hash" unless other.respond_to?(:to_hash) + raise TypeError, "can't convert argument into Hash" unless other.respond_to?(:to_hash) if block other.each_key{|k| self[k] = (self.has_key?(k))? block.call(k, self[k], other[k]): other[k] diff --git a/mrbgems/mruby-hash-ext/test/hash.rb b/mrbgems/mruby-hash-ext/test/hash.rb index b9992fa96..62cfc8856 100644 --- a/mrbgems/mruby-hash-ext/test/hash.rb +++ b/mrbgems/mruby-hash-ext/test/hash.rb @@ -16,6 +16,10 @@ assert('Hash#merge!') do 'xyz_key' => 'xyz_value' }, result_1) assert_equal({'abc_key' => 'abc_value', 'cba_key' => 'cba_value', 'xyz_key' => 'xyz_value' }, result_2) + + assert_raise(TypeError) do + { 'abc_key' => 'abc_value' }.merge! "a" + end end assert('Hash#values_at') do diff --git a/mrblib/hash.rb b/mrblib/hash.rb index 5828a13eb..315a0c86e 100644 --- a/mrblib/hash.rb +++ b/mrblib/hash.rb @@ -179,7 +179,7 @@ class Hash # ISO 15.2.13.4.22 def merge(other, &block) h = {} - raise "can't convert argument into Hash" unless other.respond_to?(:to_hash) + raise TypeError, "can't convert argument into Hash" unless other.respond_to?(:to_hash) other = other.to_hash self.each_key{|k| h[k] = self[k]} if block @@ -1306,16 +1306,19 @@ RETRY_TRY_BLOCK: } mrb->c->ci->argc = len; if (argc < len) { + int mlen = m2; + if (argc < m1+m2) { + if (m1 < argc) + mlen = argc - m1; + else + mlen = 0; + } regs[len+1] = *blk; /* move block */ SET_NIL_VALUE(regs[argc+1]); if (argv0 != argv) { - value_move(®s[1], argv, argc-m2); /* m1 + o */ + value_move(®s[1], argv, argc-mlen); /* m1 + o */ } - if (m2) { - int mlen = m2; - if (argc-m2 <= m1) { - mlen = argc - m1; - } + if (mlen) { value_move(®s[len-m2+1], &argv[argc-mlen], mlen); } if (r) { diff --git a/test/t/hash.rb b/test/t/hash.rb index 2ddd33316..0e035a3a7 100644 --- a/test/t/hash.rb +++ b/test/t/hash.rb @@ -223,6 +223,10 @@ assert('Hash#merge', '15.2.13.4.22') do 'xyz_key' => 'xyz_value' }, result_1) assert_equal({'abc_key' => 'abc_value', 'cba_key' => 'cba_value', 'xyz_key' => 'xyz_value' }, result_2) + + assert_raise(TypeError) do + { 'abc_key' => 'abc_value' }.merge "a" + end end assert('Hash#replace', '15.2.13.4.23') do diff --git a/test/t/proc.rb b/test/t/proc.rb index 49d4d92f8..33c3a0ef2 100644 --- a/test/t/proc.rb +++ b/test/t/proc.rb @@ -72,6 +72,29 @@ assert('Proc#call proc args pos block') do assert_equal [1, 2, Proc, :x], (pr.call(1, 2, 3, 4){|x| x}) end +assert('Proc#call proc args pos rest post') do + pr = Proc.new {|a,b,*c,d,e| + [a,b,c,d,e] + } + assert_equal [nil, nil, [], nil, nil], pr.call() + assert_equal [1, nil, [], nil, nil], pr.call(1) + assert_equal [1, 2, [], nil, nil], pr.call(1,2) + assert_equal [1, 2, [], 3, nil], pr.call(1,2,3) + assert_equal [1, 2, [], 3, 4], pr.call(1,2,3,4) + assert_equal [1, 2, [3], 4, 5], pr.call(1,2,3,4,5) + assert_equal [1, 2, [3, 4], 5, 6], pr.call(1,2,3,4,5,6) + assert_equal [1, 2, [3, 4, 5], 6,7], pr.call(1,2,3,4,5,6,7) + + assert_equal [nil, nil, [], nil, nil], pr.call([]) + assert_equal [1, nil, [], nil, nil], pr.call([1]) + assert_equal [1, 2, [], nil, nil], pr.call([1,2]) + assert_equal [1, 2, [], 3, nil], pr.call([1,2,3]) + assert_equal [1, 2, [], 3, 4], pr.call([1,2,3,4]) + assert_equal [1, 2, [3], 4, 5], pr.call([1,2,3,4,5]) + assert_equal [1, 2, [3, 4], 5, 6], pr.call([1,2,3,4,5,6]) + assert_equal [1, 2, [3, 4, 5], 6,7], pr.call([1,2,3,4,5,6,7]) +end + assert('Proc#return_does_not_break_self') do class TestClass attr_accessor :block |
