Unverified Commit b631c226 authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto Committed by GitHub

Merge pull request #5585 from dearblue/args-pass

Fixed some methods where keyword arguments are not passed
parents d6e1114f 16e38886
class Method class Method
def to_proc def to_proc
m = self m = self
lambda { |*args, &b| lambda { |*args, **opts, &b|
m.call(*args, &b) m.call(*args, **opts, &b)
} }
end end
def <<(other) def <<(other)
->(*args, &block) { call(other.call(*args, &block)) } ->(*args, **opts, &block) { call(other.call(*args, **opts, &block)) }
end end
def >>(other) def >>(other)
->(*args, &block) { other.call(call(*args, &block)) } ->(*args, **opts, &block) { other.call(call(*args, **opts, &block)) }
end end
end end
...@@ -20,15 +20,19 @@ args_shift(mrb_state *mrb) ...@@ -20,15 +20,19 @@ args_shift(mrb_state *mrb)
mrb_value *argv = ci->stack + 1; mrb_value *argv = ci->stack + 1;
if (ci->n < 15) { if (ci->n < 15) {
if (ci->n == 0) { goto argerr; }
mrb_assert(ci->nk == 0 || ci->nk == 15);
mrb_value obj = argv[0]; mrb_value obj = argv[0];
memmove(argv, argv + 1, (ci->n + 1 /* block */ - 1 /* first value */) * sizeof(mrb_value)); int count = ci->n + (ci->nk == 0 ? 0 : 1) + 1 /* block */ - 1 /* first value */;
memmove(argv, argv + 1, count * sizeof(mrb_value));
ci->n--; ci->n--;
return obj; return obj;
} }
else if (ci->n == 15 && RARRAY_LEN(*argv) > 0) { else if (RARRAY_LEN(*argv) > 0) {
return mrb_ary_shift(mrb, *argv); return mrb_ary_shift(mrb, *argv);
} }
else { else {
argerr:
mrb_argnum_error(mrb, 0, 1, -1); mrb_argnum_error(mrb, 0, 1, -1);
return mrb_undef_value(); /* not reached */ return mrb_undef_value(); /* not reached */
} }
...@@ -41,9 +45,12 @@ args_unshift(mrb_state *mrb, mrb_value obj) ...@@ -41,9 +45,12 @@ args_unshift(mrb_state *mrb, mrb_value obj)
mrb_value *argv = ci->stack + 1; mrb_value *argv = ci->stack + 1;
if (ci->n < 15) { if (ci->n < 15) {
mrb_value block = argv[ci->n]; mrb_assert(ci->nk == 0 || ci->nk == 15);
argv[0] = mrb_ary_new_from_values(mrb, ci->n, argv); argv[0] = mrb_ary_new_from_values(mrb, ci->n, argv);
argv[1] = block; argv[1] = argv[ci->n]; // keyword or block
if (ci->nk == 15) {
argv[2] = argv[ci->n + 1]; // block
}
ci->n = 15; ci->n = 15;
} }
......
...@@ -208,6 +208,16 @@ assert 'Method#to_proc' do ...@@ -208,6 +208,16 @@ assert 'Method#to_proc' do
yield 39 yield 39
end end
assert_equal 42, o.bar(&3.method(:+)) assert_equal 42, o.bar(&3.method(:+))
def o.baz(x, y, z, *w, u:, v:, **opts, &blk)
{ x:, y:, z:, w:, u:, v:, opts:, blk: }
end
blk = -> { }
values = { x: 1, y: 2, z: 3, w: [4, 5, 6], u: 7, v: 8, opts: { s: 9, t: 10 }, blk: blk }
assert_equal values, o.method(:baz).to_proc.call(1, 2, 3, 4, 5, 6, u: 7, v: 8, s: 9, t: 10, &blk)
assert_equal values, o.method(:baz).to_proc.call(1, 2, 3, 4, 5, 6, **{ u: 7, v: 8, s: 9, t: 10 }, &blk)
assert_equal values, o.method(:baz).to_proc.call(*[1, 2, 3, 4, 5, 6], u: 7, v: 8, s: 9, t: 10, &blk)
assert_equal values, o.method(:baz).to_proc.call(*[1, 2, 3, 4, 5, 6], **{ u: 7, v: 8, s: 9, t: 10 }, &blk)
end end
assert 'to_s' do assert 'to_s' do
...@@ -449,4 +459,17 @@ assert 'UnboundMethod#bind_call' do ...@@ -449,4 +459,17 @@ assert 'UnboundMethod#bind_call' do
assert_equal(0, m.bind_call([])) assert_equal(0, m.bind_call([]))
assert_equal(1, m.bind_call([1])) assert_equal(1, m.bind_call([1]))
assert_equal(2, m.bind_call([1,2])) assert_equal(2, m.bind_call([1,2]))
o = Object.new
def m(x, y, z, *w, u:, v:, **opts, &blk)
{ x:, y:, z:, w:, u:, v:, opts:, blk: }
end
m = o.method(:m).unbind
blk = -> { }
values = { x: 1, y: 2, z: 3, w: [4, 5, 6], u: 7, v: 8, opts: { s: 9, t: 10 }, blk: blk }
assert_equal values, m.bind_call(o, 1, 2, 3, 4, 5, 6, u: 7, v: 8, s: 9, t: 10, &blk)
assert_equal values, m.bind_call(o, 1, 2, 3, 4, 5, 6, **{ u: 7, v: 8, s: 9, t: 10 }, &blk)
assert_equal values, m.bind_call(o, *[1, 2, 3, 4, 5, 6], u: 7, v: 8, s: 9, t: 10, &blk)
assert_equal values, m.bind_call(o, *[1, 2, 3, 4, 5, 6], **{ u: 7, v: 8, s: 9, t: 10 }, &blk)
assert_raise(ArgumentError) { m.bind_call }
end end
...@@ -40,11 +40,11 @@ class Proc ...@@ -40,11 +40,11 @@ class Proc
end end
def <<(other) def <<(other)
->(*args, &block) { call(other.call(*args, &block)) } ->(*args, **opts, &block) { call(other.call(*args, **opts, &block)) }
end end
def >>(other) def >>(other)
->(*args, &block) { other.call(call(*args, &block)) } ->(*args, **opts, &block) { other.call(call(*args, **opts, &block)) }
end end
end end
class Symbol class Symbol
def to_proc def to_proc
->(obj,*args,&block) do ->(obj,*args,**opts,&block) do
obj.__send__(self, *args, &block) obj.__send__(self, *args, **opts, &block)
end end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment