[Bioperl-l] multiple inheritance
Lincoln Stein
lstein at cshl.edu
Tue Sep 9 18:45:22 EDT 2003
OK, here's my solution to this particular problem. The inheritance
hierarchy is:
A
/\
B C
\/
D
|
E
Here's the test script:
use E;
my $a1 = A->new(qw(A initialization stuff));
print "\n";
my $b1 = B->new(qw(B initialization stuff));
print "\n";
my $c1 = C->new(qw(C initialization stuff));
print "\n";
my $d1 = D->new(qw(D initialization stuff));
print "\n";
my $e1 = E->new(qw(E initialization stuff));
print "\n";
And here's its output:
A: initializing a A=HASH(0x8124394) with A initialization stuff
A: initializing a B=HASH(0x81244cc) with B initialization stuff
B: initializing a B=HASH(0x81244cc) with B initialization stuff
A: initializing a C=HASH(0x813b2c4) with C initialization stuff
C: initializing a C=HASH(0x813b2c4) with C initialization stuff
A: initializing a D=HASH(0x813b324) with D initialization stuff
B: initializing a D=HASH(0x813b324) with D initialization stuff
C: initializing a D=HASH(0x813b324) with D initialization stuff
D: initializing a D=HASH(0x813b324) with D initialization stuff
A: initializing a E=HASH(0x813b378) with E initialization stuff
B: initializing a E=HASH(0x813b378) with E initialization stuff
C: initializing a E=HASH(0x813b378) with E initialization stuff
D: initializing a E=HASH(0x813b378) with E initialization stuff
E: initializing a E=HASH(0x813b378) with E initialization stuff
As shown in the attached code, there's some magic in base class A that
causes chaining to occur and avoids initialization from occurring
more than once per class per object. Each subclass has an initialization
method that looks like this:
sub initialize {
my $self = shift;
$self->initialize_chain(@_);
# do own initialization
}
Lincoln
# ------------------------
# FILE: A.pm
# ------------------------
package A;
our %seenit;
sub new {
my $class = shift;
my $self = bless {},ref $class || $class;
$self->initialize(@_);
$self;
}
sub initialize {
my $self = shift;
warn __PACKAGE__ . ": initializing a $self with @_\n";
}
sub initialize_chain {
my $self = shift;
local %seenit unless %seenit;
$self->_initialize_chain(@_);
}
sub _initialize_chain {
my $self = shift;
my $package = caller(1);
for my $parent (@{"$package\:\:ISA"}) {
next if $seenit{$parent}++;
next unless $parent->can('initialize');
$initialize = "$parent\:\:initialize";
$self->$initialize(@_);
}
}
1;
# ------------------------
# FILE: B.pm
# ------------------------
package B;
use base 'A';
sub initialize {
my $self = shift;
$self->initialize_chain(@_);
warn __PACKAGE__ . ": initializing a $self with @_\n";
}
1;
# ------------------------
# FILE: C.pm
# ------------------------
package C;
use base 'A';C
sub initialize {
my $self = shift;
$self->initialize_chain(@_);
warn __PACKAGE__ . ": initializing a $self with @_\n";
}
1;
# ------------------------
# FILE: D.pm
# ------------------------
package D;
use base 'B','C';
sub initialize {
my $self = shift;
$self->initialize_chain(@_);
warn __PACKAGE__ . ": initializing a $self with @_\n";
}
1;
# ------------------------
# FILE: E.pm
# ------------------------
package E;
use base 'D';
sub initialize {
my $self = shift;
$self->initialize_chain(@_);
warn __PACKAGE__ . ": initializing a $self with @_\n";
}
1;
--
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