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

Reply via email to