[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
>