[Bioperl-l] [Wg-phyloinformatics] Re: phyloXML weekly report

aaron.j.mackey at gsk.com aaron.j.mackey at gsk.com
Mon Jun 9 14:30:22 EDT 2008


How about just:

  $self->${ $self->{lookup}->{tag} }(@args)

i.e., shorthand for:

  $method = $self->{lookup}->{tag}
  $self->$method(@args);

-Aaron

wg-phyloinformatics-bounces at nescent.org wrote on 06/09/2008 02:12:29 PM:

> [cross-posting to bioperl-l for archiving]
> 
> On Jun 8, 2008, at 11:32 PM, Han, Mira wrote:
> 
> > ...
> > issues:
> > There are a lot of <if/elsif>s when processing the elements,
> > I tried to make a hash of function references that point to the 
> > member functions,
> > But when I tried calling it through the hash, it was giving me an 
> > error that I'm trying to call a method on an unblessed object.
> 
> I ran into something similar when setting up a few SeqIO modules 
> (Bio::SeqIO::gbdriver being on of them) which passed on data chunks to 
> method handlers.  It has something to do with how the method is set up 
> in the class (package) namespace and how you refer to it.  It's a 
> little tricky b/c you run into semantic issues with perl's 'hammered- 
> on' OO, but it can be done.
> 
> If you call using '$self->{lookup}->{$tag}->(@args)' directly, what 
> happens is you can successfully call the method since you are still in 
> the proper module namespace.  However, since you aren't calling from 
> the invocant ($self) directly but rather from a reference in the 
> invocant, it treats the call like a subroutine instead of a method. 
> Therefore no invocant is passed as the first argument (you will 
> instead get either the first element in @args or 'undef' assigned to 
> $self within the method).  Not sure if this is supposed to be a 
> feature or a bug.  Regardless, any attempt within the method to do 
> something with $self will result in a 'using an unblessed reference' 
> or 'not a hash reference'.
> 
> There are two solutions, both of which work.  If you have method 
> references stored in a hash table in the invocant:
> 
> $self->{lookup}->{tag1} = \&foo;
> $self->{lookup}->{tag2} = \&bar;
> ....
> 
> you can grab the actual code reference (checking using 'exists') and 
> use it directly on the invocant, but NOT as a code reference.  This 
> acts as a symbolic reference, which is allowed for subroutine and 
> method calls (I think it's supposed to be DWIM-my):
> 
> if (exists $self->{lookup}->{$tag}) {
>      my $method = $self->{lookup}->{$tag};
>      $self->$method(@args);
> } else {...}
> 
> The above also works if you use strings in the lookup table which 
> contain the name of the methods (again, symbolic reference):
> 
> $self->{lookup}->{tag1} = 'foo';
> $self->{lookup}->{tag2} = 'bar';
> 
> Alternately, you can pass the invocant in explicitly (which looks 
> weird to me, hence my above solution):
> 
> if (exists $self->{lookup}->{$tag}) {
>      $self->{lookup}->{$tag}->($self, @args);
> } else {...}
> 
> perl6 fixes a lot of these issues, but of course it won't be out for a 
> while longer.
> 
> > I'd like to figure out how to do it,
> > But before that, is hashing really better than lots of if-elses?
> 
> Using a stack of if-elsifs isn't as efficient as a lookup since you 
> would test each case in succession (so something that is further down 
> the if-elseif test stack would have passed through and failed each 
> previous test case before success).  A lookup table would test simply 
> based on the existence of a value stored under a key (tag).
> 
> An alternative is to use 5.10 features (smart matching and given-when, 
> which is like a switch statement), but that will limit usage for those 
> still using 5.8.8, which is probably a majority of users, since 5.10 
> came out just last December.
> 
> chris
> 
> >
> >
> > Mira
> >
> >
> >
> > On 6/2/08 10:29 AM, "Han, Mira" <mirhan at indiana.edu> wrote:
> >
> >
> >
> > Last week (May 26-30):
> > 1. made skeleton files for TreeIO:: PhyloEventBuilder, 
> > TreeIO::phyloXML, Tree::NodePhyloXML
> > 2. managed to connect and load them up but there is a bus error 
> > problem.
> > I think it's probably due to some of the function calls that I'm 
> > making
> > That I haven't looked into properly. I'm suspecting it will go away 
> > once I properly
> > build in the end_element for <clade>
> >
> > This week (Jun 2-6):
> > 1. implement start_element, and end_element for <phylogeny> and 
> > <clade>
> > -    start_element: <phylogeny>: add treelevel, <clade>: push data 
> > to current_items.
> > -    end_element: <phylogeny>: minus treelevel, <clade>: pop data 
> > from current_elements, use new() to build node from popped data.
> > 2. get rid of that bus error
> > 3. TreeIO::phyloXML::Next_tree() : look for element </phylogeny>
> > _______________________________________________
> > Wg-phyloinformatics mailing list
> > Wg-phyloinformatics at nescent.org
> > https://lists.nescent.org/mailman/listinfo/wg-phyloinformatics
> 
> Christopher Fields
> Postdoctoral Researcher
> Lab of Dr. Marie-Claude Hofmann
> College of Veterinary Medicine
> University of Illinois Urbana-Champaign
> 
> 
> 
> 
> _______________________________________________
> Wg-phyloinformatics mailing list
> Wg-phyloinformatics at nescent.org
> https://lists.nescent.org/mailman/listinfo/wg-phyloinformatics
> 




More information about the Bioperl-l mailing list