Private methods in Ruby
Consider the following code:
(This blew my mind the other day.)
class Hello
def public_hello
self.private_hello
end
private
def private_hello
puts "Hello!"
end
end
You would expect that this would work fine: private_hello
is a private method, but it's being called from within the class.
Nope.
>> hello = Hello.new
=> #<Hello:0x10d0cc200>
>> hello.public_hello
NoMethodError: private method `private_hello' called for #<Hello:0x10d0cc200>
from (irb):3:in `public_hello'
from (irb):13
I spent an embarassingly long time trying to figure out what was wrong ("Do I just not understand how private methods work?!"), and confused one of my coworkers as well in the process of doing so.
However, it turned out to be old news. One post puts the issue pretty succinctly:
private methods can never be called with an explicit receiver, even if the receiver is self
So, the problem with self.private_hello
is that the private method is being called on an explicit receiver, even though the receiver is technically the same object—you'd need to call private_hello
by itself instead.
Having learned access control modifiers in Java first, I thought this was really bizarre. I guess I need to learn Ruby a little better! (: