Re^2: Class::Accessor and Damian's PBP
by grantm (Parson) on Feb 23, 2006 at 00:49 UTC
|
If you have so many accessible properties that you need to generate accessors for them, you may need to re-think your design. Accessors are a code smell.
I'm not sure that I entirely agree with that assertion.
Most OO classes will have a number of properties, but unfortunately Perl's object model does not provide a standard way to define those properties. The simple and common approach is to store properties as keys in a hash but this leads to hard-to-find bugs resulting from typos in hash keys. Generating accessors is an effective way to eliminate that class of error.
I do agree that lots of accessors in the public API of a class is often a problem with the design.
The examples on the page you linked to seem to be written in a language that, unlike Perl, supports both properties and private methods.
| [reply] |
|
| [reply] [d/l] |
|
| [reply] |
Re^2: Class::Accessor and Damian's PBP
by nothingmuch (Priest) on Feb 22, 2006 at 20:59 UTC
|
Whenever your setter needs to be normalized to a different value lvalue accessors don't cut it.
| [reply] |
|
use Contextual::Return;
# Name method offers unconstrained access...
sub name : lvalue {
my ($self) = @_;
$name_of{ident $self};
}
# Rank method constrains access: can assign only valid ranks
# (value being assigned is passed as $_ to LVALUE block)...
sub rank : lvalue {
my ($self) = @_;
LVALUE {
croak "Invalid rank ($_) assigned" if !$is_valid_rank{$_};
$rank_of{ident $self} = $_;
}
RVALUE {
$rank_of{ident $self};
}
}
# Serial method offers read-only access...
sub serial {
my ($self) = @_;
return $snum_of{ident $self};
}
With this functionality now available, I'm seriously reconsidering my long-held objections to lvalue accessors.
Damian | [reply] [d/l] [select] |
|
Wow, that's pretty nice... Great work =)
| [reply] |
|
| [reply] |
|
uh, override the set method?
| [reply] [d/l] |
|
|
|
Re^2: Class::Accessor and Damian's PBP
by cbrandtbuffalo (Deacon) on Feb 23, 2006 at 12:47 UTC
|
If you have so many accessible properties that you need to generate accessors for them, you may need to re-think your design.
I'm working on a configuration module, so accessors and data are the primary purpose of the module. You can see some background in Configuration Best Practices for Web Apps.
Even if you don't have many, though, I would argue the good kind of Laziness should drive you to use tools to avoid cut and paste. Even with just a few accessors, the code often ends up being largely cut and pasted, so using a module to automate the process is still a nice idea.
| [reply] |
|
After playing around in several directions, I realized that it's trivially easy to generate default accessors, which may be why there are so many modules for it (although it makes me wonder why there are any).
for my $property (qw(several members defined public)) {
no strict 'refs';
*{"get_$property"} = sub { (shift)->{$property} };
*{"set_$property"} = sub { (shift)->{$property} = $_[0] };
}
Caution: Contents may have been coded under pressure.
| [reply] [d/l] |
|
You got it. I took at look and that's almost exactly what Class::Accessor does.
| [reply] |
Re^2: Class::Accessor and Damian's PBP
by diotalevi (Canon) on Feb 22, 2006 at 20:33 UTC
|
Lvalue properties are fine if you're using Visual Basic or another language where they're better supported. They're a bad idea in perl.
| [reply] |
|
| [reply] |