[Bioperl-l] multiple inheritance
Lincoln Stein
lstein at cshl.edu
Tue Sep 9 18:03:00 EDT 2003
I know I'm responding kind of late, but the easiest way to weasle out of this
one is just to explicitly call new() in both parents.
sub new {
my $class = shift;
my $self = $class->B::new(@_);
$self->C::new(@_);
}
Or you can generalize this:
sub new {
my $class = shift;
my $self = $class;
for my $parent (@ISA) {
my $method = "$parent\:\:new";
$self = $self->$method(@_);
}
$self;
}
Note that A will end up being invoked twice (oops) and that the initializer
must be prepared to receive a first argument containing an initialized object
rather than a class name. NEXT will solve the first problem, but not the
second.
Better perhaps would be to separate object creation from initialization in all
classes:
sub new {
my $class = shift;
my $self = bless {},ref $class || $class;
$self->initialize(@_);
}
This way one would never override new() and instead would inherit like this:
sub initialize {
my $self = shift;
for my $parent (@ISA) {
next unless $parent->can('initialize');
my $method = "$parent\:\:initialize";
$self->$method(@_);
}
}
There's probably a clever way to turn this into a method that can be called in
the Bio::Root class. Let's see:
sub initialize_chain {
my $self = shift;
my $package = ref $self;
for my $parent (@{"$package\:\:ISA"}) {
next unless $parent->can('initialize');
my $method = "$parent\:\:initialize";
$self->$method(@_);
}
}
So now we override with:
sub initialize {
my $self = shift;
$self->initialize_chain(@_);
# now do our own initialization
}
A little more work and we can prevent the base class from initializing twice.
Lincoln
On Wednesday 30 July 2003 04:12 pm, Jason Stajich wrote:
> Hmm - how should we solve the multiple inheritance when we want to chain
> both constructors. Using SUPER just goes up the tree and will follow B
> first up to A and never call C's constructor.
>
> package D;
> @ISA = qw(B C);
>
> A
> / \
> B C
> \ /
> D
>
>
> The Right Way* to do this is of course not having multiple inheritance OR
> to use The Damian's NEXT
> http://search.cpan.org/author/DCONWAY/NEXT-0.50/lib/NEXT.pm
>
> We run into this for SeqFeature::SimilarityPair which ISA FeaturePair and
> a Similarity - the soln there was not to rely on the constructor for
> initializing parameters.
>
> I am hitting it again for my Tree::AlleleNode objects which are
> PopGen::Individuals (genotype containers) and Tree::Node (as part of the
> coalescent).
>
> My soln will be to explictly code all the initialization parameters for
> the skipped superclass (C as in above example) as copy+paste
>
> NEXT is part of perl 5.8.0 and would remove a lot of issues wrt to
> chaining destructors that we have some code hacks for in Bio::Root::Root.
> But I am wary of adding another module dependancy.
>
> Comments?
>
> --
> Jason Stajich
> Duke University
> jason at cgt.mc.duke.edu
> _______________________________________________
> Bioperl-l mailing list
> Bioperl-l at portal.open-bio.org
> http://portal.open-bio.org/mailman/listinfo/bioperl-l
--
Lincoln Stein
lstein at cshl.edu
Cold Spring Harbor Laboratory
1 Bungtown Road
Cold Spring Harbor, NY 11724
(516) 367-8380 (voice)
(516) 367-8389 (fax)
More information about the Bioperl-l
mailing list