The following code works:
class MyClass
def method_a
method_b
end
private
def method_b
puts "Hello!"
end
end
m = MyClass.new
m.method_a
Changing the call to method_b to self.method_b
however does not work:
def method_a
self.method_b
end
I get a NoMethodError
. I'm under the impression that self
just resolves to the instance of the class when inside an instance method. Why does self.method_b
cause problems?
Note: self.method_b
works when private
is changed to protected
.
Note: if the above methods are changed to class methods then calling self.method_b
from method_a doesn't throw the NoMethodError
.
This is how private
methods work in Ruby. They cannot be called with an explicit receiver (unless it is a setter method; see below).
Read more in the section on Access Control from the Pickaxe.
Private methods whose names end with an =
may be invoked using self.method_name = ...
as this is necessary to differentiate them from setting a local variable:
class Foo
def try
set_foo(1) # Invokes private method
self.set_foo(2) # ERROR: private method `set_foo' called for ...
self.send(:set_foo,3) # Invokes private method
bar = 1 # Sets local variable
self.bar = 2 # Invokes private method
self.send(:bar=,3) # Invokes private method
end
private
def set_foo(v)
@foo = v
end
def bar=(v)
@bar = v
end
end
Foo.new.bar = 42 # ERROR: private method `bar=' called for ...