On Mon, Oct 12, 2009 at 02:54:05AM -0700, Ovid wrote:
> ----- Original Message ----
>
> > From: Jesse Luehrs <[email protected]>
>
> > > 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