* vm_eval.c (vm_call0): should pass block to enumerators. patched
by Kazuki Tsujimoto. [ruby-dev:44961][Bug #5731] * vm_eval.c (method_missing), vm_insnhelper.c (vm_call_method): ditto. patched by satoshi shiba. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34399 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
cba57022b0
commit
72969cd348
@ -1,3 +1,11 @@
|
|||||||
|
Mon Jan 30 19:08:19 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* vm_eval.c (vm_call0): should pass block to enumerators. patched
|
||||||
|
by Kazuki Tsujimoto. [ruby-dev:44961][Bug #5731]
|
||||||
|
|
||||||
|
* vm_eval.c (method_missing), vm_insnhelper.c (vm_call_method):
|
||||||
|
ditto. patched by satoshi shiba.
|
||||||
|
|
||||||
Mon Jan 30 12:31:05 2012 NAKAMURA Usaku <usa@ruby-lang.org>
|
Mon Jan 30 12:31:05 2012 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||||
|
|
||||||
* file.c (append_fspath): need to set the encoding to result always.
|
* file.c (append_fspath): need to set the encoding to result always.
|
||||||
|
@ -446,6 +446,57 @@ class TestObject < Test::Unit::TestCase
|
|||||||
assert_equal([[:respond_to?, :to_ary, true]], called, bug5158)
|
assert_equal([[:respond_to?, :to_ary, true]], called, bug5158)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_method_missing_passed_block
|
||||||
|
bug5731 = '[ruby-dev:44961]'
|
||||||
|
|
||||||
|
c = Class.new do
|
||||||
|
def method_missing(meth, *args) yield(meth, *args) end
|
||||||
|
end
|
||||||
|
a = c.new
|
||||||
|
result = nil
|
||||||
|
assert_nothing_raised(LocalJumpError, bug5731) do
|
||||||
|
a.foo {|x| result = x}
|
||||||
|
end
|
||||||
|
assert_equal(:foo, result, bug5731)
|
||||||
|
result = nil
|
||||||
|
e = a.enum_for(:foo)
|
||||||
|
assert_nothing_raised(LocalJumpError, bug5731) do
|
||||||
|
e.each {|x| result = x}
|
||||||
|
end
|
||||||
|
assert_equal(:foo, result, bug5731)
|
||||||
|
|
||||||
|
c = Class.new do
|
||||||
|
def respond_to_missing?(id, priv)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
def method_missing(id, *args, &block)
|
||||||
|
return block.call(:foo, *args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
foo = c.new
|
||||||
|
|
||||||
|
result = nil
|
||||||
|
assert_nothing_raised(LocalJumpError, bug5731) do
|
||||||
|
foo.foobar {|x| result = x}
|
||||||
|
end
|
||||||
|
assert_equal(:foo, result, bug5731)
|
||||||
|
result = nil
|
||||||
|
assert_nothing_raised(LocalJumpError, bug5731) do
|
||||||
|
foo.enum_for(:foobar).each {|x| result = x}
|
||||||
|
end
|
||||||
|
assert_equal(:foo, result, bug5731)
|
||||||
|
|
||||||
|
result = nil
|
||||||
|
foobar = foo.method(:foobar)
|
||||||
|
foobar.call {|x| result = x}
|
||||||
|
assert_equal(:foo, result, bug5731)
|
||||||
|
|
||||||
|
result = nil
|
||||||
|
foobar = foo.method(:foobar)
|
||||||
|
foobar.enum_for(:call).each {|x| result = x}
|
||||||
|
assert_equal(:foo, result, bug5731)
|
||||||
|
end
|
||||||
|
|
||||||
def test_send_with_no_arguments
|
def test_send_with_no_arguments
|
||||||
assert_raise(ArgumentError) { 1.send }
|
assert_raise(ArgumentError) { 1.send }
|
||||||
end
|
end
|
||||||
|
@ -118,6 +118,7 @@ vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
|
|||||||
|
|
||||||
RB_GC_GUARD(new_args);
|
RB_GC_GUARD(new_args);
|
||||||
rb_ary_unshift(new_args, ID2SYM(id));
|
rb_ary_unshift(new_args, ID2SYM(id));
|
||||||
|
th->passed_block = blockptr;
|
||||||
return rb_funcall2(recv, idMethodMissing,
|
return rb_funcall2(recv, idMethodMissing,
|
||||||
argc+1, RARRAY_PTR(new_args));
|
argc+1, RARRAY_PTR(new_args));
|
||||||
}
|
}
|
||||||
@ -563,6 +564,7 @@ method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status)
|
|||||||
{
|
{
|
||||||
VALUE *nargv, result, argv_ary = 0;
|
VALUE *nargv, result, argv_ary = 0;
|
||||||
rb_thread_t *th = GET_THREAD();
|
rb_thread_t *th = GET_THREAD();
|
||||||
|
const rb_block_t *blockptr = th->passed_block;
|
||||||
|
|
||||||
th->method_missing_reason = call_status;
|
th->method_missing_reason = call_status;
|
||||||
th->passed_block = 0;
|
th->passed_block = 0;
|
||||||
@ -589,6 +591,7 @@ method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status)
|
|||||||
if (rb_method_basic_definition_p(CLASS_OF(obj) , idMethodMissing)) {
|
if (rb_method_basic_definition_p(CLASS_OF(obj) , idMethodMissing)) {
|
||||||
raise_method_missing(th, argc+1, nargv, obj, call_status | NOEX_MISSING);
|
raise_method_missing(th, argc+1, nargv, obj, call_status | NOEX_MISSING);
|
||||||
}
|
}
|
||||||
|
th->passed_block = blockptr;
|
||||||
result = rb_funcall2(obj, idMethodMissing, argc + 1, nargv);
|
result = rb_funcall2(obj, idMethodMissing, argc + 1, nargv);
|
||||||
if (argv_ary) rb_ary_clear(argv_ary);
|
if (argv_ary) rb_ary_clear(argv_ary);
|
||||||
return result;
|
return result;
|
||||||
|
@ -599,6 +599,7 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp,
|
|||||||
argv[0] = ID2SYM(me->def->original_id);
|
argv[0] = ID2SYM(me->def->original_id);
|
||||||
MEMCPY(argv+1, cfp->sp - num, VALUE, num);
|
MEMCPY(argv+1, cfp->sp - num, VALUE, num);
|
||||||
cfp->sp += - num - 1;
|
cfp->sp += - num - 1;
|
||||||
|
th->passed_block = blockptr;
|
||||||
val = rb_funcall2(recv, rb_intern("method_missing"), num+1, argv);
|
val = rb_funcall2(recv, rb_intern("method_missing"), num+1, argv);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user