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
def to_proc
m = self
lambda { |*args, &b|
m.call(*args, &b)
lambda { |*args, **opts, &b|
m.call(*args, **opts, &b)
}
end
def <<(other)
->(*args, &block) { call(other.call(*args, &block)) }
->(*args, **opts, &block) { call(other.call(*args, **opts, &block)) }
end
def >>(other)
->(*args, &block) { other.call(call(*args, &block)) }
->(*args, **opts, &block) { other.call(call(*args, **opts, &block)) }
end
end
......@@ -20,15 +20,19 @@ args_shift(mrb_state *mrb)
mrb_value *argv = ci->stack + 1;
if (ci->n < 15) {
if (ci->n == 0) { goto argerr; }
mrb_assert(ci->nk == 0 || ci->nk == 15);
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--;
return obj;
}
else if (ci->n == 15 && RARRAY_LEN(*argv) > 0) {
else if (RARRAY_LEN(*argv) > 0) {
return mrb_ary_shift(mrb, *argv);
}
else {
argerr:
mrb_argnum_error(mrb, 0, 1, -1);
return mrb_undef_value(); /* not reached */
}
......@@ -41,9 +45,12 @@ args_unshift(mrb_state *mrb, mrb_value obj)
mrb_value *argv = ci->stack + 1;
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[1] = block;
argv[1] = argv[ci->n]; // keyword or block
if (ci->nk == 15) {
argv[2] = argv[ci->n + 1]; // block
}
ci->n = 15;
}
......
......@@ -208,6 +208,16 @@ assert 'Method#to_proc' do
yield 39
end
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
assert 'to_s' do
......@@ -449,4 +459,17 @@ assert 'UnboundMethod#bind_call' do
assert_equal(0, m.bind_call([]))
assert_equal(1, m.bind_call([1]))
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
......@@ -40,11 +40,11 @@ class Proc
end
def <<(other)
->(*args, &block) { call(other.call(*args, &block)) }
->(*args, **opts, &block) { call(other.call(*args, **opts, &block)) }
end
def >>(other)
->(*args, &block) { other.call(call(*args, &block)) }
->(*args, **opts, &block) { other.call(call(*args, **opts, &block)) }
end
end
class Symbol
def to_proc
->(obj,*args,&block) do
obj.__send__(self, *args, &block)
->(obj,*args,**opts,&block) do
obj.__send__(self, *args, **opts, &block)
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