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

Chris Fields cjfields at uiuc.edu
Mon Jun 9 19:08:23 UTC 2008


Yes, that works as well.

chris

On Jun 9, 2008, at 1:30 PM, aaron.j.mackey at gsk.com wrote:

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

Christopher Fields
Postdoctoral Researcher
Lab of Dr. Marie-Claude Hofmann
College of Veterinary Medicine
University of Illinois Urbana-Champaign







More information about the Bioperl-l mailing list