Joel Roth asks is violating encapsulation really that bad?.
In two words, it depends.
Encapsulation is merely a technique of structuring your program. The same goes for structured programming and design patterns and object orientation and functional programming and minimizing mutable state. These techniques exist (and good programmers practice them) to help programmers reason about the intent and activity of code.
If you had ten minutes to write a short program to save you a million dollars and you never had to touch that program again, never ever, you might make different design decisions than if you worked on a year long project with a dozen other programmers. If you're a capable and informed intelligent economic actor, this is because the reward of being able to reason about a system at every level from small to large governs the risk of unexpected interactions between unrelated components.
Ask yourself this: would you violate the encapsulation of your objects? Would you use global variables? Would you eschew lexical scoping in favor of global variables? Would you avoid function parameters and return values in favor of setting and reading global variables? Would you avoid functions altogether?
These design strategies exist along a continuum (just like scalability and performance strategies). You pick what you need when it's appropriate. If you're willing to bear the risk that your violation of encapsulation here or there makes maintaining your code more difficult in the future, at least make that choice with good information. (Again, if you don't need to maintain your software, do what's fastest.)
With that said, in the context of writing tutorials—especially for novice programmers—it's irresponsible to encourage people to write quick and dirty code with known risks. The experts writing tutorials have gone through the pain of maintaining and debugging and fixing plenty of code where the initial developer's gamble went awry. Tutorials should encourage novices away from well-known pitfalls. When they're no longer novices—when they really, truly understand the risks—they can do things the risky way.
Hi chromatic,
I'd like to differentiate between using code to clarify how objects work in Perl 5, and advocating well-known pitfalls.
In your opinion is there no context in which $object->{key} can be safely mentioned to novices without inducing quick-and-dirty coding practices?
Joel Roth
In my 2006 YAPC talk on inside-out objects, I made an analogy for encapsulation as a choice between "double-yellow lines" and "Jersey barriers". (For those outside the US, those are the painted lines in the middle of the road and the concrete barriers used to divide traffic.)
The typical hash-based OO pattern in Perl is what I called "advisory encapsulation". To use the double-yellow line analogy, you shouldn't cross it and you just might get hit by oncoming traffic if you aren't really careful, but sometimes there is an accident or an obstruction and it saves a lot of time to just swerve over the double-yellow line and go around.
The alternative is "enforced encapsulation" -- which inside-out objects (mostly) provide. Just like the concrete barrier, you'll never get hit by oncoming traffic, but you're totally stuck if there is an obstruction.
I bring this up not to advocate inside-out objects (which I know enough about to despise), but to point out that advisory encapsulation is very consistent with Perl's general design and philosophy. Yes, you can go mucking about inside blessed references if you really need to, but that doesn't make it a good idea for a regular practice.
From a teaching perspective, I think one should teach the guts just enough so that people understand the issues and pitfalls and then one should teach "good practices" that people should use in everyday code.
And to answer Joel Roth's question with David Golden's analogy:
A new driver's manual should tell new drivers to not cross over the double yellow line. So an OO tutorial should tell drivers to not violate encapsulations.
You have to show novices the encapsulation-breaking form if only to explain what's going on when they read poorly-written existing code.
Another problem with encouraging people to access object attributes directly is that it obscures the intent of the code; there's no way of knowing if the author of the class intends for you to access that attribute directly, or if it's delegated elsewhere, or a calculated attribute, or part of another calculated attribute, or something else. You just get a big bucket of key/value pairs and hope that you're not breaking something by rummaging around in it directly.