Private methods in Ruby are pretty straightforward, but there are a few gotchas to be aware of.
Private Instance Methods
Private instance methods work pretty much as you would expect:
Instead of using the private keyword by itself - in which case all methods following this line will be private - you can also selectively declare private methods.
Private Class Methods
Class methods don’t necessarily work the same way:
What’s going on here? The private keyword is actually a method call on the instance’s class which sets the visibility for subsequently defined methods. It doesn’t affect subsequent class method declarations, as you can see from the result. If you’re interested in understanding why this is, I would suggest you read this excellent post by Jake Jesbeck. The short answer is that it’s due to the way Ruby looks up method declarations, known as dynamic dispatch.
You have 3 options here - you can either explicitly declare a private class method:
Or you can use the alternate syntax for declaring class methods:
A third option (which I haven’t really seen used anywhere, but it’s an option) is to use a module.
One more gotcha is with private initializers:
What’s going on here? If initialize is private, why can we still create a new object from outside of the class? This is because new and initialize are 2 different methods - in fact, the initialize method is always private!
This is a topic for a longer discussion, but since we are really calling new (which ends up calling initialize) we need to set new to private.
Private Methods in Subclasses
When you override a method the public/private level of the subclass wins out:
This doesn’t apply to the initialize method though, which is always private.