On Mon, 2006-10-02 at 05:00 +0900, Tomasz W. wrote:
I have an modest proposal - can’t we just get rid of private methods
completely in Ruby 2 ?
The private modifier in Ruby is usually more advisory than anything
else. That’s why #define_method is private, for example. Just like
private instance variables indicate data that clients of the class
shouldn’t touch, private methods indicate operations clients of the
class shouldn’t touch. Note “shouldn’t” as opposed to “can’t”. Certainly
clients of a class have no business redefining its methods on a regular
basis - if that was intended, the class would be engineered for
inheriting and clients could create their own customized versions. Using
metaprogramming for this is more of an emergency measure when the author
of the modified code didn’t foresee the need for this and code
In my code, I use private methods for helper operations to dissect an
algorithm into separate steps - these serve only to give fragments of
code a name, not encapsulate any standalone functionality. Calling them
out-of-order from client code would usually clobber an object’s
internals beyond repair.
In all OO systems, the private / public distinction is to hide
information about the inner workings of a class. While instance
variables are obviously such information, often also how a class
achieves what it does qualifies.
If you have to call methods directly, that’s one more indication
that you’re Doing Something Weird.
The difficulty in unit-testability is more of a failure on the side of
the test framework. Including a “whitebox” mode in Test::Unit
(generating public wrappers for private methods of tested classes) would
be a more concise solution to this problem.
The feature of private methods in Ruby is one I like. It’s an
encapsulation safety net as opposed to a roadblock in Ruby, but makes it
more apparent in code that something out-of-the-ordinary is being done.
I might be biased, since I’m opposed to strong usage of Ruby’s
metaprogramming capacities in “serious” code, at least without
encapsulating such code very tightly. But removing all method-level
encapsulation to facilitate meta hacks or get rid of some scenarios when
they are necessary seems just overkill.