[Bioperl-l] Subclassing Bio::Seq ? Extending Bio::Perl

Hilmar Lapp hlapp at gmx.net
Tue Oct 24 16:24:09 UTC 2006

I think you've generally taken the right path, but see below.

First off, object factories are used extensively already but not yet  
in each and every place where Bioperl creates an object internally.  
Achieving your goal may entail fixes to Bioperl to use a factory  
instead of a hard-coded module name. Also be on the lookout for  
factory() or seq_factory() methods for classes whose work entails  
creating sequence objects and that already give you control over the  
type to be created.

The problem that hits you here though isn't one of determining the  
type of the object to be created, because the respective method  
doesn't create a sequence object. It only returns the sequence object  
that the feature has a reference to.

The reason that this is a Bio::PrimarySeq and not a Bio::Seq or your  
extension of the latter is that the Perl garbage collector can't deal  
with circular references. The way we've circumvented the problem with  
sequence (who hold references to their feature objects) and feature  
objects (who need to hold a reference to their sequence object) is to  
make Bio::Seq a wrapper around Bio::PrimarySeq (i.e., Bio::Seq  
implements Bio::PrimarySeqI by delegating all the Bio::PrimarySeqI  
methods to an instance of Bio::PrimarySeq, and then adds  
implementations of the Bio::SeqI methods), and then make feature  
objects only hold a reference to the 'base' Bio::PrimarySeq instance.  
This works because Bio::PrimarySeq doesn't hold features, only  
Bio::SeqI objects do.

Having said all that, note that if all what you want to do is  
defining computations on Bio::Seq objects, as opposed to storing  
values for additional attributes, the best design approach is not to  
extend the class but to create a class with those computations as  
static methods (which would accept the seq object on which to compute  
as an argument; e.g., print $seqComputations->message_digest($seq)).


On Oct 24, 2006, at 10:28 AM, JK ((Jesper Agerbo Krogh)) wrote:

> Hi.
> We're trying to "extend" bioperl in our own setup. We have some  
> funtions
> that we'd like to "allways" have available on a Bio::Seq-object. As an
> example,
> I'd like to have the sequence-digest available on ->digest that just
> returns
> A hex-encoded message-digest of the sequence in the object. This is
> really comfortable
> when trying to figure out wether we've got some computations stored in
> the cache
> for this particular sequence.
> Another example is that we have some fields we want to be mandatory in
> the objects,
> thus adding additional checks in the constructor is nessesary.
> Our approach has been to "subclass" Bio::Seq in a new object:  
> (Nz::Seq)
> and add
> the functionality there. This generally works fine (->translate()  
> calls
> ->can_call_new()
> and instantiates the correct subclassed object.
> But the logic fails when the ->seq of a feature just instantiates a
> Bio::PrimarySeq
> without trying to get the subclassed object.
> So the question basically is:
> What is the preferred way of extending/subclassing Bio-perl -objects
> with
> our own methods?
> Jesper
> _______________________________________________
> Bioperl-l mailing list
> Bioperl-l at lists.open-bio.org
> http://lists.open-bio.org/mailman/listinfo/bioperl-l

: Hilmar Lapp  -:-  Durham, NC  -:-  hlapp at gmx dot net :

More information about the Bioperl-l mailing list