[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)).
-hlmar
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