Fixed some methods where keyword arguments are not passed
MODIFY
mrbgems/mruby-method/mrblib/method.rb
mrbgems/mruby-method/mrblib/method.rb
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

MODIFY
mrbgems/mruby-method/src/method.c
mrbgems/mruby-method/src/method.c
@@ -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;
}

MODIFY
mrbgems/mruby-method/test/method.rb
mrbgems/mruby-method/test/method.rb
@@ -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

MODIFY
mrbgems/mruby-proc-ext/mrblib/proc.rb
mrbgems/mruby-proc-ext/mrblib/proc.rb
@@ -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

MODIFY
mrblib/symbol.rb
mrblib/symbol.rb
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

Fixed some methods where keyword arguments are not passed