|
Is there an elegant way to [allow a subclass to control object initialization
of a parent class], while using the inside-out paradigm?
The short answer is 'yes'. However, I really don't think this kind of control
is necessary. In general, if someone felt they really needed to do this, then
my opinion would be that their object design is probably flawed.
For instance, your example doesn't require this kind of control:
package Point; {
use Object::InsideOut;
my @x :Field('Get' => 'getX');
my @y :Field('Get' => 'getY');
my %init_args :InitArgs = (
'x' => {
'Field' => \@x,
'Type' => 'Numeric',
'Mandatory' => 1,
},
'y' => {
'Field' => \@y,
'Type' => 'Numeric',
'Mandatory' => 1,
},
);
}
package Circle
use Object::InsideOut 'Point';
my @radius :Field('Get' => 'getRadius');
my %init_args :InitArgs = (
'radius' => {
'Field' => \@radius,
'Type' => 'Numeric',
'Mandatory' => 1,
},
);
}
package main;
MAIN:
{
my $circle = Circle->new( { 'x' => 3,
'y' => -4.5,
'radius' => 1.2 } );
}
Additionally, you can control which args apply to which classes:
my $circle = Circle->new( {
'Point' => {
'x' => 3,
'y' => -4.5,
},
'Circle' => {
'radius' => 1.2,
}
} );
However, if needed, the subclass could provide its own new() method that is a
wrapper around Object::InsideOut's new() method. This was illustrated in an
earlier thread in this
forum.
Here's your example, coded with such a 'new() wrapper':
package Point; {
use Object::InsideOut;
my @x :Field('Get' => 'getX');
my @y :Field('Get' => 'getY');
my %init_args :InitArgs = (
'x' => {
'Field' => \@x,
'Type' => 'Numeric',
'Mandatory' => 1,
},
'y' => {
'Field' => \@y,
'Type' => 'Numeric',
'Mandatory' => 1,
},
);
}
package Circle
use Object::InsideOut 'Point';
my @radius :Field('Get' => 'getRadius');
my %init_args :InitArgs = (
'radius' => {
'Field' => \@radius,
'Type' => 'Numeric',
'Mandatory' => 1,
},
);
sub new
{
my ($thing, $x, $y, $radius) = @_;
return ($thing->Object::InsideOut::new( { 'x' => $x,
'y' => $y,
'radius' => $radius } );
}
}
package main;
MAIN:
{
my $circle = Circle->new(3, -4.5, 1.2);
}
|