The two invocations of an instance method carry different semantics. The first call to bar
works as expected.
class T
def foo
bar # <= This works. "bar" is printed.
self.bar # <= EXCEPTION: `foo': private method `bar' called for ...
end
private
def bar
puts 'bar'
end
end
t = T.new
t.foo
I'd like to understand why. What causes self.bar
to have a different semantics, throwing an exception? I'm not interested in the exception per se since I can work around with the dubious removal of the private
label, but primarily interested in the semantic discussion.
Private methods can not be called with explicit receiver like self
. This means that you can call a private method from within a class it is declared in as well as all subclasses of this class.
Here is a good article about that. It explains well why code like yours will raise NoMethodError
.
On wikibooks there is also a good explanation of visibility levels in ruby.
For the reference you can bypass this with Object#send but generally it is considered as a bad practice to do so.