summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--test/ruby/test_object.rb51
-rw-r--r--version.h6
-rw-r--r--vm_eval.c3
-rw-r--r--vm_insnhelper.c1
5 files changed, 66 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 985018d089..ac8947bf5d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Mon Feb 6 15:01:55 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 Feb 6 21:52:20 2012 Yuki Sonoda (Yugui) <yugui@yugui.jp>
* common.mk (INSTRUBY_ARGS): added --mantype to apply mdoc2man.rb
diff --git a/test/ruby/test_object.rb b/test/ruby/test_object.rb
index 63c1d32bef..db34d14479 100644
--- a/test/ruby/test_object.rb
+++ b/test/ruby/test_object.rb
@@ -383,6 +383,57 @@ class TestObject < Test::Unit::TestCase
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
assert_raise(ArgumentError) { 1.send }
end
diff --git a/version.h b/version.h
index 4ddefe25b0..1d96d4b718 100644
--- a/version.h
+++ b/version.h
@@ -1,10 +1,10 @@
#define RUBY_VERSION "1.9.3"
-#define RUBY_PATCHLEVEL 43
+#define RUBY_PATCHLEVEL 44
-#define RUBY_RELEASE_DATE "2012-02-06"
+#define RUBY_RELEASE_DATE "2012-02-07"
#define RUBY_RELEASE_YEAR 2012
#define RUBY_RELEASE_MONTH 2
-#define RUBY_RELEASE_DAY 6
+#define RUBY_RELEASE_DAY 7
#include "ruby/version.h"
diff --git a/vm_eval.c b/vm_eval.c
index 7df7f5f47b..a7e15918b5 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -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_ary_unshift(new_args, ID2SYM(id));
+ th->passed_block = blockptr;
return rb_funcall2(recv, idMethodMissing,
argc+1, RARRAY_PTR(new_args));
}
@@ -547,6 +548,7 @@ method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status)
{
VALUE *nargv, result, argv_ary = 0;
rb_thread_t *th = GET_THREAD();
+ const rb_block_t *blockptr = th->passed_block;
th->method_missing_reason = call_status;
th->passed_block = 0;
@@ -572,6 +574,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)) {
raise_method_missing(th, argc+1, nargv, obj, call_status | NOEX_MISSING);
}
+ th->passed_block = blockptr;
result = rb_funcall2(obj, idMethodMissing, argc + 1, nargv);
if (argv_ary) rb_ary_clear(argv_ary);
return result;
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 5ce46d6331..55152df2d9 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -555,6 +555,7 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp,
argv[0] = ID2SYM(me->def->original_id);
MEMCPY(argv+1, cfp->sp - num, VALUE, num);
cfp->sp += - num - 1;
+ th->passed_block = blockptr;
val = rb_funcall2(recv, rb_intern("method_missing"), num+1, argv);
break;
}