Wouldn't it be nice if inside-out objects worked like this?
use base 'Encapsulation'; sub new { bless {}, shift; } sub foo { my $self = shift; return $self->{foo} unless @_; $self->{foo} = shift; } 1;
If that was the interface but subclasses and other code couldn't reach inside, wouldn't more people use 'em? I believe most programmers violate encapsulation because they're lazy, not because they've gone rogue or something. Here's how to make that work.
That gives you protection during testing/development and speed in production (at the risk of REALLY painful bugs if there are flaws in the emulation of Encapsulation.pm).BEGIN {
if ($running_on_dev_server) {
require base;
base->import('Encapsulation');
}
}
if ($ENV{AUTHOR_TESTING}) {
Re:Dev vs. live
Aristotle on 2006-10-06T20:09:13
No.
Ovid is throwing away half the point of inside-out objects already: compile-time checking of field names. The other half is being agnostic about the implementation of any superclasses; and your suggestion would mean that one could no longer rely on that, either.
You may as well not use inside-out objects at all. (I am reminded of chromatic’s chocolate cake recipe analogy…)
Re:Dev vs. live
ChrisDolan on 2006-10-06T20:15:21
I was simply suggesting that this hack could be used at development time to catch places where external code illegitimately accessed variables via hash values instead of accessor functions.
That is, the encapsulation hack could be put to an alternate use. Especially if the overload function dies if the caller package isn't isa('Encapsulation').
I agree that the "inside-outness" is not significant in this case.
People seem to think that Inside-Out Objects are about not letting other people touch your internals.
They aren't.
Inside-Out Objects solve two out of three problems* I have with traditional Perl OO:
The first point means that OO programming isn't much better than programming in perl4 (not only don't you have the benefits of compile time errors, you don't have name spaces either).
The second point means that Perl is making easy things hard: code reuse is much harder that it should be.
The point of IOO isn't so much that it prevents other classes from accessing the internals (if you want to, changing a few 'my's to 'our's gives access, without giving up any of the other benefits of IOO), it's about giving classes the freedom to do whatever they want, without accidently touching someone elses internals.
The implementation you suggest doesn't solve any of the problems IOO solves. You don't get compile time errors on mistyping attribute names, and you will put a dependency in the inheritance tree.
Now, I won't judge your implementation as good or bad - if it works for you then it should be good enough, if it works for others so much the better. Just don't call it a different way of doing Inside-Out Objects. They aren't.
*: The third point being: too much typing to get to an attribute.
Re:That's not what I call 'inside-out' objects.
Ovid on 2006-10-07T16:32:14
I've evidently been wrong about IOO. Since the major problem I've faced has traditionally been encapsulation, that was the bit I've focused on. I will have to concede all your points. I just find that virtually every IOO implementation I've seen out there has been painful to work with, so I gave up and hope that solving the major problem I have might be good enough.
Re:That's not what I call 'inside-out' objects.
Aristotle on 2006-10-07T18:35:28
Hmm. For me, the visible difference between hash-based and inside-out objects is turning the following:
my $self = shift;
$self->{ bar };into this:
my $self = refaddr shift;
$bar{ $self };That seems hardly painful… but then, as MJD says, people are weird about syntax.