diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-11-25 17:08:32 +0900 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-11-25 17:08:32 +0900 |
| commit | b631c226eb3e59a813224183bbc9ddc2a01acd0e (patch) | |
| tree | ef93a007a11e728118f01432c16c71506c336241 | |
| parent | d6e1114f71927e34bda05544d548edaa411f583f (diff) | |
| parent | 16e388863afef7616c7272d779f8cb7abc478992 (diff) | |
| download | mruby-b631c226eb3e59a813224183bbc9ddc2a01acd0e.tar.gz mruby-b631c226eb3e59a813224183bbc9ddc2a01acd0e.zip | |
Merge pull request #5585 from dearblue/args-pass
Fixed some methods where keyword arguments are not passed
| -rw-r--r-- | mrbgems/mruby-method/mrblib/method.rb | 8 | ||||
| -rw-r--r-- | mrbgems/mruby-method/src/method.c | 15 | ||||
| -rw-r--r-- | mrbgems/mruby-method/test/method.rb | 23 | ||||
| -rw-r--r-- | mrbgems/mruby-proc-ext/mrblib/proc.rb | 4 | ||||
| -rw-r--r-- | mrblib/symbol.rb | 4 |
5 files changed, 42 insertions, 12 deletions
diff --git a/mrbgems/mruby-method/mrblib/method.rb b/mrbgems/mruby-method/mrblib/method.rb index 56af7cf61..09b611eb7 100644 --- a/mrbgems/mruby-method/mrblib/method.rb +++ b/mrbgems/mruby-method/mrblib/method.rb @@ -1,16 +1,16 @@ 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 diff --git a/mrbgems/mruby-method/src/method.c b/mrbgems/mruby-method/src/method.c index 73933049f..b8a55e618 100644 --- a/mrbgems/mruby-method/src/method.c +++ b/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; } diff --git a/mrbgems/mruby-method/test/method.rb b/mrbgems/mruby-method/test/method.rb index 675277726..ba4d05e3c 100644 --- a/mrbgems/mruby-method/test/method.rb +++ b/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 diff --git a/mrbgems/mruby-proc-ext/mrblib/proc.rb b/mrbgems/mruby-proc-ext/mrblib/proc.rb index abe9c7944..3be0afbbc 100644 --- a/mrbgems/mruby-proc-ext/mrblib/proc.rb +++ b/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 diff --git a/mrblib/symbol.rb b/mrblib/symbol.rb index 9c981dd9e..827e2c1e0 100644 --- a/mrblib/symbol.rb +++ b/mrblib/symbol.rb @@ -1,7 +1,7 @@ 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 |
