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

ruby-changes:57822

From: Dylan <ko1@a...>
Date: Fri, 20 Sep 2019 03:25:01 +0900 (JST)
Subject: [ruby-changes:57822] 7fbd2f7cc2 (master): Allow calling a private method with `self.`

https://git.ruby-lang.org/ruby.git/commit/?id=7fbd2f7cc2

From 7fbd2f7cc247ee66e877ab3c88f0274834c6b6c7 Mon Sep 17 00:00:00 2001
From: Dylan Thacker-Smith <Dylan.Smith@s...>
Date: Tue, 2 Jul 2019 15:06:54 +0100
Subject: Allow calling a private method with `self.`

This makes it consistent with calling private attribute assignment
methods, which currently is allowed (e.g. `self.value =`).

Calling a private method in this way can be useful when trying to
assign the return value to a local variable with the same name.

[Feature #11297] [Feature #16123]

diff --git a/compile.c b/compile.c
index 7cfda23..cea09c8 100644
--- a/compile.c
+++ b/compile.c
@@ -6773,6 +6773,10 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in https://github.com/ruby/ruby/blob/trunk/compile.c#L6773
             iseq_block_param_id_p(iseq, node->nd_recv->nd_vid, &idx, &level)) {
             ADD_INSN2(recv, nd_line(node->nd_recv), getblockparamproxy, INT2FIX(idx + VM_ENV_DATA_SIZE - 1), INT2FIX(level));
         }
+        else if (private_recv_p(node)) {
+            ADD_INSN(recv, nd_line(node), putself);
+            flag |= VM_CALL_FCALL;
+        }
         else {
             CHECK(COMPILE(recv, "recv", node->nd_recv));
         }
diff --git a/spec/ruby/language/send_spec.rb b/spec/ruby/language/send_spec.rb
index 4ba3dcc..cce2e1a 100644
--- a/spec/ruby/language/send_spec.rb
+++ b/spec/ruby/language/send_spec.rb
@@ -260,7 +260,7 @@ end https://github.com/ruby/ruby/blob/trunk/spec/ruby/language/send_spec.rb#L260
 describe "Invoking a private getter method" do
   it "does not permit self as a receiver" do
     receiver = LangSendSpecs::PrivateGetter.new
-    -> { receiver.call_self_foo }.should raise_error(NoMethodError)
+    -> { receiver.call_self_foo }.should_not raise_error(NoMethodError)
     -> { receiver.call_self_foo_or_equals(6) }.should raise_error(NoMethodError)
   end
 end
diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb
index 1289b44..a8064c4 100644
--- a/test/ruby/test_method.rb
+++ b/test/ruby/test_method.rb
@@ -673,7 +673,7 @@ class TestMethod < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_method.rb#L673
     assert_nothing_raised { mv3 }
 
     assert_nothing_raised { self.mv1 }
-    assert_raise(NoMethodError) { self.mv2 }
+    assert_nothing_raised { self.mv2 }
     assert_nothing_raised { self.mv3 }
 
     v = Visibility.new
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb
index 7bb2261..8689c60 100644
--- a/test/ruby/test_module.rb
+++ b/test/ruby/test_module.rb
@@ -2479,7 +2479,8 @@ class TestModule < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_module.rb#L2479
       assert_include(methods, :#{method}, ":#{method} should be private")
 
       assert_raise_with_message(NoMethodError, "private method `#{method}' called for main:Object") {
-        self.#{method}
+        recv = self
+        recv.#{method}
       }
     }
   end
diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb
index 87d60e4..4be0720 100644
--- a/test/ruby/test_refinement.rb
+++ b/test/ruby/test_refinement.rb
@@ -538,7 +538,7 @@ class TestRefinement < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_refinement.rb#L538
 
   def test_main_using_is_private
     assert_raise(NoMethodError) do
-      eval("self.using Module.new", Sandbox::BINDING)
+      eval("recv = self; recv.using Module.new", Sandbox::BINDING)
     end
   end
 
-- 
cgit v0.10.2


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

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