Excerpts from Ovid's message of Mon Oct 12 11:53:23 -0400 2009:
> So instead of this:
> 
>   package Thing;
>   use Moose;
>   with (
>     DoesRobot => { excludes => 'draw', aliases => { draw => 'draw_with_arm' } 
> },
>     'DoesDrawable'
>   );
> 
> You recommend this:
> 
>   package Thing;
>   use Moose;
>   has robot_arm => (
>     is      => 'ro',
>     isa     => 'RobotArm',
>     default => sub { RobotArm->new({ to_draw => shift }) },
>     handles => { draw_with_arm => 'draw' },
>   );
> 
> This is interesting in a couple of ways.  Aside from the fact that we have 
> more scaffolding code we have to write, we no longer get our
> composition-time safety from 'requires' which roles provide.  With 
> delegation, if $self doesn't provide the methods you need, you get your
> failures at runtime instead of composition time.  This is a problem when 
> delegation requires bi-directional in the sending and receiving
> objects.

The fact that a hammer's no good for washing clothes doesn't mean you can't
still bash nails with it.

  package HasRobot;
  use Moose::Role;
  requires @some_methods; 

  has robot_arm => (
    is => 'ro',
    isa => 'RobotArm',
    lazy => 1,
    default => sub { RobotArm->new({ to_draw => shift }) },
    handles => { draw_with_arm => 'draw' },
  );

(If you don't like hardcoding draw_with_arm, use MooseX::Role::Parameterized to
refactor it.)

Alternately, make a RobotArm::Drawable role that just requires @some_methods.

hdp.

Reply via email to