[前][次][番号順一覧][スレッド一覧]

ruby-changes:45944

From: nobu <ko1@a...>
Date: Sat, 18 Mar 2017 23:22:20 +0900 (JST)
Subject: [ruby-changes:45944] nobu:r58015 (trunk): vm_args.c: pass block

nobu	2017-03-18 23:22:15 +0900 (Sat, 18 Mar 2017)

  New Revision: 58015

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=58015

  Log:
    vm_args.c: pass block
    
    * vm_args.c (refine_sym_proc_call): pass block to the method when
      using refinements.  [ruby-core:80219] [Bug #13325]

  Modified files:
    trunk/test/ruby/test_refinement.rb
    trunk/vm_args.c
Index: vm_args.c
===================================================================
--- vm_args.c	(revision 58014)
+++ vm_args.c	(revision 58015)
@@ -12,6 +12,8 @@ NORETURN(static void raise_argument_erro https://github.com/ruby/ruby/blob/trunk/vm_args.c#L12
 NORETURN(static void argument_arity_error(rb_thread_t *th, const rb_iseq_t *iseq, const int miss_argc, const int min_argc, const int max_argc));
 NORETURN(static void argument_kw_error(rb_thread_t *th, const rb_iseq_t *iseq, const char *error, const VALUE keys));
 VALUE rb_keyword_error_new(const char *error, VALUE keys); /* class.c */
+static VALUE method_missing(VALUE obj, ID id, int argc, const VALUE *argv,
+			    enum method_missing_reason call_status);
 
 struct args_info {
     /* basic args info */
@@ -800,6 +802,7 @@ refine_sym_proc_call(RB_BLOCK_CALL_FUNC_ https://github.com/ruby/ruby/blob/trunk/vm_args.c#L802
     VALUE obj;
     ID mid;
     const rb_callable_method_entry_t *me;
+    rb_thread_t *th;
 
     if (argc-- < 1) {
 	rb_raise(rb_eArgError, "no receiver given");
@@ -807,11 +810,14 @@ refine_sym_proc_call(RB_BLOCK_CALL_FUNC_ https://github.com/ruby/ruby/blob/trunk/vm_args.c#L810
     obj = *argv++;
     mid = SYM2ID(callback_arg);
     me = rb_callable_method_entry_with_refinements(CLASS_OF(obj), mid);
+    th = GET_THREAD();
+    if (!NIL_P(blockarg)) {
+	vm_passed_block_handler_set(th, blockarg);
+    }
     if (!me) {
-	/* fallback to funcall (e.g. method_missing) */
-	return rb_funcall_with_block(obj, mid, argc, argv, blockarg);
+	return method_missing(obj, mid, argc, argv, MISSING_NOENTRY);
     }
-    return vm_call0(GET_THREAD(), obj, mid, argc, argv, me);
+    return vm_call0(th, obj, mid, argc, argv, me);
 }
 
 static void
Index: test/ruby/test_refinement.rb
===================================================================
--- test/ruby/test_refinement.rb	(revision 58014)
+++ test/ruby/test_refinement.rb	(revision 58015)
@@ -1769,6 +1769,31 @@ class TestRefinement < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/ruby/test_refinement.rb#L1769
     assert_equal("Foo#x", FooExtClient.return_proc(&:x).(Foo.new))
   end
 
+  def test_symbol_proc_with_block
+    assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+    bug = '[ruby-core:80219] [Bug #13325]'
+    begin;
+      module M
+        refine Class.new do
+        end
+      end
+      class C
+        def call(a, x, &b)
+          b.call(a, &x)
+        end
+      end
+      o = C.new
+      r = nil
+      x = ->(z){r = z}
+      assert_equal(42, o.call(42, x, &:tap))
+      assert_equal(42, r)
+      using M
+      r = nil
+      assert_equal(42, o.call(42, x, &:tap), bug)
+      assert_equal(42, r, bug)
+    end;
+  end
+
   module AliasInSubclass
     class C
       def foo

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]