Re: multiple inheritance and instance data?



bugbear (bugbear@xxxxxxxxxxxxxxxxxxxxxxxxx) wrote on MMMMCMLVIII
September MCMXCIII in <URL:news:460bbb56$0$8741$ed2619ec@xxxxxxxxxxxxxxxxxxxxxxxxxx>:
== I would like to have a class which has the behviour
== of 2 more primitive classes.
==
== I have read up on inheritance, and constructors.
==
== I understand how the @ISA tree is traversed
== to find methods.
==
== http://perldoc.perl.org/perltoot.html
==
== But I can't see, if BOTH parent classes
== have constructors that return a blessed
== object (e.g. a the typical hash reference),
== what I'm meant to do in my child
== class.
==
== I think I'm just in trouble,
== and that I'm up against a reasonable
== limitation of Perl's object modelling,
== but I would welcome any help
== or insight.


You are spot on.

And if you cannot control the implementation of the two classes you
want to inherit from, than chances are, you cannot do it.

Because most Perl programmers will *CONFIGURE* objects inside *CONSTRUCTORS*.


Which is bad.

Worse than using global variables.


Worse then leaving strict off.


Worse than using goto.


Worse than using Java.


Because with goto, and without strict, and with using global variables,
you can still write useable, reusable code. You can even write reusable
code in Java.





If you configure your objects in your constructor, you're a bad citizen.
Your code cannot be fully reused.





The answer: use inside-out objects, and don't configure your objects
inside the constructor.


Something like this (untested, will not even compile):


{
package Parent1;
use Scalar::Util 'refaddr';

my @ATTRIBUTES = \my (
%attr1,
%attr2,
);

sub DESTROY {
my $key = refaddr (my $self = shift);
delete $$_ {$key} for @ATTRIBUTES;
}

sub new {bless \do {my $var} => shift}

sub init {
my $key = refaddr (my $self = shift);
$attr1 {$key} = ...;
$attr2 {$key} = ...;
$self;
}

...
}

{
package Parent2;
use Scalar::Util 'refaddr';

my @ATTRIBUTES = \my (
%attr3,
%attr4,
);

sub DESTROY {
my $key = refaddr (my $self = shift);
delete $$_ {$key} for @ATTRIBUTES;
}

sub new {bless \do {my $var} => shift}

sub init {
my $key = refaddr (my $self = shift);
$attr3 {$key} = ...;
$attr4 {$key} = ...;
$self;
}

...
}

{
package Base;
use Scalar::Util 'refaddr';

our @ISA = qw [Parent1 Parent2];

my @ATTRIBUTES = \my (
%attr5,
%attr6,
);

sub DESTROY {
my $key = refaddr (my $self = shift);
delete $$_ {$key} for @ATTRIBUTES;
$self -> "${_}::DESTROY" for @ISA;
}

sub new {bless \do {my $var} => shift}

sub init {
my $key = refaddr (my $self = shift);

$self -> Parent1::init (...);
$self -> Parent2::init (...);
$attr5 {$key} = ...;
$attr6 {$key} = ...;
$self;
}
}



Abigail
--
package Just_another_Perl_Hacker; sub print {($_=$_[0])=~ s/_/ /g;
print } sub __PACKAGE__ { &
print ( __PACKAGE__)} &
__PACKAGE__
( )
.