Object-InsideOut - Re: Subclass Controlling Superclass Initialization

Posted on Sat Jan 14 06:26:31 2006 by jdhedden in response to 1622 (See the whole thread of 2)
Re: Subclass Controlling Superclass Initialization
    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); }
Write a response