Moose > Moose::Cookbook::Roles::Recipe3

題名

Moose::Cookbook::Roles::Recipe3 - オブジェクトのインスタンスにロールを組み込む

概要

  package MyApp::Role::Job::Manager;

  use List::Util qw( first );

  use Moose::Role;

  has 'employees' => (
      is  => 'rw',
      isa => 'ArrayRef[Employee]',
  );

  sub assign_work {
      my $self = shift;
      my $work = shift;

      my $employee = first { !$_->has_work } @{ $self->employees };

      die 'All my employees have work to do!' unless $employee;

      $employee->work($work);
  }

  package main;

  my $lisa = Employee->new( name => 'Lisa' );
  MyApp::Role::Job::Manager->meta->apply($lisa);

  my $homer = Employee->new( name => 'Homer' );
  my $bart  = Employee->new( name => 'Bart' );
  my $marge = Employee->new( name => 'Marge' );

  $lisa->employees( [ $homer, $bart, $marge ] );
  $lisa->assign_work('mow the lawn');

本文

このレシピではオブジェクトにロールを組み込む方法を紹介します。この例では、ひとりの従業員にマネージャーの職責を与えています。

ロールをオブジェクトに組み込む方法は簡単です。Moose::Meta::Roleオブジェクトが提供しているapplyというメソッドにオブジェクトのインスタンスを渡せば、あとはよきに計らってくれます。

  MyApp::Role::Job::Manager->meta->apply($lisa);

また、Moose::Utilapply_all_roles関数を使う手もあります。

  apply_all_roles( $person, MyApp::Role::Job::Manager->meta );

apply_all_rolesを使う主な利点は、一度に複数のロールを組み込めるということです。

組み込もうとしているロールにパラメータを渡すこともできます。

  MyApp::Role::Job::Manager->meta->apply(
      $lisa,
      -alias => { assign_work => 'get_off_your_lazy_behind' },
  );

メソッドの排除や別名の動作についてはロールのレシピ2で例を見ました。

まとめ

オブジェクトのインスタンスにロールを組み込むやり方は、既存のオブジェクトに振る舞いを追加したくなったときに便利です。今回の例では、これを効果的に利用して昇進をモデリングしました。

また、これは既存の、特にMooseを使っていないコードにある種の控えめなモンキーパッチをあてるときにも便利です。たとえばデバッグ用のロールを作って、実行時にオブジェクトに組み込むようなこともできるかもしれません。

作者

Dave Rolsky <autarch@urth.org>

コピーライト & ライセンス

Copyright 2006-2009 by Infinity Interactive, Inc.

http://www.iinteractive.com

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.