radiantmatrix has asked for the wisdom of the Perl Monks concerning the following question:
There's been a fair amount of banter about objects here lately, especially getters and setters. Now, I've usually been in the camp that using lvalue subs for this purpose is typically a bad idea (though it might be less so in Perl6). However, in meditating on the ideas and approaches in many PM threads on the topic, I thought of an approach which seems appealing.
Given my relative lack of wisdom in this topic area, I presume that I haven't been the first to think of it; yet, I never see it done. I assume that's because there is something wrong with it (or that there are simply unarguably better solutions). What I hope with this request is that my fellow Monks can help me understand if this really is a flawed approach, the reason(s) why, and what the superior approach is.
Without further ado, the code for a simple illustrive class:
package Objet; # yes, the 'c' is absent by design; use strict; use warnings; sub new { my $self = bless {}, shift; my %args = @_; while (my $k, $v = each %args) { $self->attrib($k => $v); } return $self; } sub attrib { my $self = shift; my ($attr, $value) = @_; # if we aren't setting, then get. # I don't use defined $value, because setting to undef might be ok. return $self->{$attr} unless (scalar @_ >= 2); # otherwise, set the attribute $self->{$attr} = $value; } 1;
Of course, there's lots I'd do to validate that attributes should exist, and so on, but this is simple-case code. This might be implemented like:
use Objet; my $o = Objet->new('aleph' => 1, 'gamma' => 2); $o->attrib( 'zeta' => 900 ); # sets attribute 'zeta' to 900 print $o->attrib( 'aleph' ); # gets value of attrib 'aleph'
Update: it seems that I've managed to oversimplify to the extent that I've distracted from my own question. I already realize that there are major implmentation flaws in the above, but that's because it's basically simple psuedo-code that compiles. I realize that the attrib method would be more complex than it is: validation (including checking if an attribute exists {avoids typos}, and if an attribute is private/public), setting that is more complicated than an assignment, and so on would need to be addressed. A slight snippet of example:
Yes, there are still implementation issues, and I wouldn't implement new() that way at all, etc. But hopefully this makes it clear that there are plenty of ways to have independent setter/getter subroutines, but only one public interface to all of it, which is what I'm asking about.
So, what's wrong with this approach? Thanks in advance for hitting me with the Paddles of Enlightenment.
|
|---|