summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mrbgems/mruby-hash-ext/mrblib/hash.rb2
-rw-r--r--mrbgems/mruby-hash-ext/test/hash.rb4
-rw-r--r--mrblib/hash.rb2
-rw-r--r--src/vm.c15
-rw-r--r--test/t/hash.rb4
-rw-r--r--test/t/proc.rb23
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
diff --git a/src/vm.c b/src/vm.c
index 620f9e977..2c6fbf087 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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(&regs[1], argv, argc-m2); /* m1 + o */
+ value_move(&regs[1], argv, argc-mlen); /* m1 + o */
}
- if (m2) {
- int mlen = m2;
- if (argc-m2 <= m1) {
- mlen = argc - m1;
- }
+ if (mlen) {
value_move(&regs[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