note
Abigail-II
<blockquote><em>
I'm a little unclear as to whether you feel that I should simply have put
in use strict in all my examples, or whether your are pointing out that
using a hash_ref will not enable use strict to contribute much towards
debugging, or both.
</em></blockquote>
No, I'm wasn't saying you should use strict in your examples. That would
be pointless drivel. I'm pointing out that if you use hash keys as attributes
you will not benefit from using strict. But using strict is a good practise
so why advocate a coding style that cannot benefit from it.
<blockquote><em>
With respect to hiding (full encapsulation via anonymous subroutines)
I feel quite strongly that this belongs in an advanced OO tutorial such
as this one. I don't believe that throwing closures into the mix will
help people learn the fundamentals of how objects work in Perl.
</em></blockquote>
Where did I say full encapsulation can only be done with anonymous
subroutines? Full encapsulation doesn't belong in an advanced tutorial.
Full encapsulation is where you start. It's just like driving a car.
Avoiding pedestrians isn't "advanced driving" - it's part of the basics.
And you can get full (data) encapulation with techniques no more difficult
that using hash references.
<blockquote><em>
This ties into my feeling that, while hashes have their limitations,
they are the easiest way to introduce someone to OO in Perl. Are they
ideal? No. Are they less complicated than arrays or closures? Yes. Again,
this was never meant to be the canonical OO tutorial, just an
introduction.
</em></blockquote>
Did I say you need to use arrays or closures? No. Do I think you can
avoid the limitations I pointed out only by using arrays or closures instead of
hashes? No. I'd still use hashes.
<p>
Here's how you can write the Quote class you used in your tutorial.
<code>
package Quote;
use strict;
use warnings;
my (%phrase, %author, %approved);
sub new {
bless [] => shift; # Any reference will do.
}
sub set_phrase {
my $self = shift;
my $phrase = shift;
$phrase {$self} = $phrase;
}
sub get_phrase {
my $self = shift;
return $phrase {$self};
}
sub set_author {
my $self = shift;
my $author = shift;
$author {$self} = $author;
}
sub get_author {
my $self = shift;
return $author {$self};
}
sub is_approved {
my $self = shift;
@_ ? $approved {$self} = shift : $approved {$self};
}
sub DESTROY {
my $self = shift;
delete $phrase {$self};
delete $author {$self};
delete $approved {$self};
}
</code>
<p>
Doesn't this remarkably look like your code? Perhaps my code is even
simpler, I hardly use references - only the constructor returns a
reference, but we don't care what it is, or how to put data in it
(or to get something out of it). The only addition is the <code>DESTROY</code>
function. But this code <strong>is</strong> using full encapsulation.
Attributes cannot be trampled over. We're not enforcing our implementation
on an inheriting class. We don't even care how an inherited class is
implemented (if we are inherited, or we inherit something else, we don't
need our constructor to be called - cool, isn't?)
<p>
I'm convinced this way of implementing classes is actually <em>easier</em>
to learn, and less error-phrone than the traditional "just dump everything
in the same place" way by using a hashref.
<p>
Abigail
218778
219142