Skip to content
Permalink
Browse files

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]
  • Loading branch information
dylanahsmith authored and nobu committed Jul 2, 2019
1 parent 17a1366 commit 7fbd2f7cc247ee66e877ab3c88f0274834c6b6c7
Showing with 9 additions and 4 deletions.
  1. +4 −0 compile.c
  2. +1 −1 spec/ruby/language/send_spec.rb
  3. +1 −1 test/ruby/test_method.rb
  4. +2 −1 test/ruby/test_module.rb
  5. +1 −1 test/ruby/test_refinement.rb
@@ -6773,6 +6773,10 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
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));
}
@@ -260,7 +260,7 @@ def []=(*)
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
@@ -673,7 +673,7 @@ def test_visibility
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
@@ -2479,7 +2479,8 @@ def assert_top_method_is_private(method)
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
@@ -538,7 +538,7 @@ def foo

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

0 comments on commit 7fbd2f7

Please sign in to comment.
You can’t perform that action at this time.