in reply to Re^7: Perl "new" command
in thread Perl "new" command
So, you break encapsulation, and will depend on how things are implemented. If you're willing to break encapsulation, why even bother with OO?bless do { my %self = (%{Colour->new($colour)}, %{Age->new($age)}); \% +self }, $class;
The other solution is to go the inside-out object route. If your class doesn't care about the contents of the reference, then all is fine and dandy.Inside-out objects aren't a silver bullet, and won't save the naive programmer.
Packages Colour and Age are written as inside-out objects, but because the same method constructs and initializes the object, the author of Colour_and_Age is screwed. He doesn't even have the luxury of breaking encapsulation.package Colour { use Scalar::Util 'refaddr'; my %colour; sub new { my $o = bless \do{my $var}, $_[0]; $colour{refaddr $o} = $_[1]; $o; } sub colour {$colour{refaddr $_[0]}} }; package Age { use Scalar::Util 'refaddr'; my %age; sub new { my $o = bless \do{my $var}, $_[0]; $age{refaddr $o} = $_[1]; $o; } sub age {$age{refaddr $_[0]}} }; package Colour_and_Age { our @ISA = qw[Age Colour]; use Scalar::Util 'refaddr'; sub new { my ($class, $colour, $age) = @_; ... Now what? ... } }
Now, if one separates object construction and object initialization, for instance:
then one can use multiple inheritance without any problem:use Scalar::Util 'refaddr'; package Colour { use Scalar::Util 'refaddr'; my %colour; sub new {bless \do{my $var}, $_[0]} sub init {$colour{refaddr $_[0]} = $_[1]; $_[0]} sub colour {$colour{refaddr $_[0]}} }; package Age { use Scalar::Util 'refaddr'; my %age; sub new {bless \do{my $var}, $_[0]} sub init {$age{refaddr $_[0]} = $_[1]; $_[0]} sub age {$age{refaddr $_[0]}} };
It only takes a few more keystrokes to create your classes that way, and you aren't robbing any users from using your classes with multiple inheritance. Also note you don't need inside-out objects to separate constructions and initialization.package Colour_and_Age { use Scalar::Util 'refaddr'; our @ISA = qw[Age Colour]; sub new {bless \do{my $var}, $_[0]} sub init ( my ($self, $colour, $age) = @_; $self->Colour::init($colour); $self->Age::init($age); $self; } }; my $o = Colour_and_Age::->new->init(red => 42);
|
---|