[Bioperl-l] Auto-method caller proposal

aaron.j.mackey at gsk.com aaron.j.mackey at gsk.com
Wed Jan 3 15:01:25 EST 2007


I'm not against this at all, but let's not reinvent a (somewhat-standard) 
wheel: see Class::MethodMaker and accompanying tools.

-Aaron

bioperl-l-bounces at lists.open-bio.org wrote on 01/03/2007 01:09:26 PM:

> I propose a method that sets method values based on user-supplied args 
> to new(), most likely to be placed in Bio::Root::RootI (given its 
> intention to substitute or complement _rearrange for some module 
> authors). The method name (_set_from_args) is open to alternative 
> suggestions.
> 
> A lazy module author (eg. someone doing a run wrapper) might say:
> 
> package Bio::Tools::Run::Lazy;
> sub new {
>    my ($class, @args) = @_;
>    my $self = $class->SUPER::new(@args);
> 
>    $self->_set_from_args(\@args,
>                          -methods => [qw(id score evalue)],
>                          -create => 1);
> 
>    return $self;
> }
> 1;
> 
> A user with a tendency to accidentally press shift or forget to use 
> dashes could then say:
> 
> use Bio::Tools::Run::Lazy;
> my $lazy = Bio::Tools::Run::Lazy->new(-sCore => 5, evalue => 0);
> my $id = $lazy->id # undef, not fatal
> my $score = $lazy->score # 5, $lazy->sCore would be fatal
> my $evalue = $lazy->evalue # 0
> 
> 
> This has the very slight advantage over AUTOLOAD in that we can 
> $lazy->can('id'), and the better advantage over the current run 
> wrappers: not every one of them would have to define its own AUTOLOAD 
> method and have its own way of dealing with dashed or dashless 
parameters.
> 
> 
> For less lazy authors who define all their methods, we can still gain a 
> benefit. Instead of the current:
> 
> package Bio::Tools::Run::GoodBoy;
> sub new {
>    my ($class, @args) = @_;
>    my $self = $class->SUPER::new(@args);
> 
>    my ($id, $score, $evalue) = $self->_rearrange([qw(ID SCORE EVALUE)], 
> %args);
> 
>    $self->id($id) if defined $id;
>    $self->score($score) if defined $score;
>    $self->evalue($evalue) if defined $evalue;
> 
>    return $self;
> }
> # methods...
> 1;
> 
> We can have the nicer:
> 
> package Bio::Tools::Run::GoodBoy;
> sub new {
>    my ($class, @args) = @_;
>    my $self = $class->SUPER::new(@args);
> 
>    $self->_set_from_args(\@args,
>                          -methods => [qw(id score evalue)]);
> 
>    return $self;
> }
> # methods...
> 1;
> 
> 
> 
> 
> Proposed code (excuse the broken formatting):
> 
> =head2 _set_from_args
> 
>   Usage     : $object->_set_from_args(\%args, -methods => \@methods)
>   Purpose   : Takes a hash of user-supplied args whos keys match method 
> names,
>             : and calls the method supplying it the corresponding value.
>   Example   : $self->_set_from_args(%args, -methods => [qw(sequence id 
> desc)]);
>             : Where %args = (-sequence    => $s,
>           :                -description => $d,
>           :                -ID          => $i);
>   Returns   : n/a
>             : the above _set_from_args calls the following methods:
>             : $self->sequence($s);
>             : $self->id($i);
>             : ( $self->description($i) is not called because 
> 'description' wasn't
>             :   one of the given methods )
>   Argument  : \%args          : a hash ref of arguments where keys are 
> any-case
>             :                   strings corresponding to method names 
but
>             :                   optionally prefixed  with hyphens, and 
> values are
>             :                   the values the method should be supplied
>             : -methods => []  : (optional) only call methods with names 
> in this
>             :                   array ref
>             : -force => bool  : (optional, default 0) call methods that 
> don't
>             :                   seem to exist, ie. let AUTOLOAD handle 
them
>             : -create => bool : (optional, default 0) when a method 
doesn't
>             :                   exist, create it as a simple 
getter/setter
>             :                   (combined with -methods it would create 
> all the
>             :                   supplied methods that didn't exist, even 

> if not
>             :                   mentioned in the supplied %args)
> 
> =cut
> 
> sub _set_from_args {
>      my ($self, $args, @own_args) = @_;
>      $self->throw("a hash ref of arguments must be supplied") unless 
> ref($args);
> 
>      my ($methods, $force, $create);
>      if (@own_args) {
>          ($methods, $force, $create) = $self->_rearrange([qw(METHODS
>                                                              FORCE
>                                                              CREATE)], 
> @own_args);
>      }
> 
>      my %args = ref($args) eq 'HASH' ? %{$args} : @{$args};
>      my %methods = $methods ? map { lc($_) => $_ } @{$methods} : ();
> 
>      if ($create) {
>          foreach my $method (@{$methods}) {
>              $self->can($method) && next;
> 
>              # create get/setter method
>              no strict 'refs';
>              *{ref($self).'::'.$method} = sub { my $self = shift;
>                                                if (@_) { 
> $self->{'_'.$method} = shift }
>                                                return 
> $self->{'_'.$method} || return; };
>          }
>      }
> 
>      while (my ($method, $value) = each %args) {
>          $method =~ s/^-+//;
>          $method = $methods{lc($method)} || ($methods ? next : $method);
> 
>          unless ($force) {
>              $self->can($method) || next;
>          }
> 
>          $self->$method($value);
>      }
> }
> _______________________________________________
> Bioperl-l mailing list
> Bioperl-l at lists.open-bio.org
> http://lists.open-bio.org/mailman/listinfo/bioperl-l
> 




More information about the Bioperl-l mailing list