From b4657182da44febeccd5f22af636bceda776122f Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 13 May 2014 09:13:33 +0900 Subject: convert &arg using to_proc; fix #2242 --- src/vm.c | 3 +++ test/t/proc.rb | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/vm.c b/src/vm.c index 2c6fbf087..4f257d462 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1286,6 +1286,9 @@ RETRY_TRY_BLOCK: int len = m1 + o + r + m2; mrb_value *blk = &argv[argc < 0 ? 1 : argc]; + if (!mrb_nil_p(*blk) && mrb_type(*blk) != MRB_TT_PROC) { + *blk = mrb_convert_type(mrb, *blk, MRB_TT_PROC, "Proc", "to_proc"); + } if (argc < 0) { struct RArray *ary = mrb_ary_ptr(regs[1]); argv = ary->ptr; diff --git a/test/t/proc.rb b/test/t/proc.rb index 33c3a0ef2..e871e637e 100644 --- a/test/t/proc.rb +++ b/test/t/proc.rb @@ -131,3 +131,20 @@ assert('Proc#return_does_not_break_self') do assert_equal nil, c.return_nil assert_equal c, c.block.call end + +assert('&obj call to_proc if defined') do + pr = Proc.new{} + def mock(&b) + b + end + assert_equal pr.object_id, mock(&pr).object_id + assert_equal pr, mock(&pr) + + obj = Object.new + def obj.to_proc + Proc.new{ :from_to_proc } + end + assert_equal :from_to_proc, mock(&obj).call + + assert_raise(TypeError){ mock(&(Object.new)) } +end -- cgit v1.2.3