http://www.perlmonks.org?node_id=11116797

exilepanda has asked for the wisdom of the Perl Monks concerning the following question:

For example, I have Robo class, which subclass from Robo::Arm Robo::Head Robo::Feet at once ( and each has it's own new() constructor ).

After lot of readings, I learned I can use Exporter and then push @ISA, or use base, or parent to obtain methods from other class(modules).

However, if a method is not solely depends on themselves, I mean, the being called method require attributes defined in the class's own constructor to work properly, the tricks of above will not work. The result is that I can access the method, but the method won't work properly.

Is that any trick that you can kick on the constructor ahead, and then calling those parent methods with correct object reference? Thank you very much for any clue.

----------------------------------

Update: Thank you everyone that point out and I am agree that it is not an is-a scenario, but has-a, which is very likely what I am asking, but I have to point out that I do not have enough time to learn Moose at this moment.

Though, here's some code I can demonstrate.

package Robo::Arm; sub new { bless { } , shift } sub pick { print "I am grabbing " . $_[1] } 1; package Robo::Feet; sub new { bless { Position => [11,0] } , shift } sub walk { my $c = shift; my ( $x, $y ) = @{$c->{Position}} ; if ( $x > 10 || $y > 10 ) { print "Out of boundary. I stop walk" } else { print "I start walk from pos $x $y " } } 1; package Robo; use parent -norequire , 'Robo::Arm', 'Robo::Feet'; sub new { bless { Arm => new Robo::Arm(), Feet => new Robo::Feet(), }, shift } 1; package main; my $robo = new Robo; $robo -> pick ( "Apple" ) ; $robo -> walk ;
Now, look at the walk from Feet, that's what I mean, I can access the method, but the method won't run as expected. I expect it won't walk if the init value was considered. So, I have a very clumsy work around

package Robo::Arm; sub new { bless { } , shift } sub pick { print "I am grabbing " . $_[1] } 1; package Robo::Feet; sub new { bless { Position => [11,0] } , shift } sub walk { my $c = shift; my ( $x, $y ) = @{$c->{Position}} ; if ( $x > 10 || $y > 10 ) { print "Out of boundary. I stop walk" } else { print "I start walk at pos $x $y " } } 1; package Robo; sub AUTOLOAD { our $AUTOLOAD ; $AUTOLOAD =~ /([\w]+)$/; my $meth = $1; my $c = shift; my $can = undef; foreach ( keys %$c ) { if ( $c->{$_}->can ( $meth ) ) { eval "\$c->{\$_}->${meth} (\@_) " ; $can++ } } die "There's no $meth method anywhere" unless $can; } sub new { bless { Arm => new Robo::Arm(), Feet => new Robo::Feet(), }, shift } 1; package main; my $robo = new Robo; $robo -> walk ; $robo -> pick ( "Apple" ) ;

And that's what I am trying to ask a better way to do