Re: multiple inheritance and instance data?



Peter Scott wrote:
On Thu, 29 Mar 2007 14:12:54 +0100, bugbear wrote:
I would like to have a class which has the behaviour
of 2 more primitive classes.
[...]
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.

It's not that both parent constructors return blessed objects that's the
problem (what else would they do?).

Yeah - I worked that out.


It's whether the parent constructors do anything besides creating empty
blessed hashrefs.

That's why it's a best practice for constructors to create empty objects
and nothing else.

But surely constructors should do "the right and useful" thing - otherwise
what are they for.

Failing that - how/where should "real" construction take place?

You write a constructor in the child that blesses an object into your
child class. Then you have to inspect the constructors of your parents to
see what they're doing. If they both follow best practice, you need do
nothing else. If one of them is well behaved and the other isn't, you can
instead call the constructor on the not-well-behaved one and then rebless
the returned object into your class. If they're both not well behaved,
you probably have to cut and paste.

OK - my invention (while thinking about the issues) was as follows,
which seems to work (i.e. passes all the tests I've tried). I would
welcome comments on style or blatent
bugs/faults I haven't thought of. Essentially I perform
a hash merge on the parent hashes.

BugBear

#!/usr/bin/perl

use strict;
use Data::Dumper;

package A;

sub new {
my ($class, $name) = @_;
my $self = {};
$self->{a} = $name;
bless $self, $class;
return $self;
}

package B;

sub new {
my ($class, $name) = @_;
my $self = {};
$self->{b} = $name;
bless $self, $class;
return $self;
}

package C;
# single inheritance

use vars qw(@ISA);
@ISA = qw (A);

sub new {
my ($class, $name) = @_;
my $self = $class->SUPER::new("from C");

$self->{c} = "c";
bless $self, $class;
return $self;
}

package D;

use vars qw(@ISA);
@ISA = qw (A B);

sub new {
my ($class, $name) = @_;
my $selfa = new A($name);
my $selfb = new B($name);
my %merged = (%$selfa, %$selfb);

my $self = \%merged;
$self->{d} = "d";
bless $self, $class;
return $self;
}
package main;
use Data::Dumper;

my $a = new A("j1");
my $b = new B("j2");
my $c = new C("j3");
my $d = new D("j4");
print Dumper($a, $b, $c, $d);
print Dumper(UNIVERSAL::isa($d, "A"));
print Dumper(UNIVERSAL::isa($d, "B"));
print Dumper(UNIVERSAL::isa($d, "D"));
.



Relevant Pages

  • Re: Threads and OO Question
    ... > " bless is not supported on shared references. ... sub increment { ... package MyPackage; ... my $class = shift; ...
    (comp.lang.perl.misc)
  • Ambiguous method call
    ... (package A::B could as well be required/used separately from a different file without changing the result) ... sub new{ ... my $class = shift; ... Attempt to bless into a reference at A.pm line 18. ...
    (comp.lang.perl.misc)
  • Module questions (perhaps a module creation mini-tutorial)
    ... sub new { ... I get a hash in $_with only one value - the string name of the ... package I am calling. ... Why does bless need an empty hash intialized for it to bless it? ...
    (perl.beginners)
  • Sharing object between threads - howto?
    ... package PlugIn::SuperSnoop; ... sub startThread { ... bless is not supported on shared references. ... bless will only bless the thread local reference and the blessing will not propagate to the other threads. ...
    (comp.lang.perl.misc)
  • Re: Types of constructors
    ... Private mUID As String ... Private Sub New ... the function had full access to the new object's private member fields. ... : What are the other kinds of constructors besides: ...
    (microsoft.public.dotnet.languages.vb)