On Mon, Oct 12, 2009 at 02:54:05AM -0700, Ovid wrote: > ----- Original Message ---- > > > From: Jesse Luehrs <d...@tozt.net> > > > > package Thing; > > > use Moose; > > > with ( > > > DoesRobot => { excludes => 'draw', aliases => { draw => > > > 'draw_with_arm' }, > > > 'DoesDrawable' > > > ); > > > > Again, if the robot was a delegate rather than a role, you'd have > > $thing->draw_with_arm delegated to $thing->robot_arm->draw, but > > $thing->robot_arm->draw would still be available to be called > > separately: > > > > package Thing; > > use Moose; > > with 'DoesDrawable'; > > > > has robot_arm => ( > > is => 'ro', > > isa => 'RobotArm', > > default => { RobotArm->new }, > > handles => { draw_with_arm => 'draw' }, > > ); > > I've been trying to write up a response to this and I note that the > delegation example isn't equivalent. Consider the following code: > > #!/usr/bin/perl > > { > package RobotArm; > use Moose; > use Data::Dumper; > sub draw { print STDERR Dumper( \...@_ ); } > } > { > package Thing; > use Moose; > has robot_arm => ( > is => 'ro', > isa => 'RobotArm', > default => sub { RobotArm->new }, > handles => { draw_with_arm => 'draw' }, > ); > } > my $thing = Thing->new; > $thing->draw_with_arm; > > That will print out: > > $VAR1 = [ > bless( {}, 'RobotArm' ) > ]; > > In short, the robot arm doesn't know what to draw because the original > invocant is not passed. How is this handled in Moose? I assume it's a > matter of somehow passing the invocant to the default?
Yeah, something like this would work: package Thing; use Moose; has robot_arm => ( is => 'ro', isa => 'RobotArm', default => sub { my $self = shift; return RobotArm->new(to_draw => $self); }, handles => { draw_with_arm => 'draw' }, ); -doy