[Bioperl-l] Re: Automatic generation of set and get methods
Brian Desany
bdesany@bcm.tmc.edu
Fri, 15 Nov 2002 11:56:35 -0600
What the heck, I'll de-lurk too and point out that I got this idiom from I
*think* Damian Conway's OO Perl book. (Apologies if I mis-identified who I
stole this idea from).
for my $attribute (qw( assembly
yac_number
set_scheme
seeds
include_seeds
xmatch
trim_scheme
append_readpair
command
phrap_opt
db ) ) {
no strict "refs";
*$attribute = sub {
my $self = shift;
if (@_) {
my $val = shift;
$self->{$attribute} = $val;
}
return $self->{$attribute};
}
}
It has the benefit of reducing cutting and pasting, but also explictly
listing what attributes are supported by the module. I'll stay out of the
debate on what the return value should be when setting the attribute, but
the guts can follow whatever convention you want.
Speaking of which, this doesn't address validation, but then again if I want
custom validation for a particular method, I don't mind hand-coding the
whole method. And if enough multiple methods require the same kind of
validation, than I'll set up two of these things with slightly different
guts. For me it's been a good tradeoff.
-Brian Desany.
>
>I'll de-lurk briefly here to offer yet another perspective, as this is
>an interesting discussion and a topic that I sometimes spend idle
>moments worrying about: ie, what's the "best" way to do this.
>
>I think my approach is a complete hybrid of the stuck/not stuck in the
>mud views advocated so far. I'm definitely in favor of having explicit
>methods, but like everyone else I'm lazy and don't like
>cutting, pasting
>and modifying lots get/set methods. So, here's what I do: I write one
>method that works for all fields and can be called explicitly, and use
>AUTOLOAD for "convenience" methods.
>
>sub field {
> my($self, $field, $value) = @_ ;
>
> @_ == 1 and return grep (/^[^_]/, sort keys %$self) ;
> @_ == 2 and return $self->{$field} ;
> @_ == 3 and return $self->{$field} = $value ;
>}
>
>sub AUTOLOAD {
> my $self = shift ;
> my $class = ref $self ;
> my($package, $methodName) = $AUTOLOAD =~ /(.+)::([^:]+)$/ ;
>
> no strict 'refs' ;
> unless ( grep { $methodName eq $_ } (@Fields,
>@{"${class}::Fields"}) ) {
> # die with stack trace
> Carp::confess("'$methodName' is not a valid field in class
>'$package'") ;
> }
> use strict 'refs' ;
>
> return $self->field($methodName, @_) ;
>}
>
>I've been using this approach for a while and it works for me.
> But then
>I like living dangerously ;-). Seriously, I would like to hear what
>folks consider "scary" about using AUTOLOAD in this way.
>
> -Steve
>--
>Steve Mathias, Ph.D.
>UNM Biocomputing Center
>E-Mail: smathias@unm.edu
>Office phone: (505) 272-8111
>_______________________________________________
>Bioperl-l mailing list
>Bioperl-l@bioperl.org
>http://bioperl.org/mailman/listinfo/bioperl-l
>