Commit | Line | Data |
c79239a2 |
1 | package Moose::Cookbook::Roles::Recipe3; |
9a823f26 |
2 | |
3 | =pod |
4 | |
5547fba7 |
5 | =begin testing-SETUP |
c79239a2 |
6 | |
7 | { |
8 | # Not in the recipe, but needed for writing tests. |
9 | package Employee; |
10 | |
11 | use Moose; |
12 | |
13 | has 'name' => ( |
14 | is => 'ro', |
15 | isa => 'Str', |
16 | required => 1, |
17 | ); |
18 | |
19 | has 'work' => ( |
20 | is => 'rw', |
21 | isa => 'Str', |
22 | predicate => 'has_work', |
23 | ); |
24 | } |
25 | |
5547fba7 |
26 | =end testing-SETUP |
c79239a2 |
27 | |
9a823f26 |
28 | =head1 NAME |
29 | |
30 | Moose::Cookbook::Roles::Recipe3 - Applying a role to an object instance |
31 | |
32 | =head1 SYNOPSIS |
33 | |
34 | package MyApp::Role::Job::Manager; |
35 | |
36 | use List::Util qw( first ); |
37 | |
38 | use Moose::Role; |
39 | |
40 | has 'employees' => ( |
41 | is => 'rw', |
42 | isa => 'ArrayRef[Employee]', |
43 | ); |
44 | |
45 | sub assign_work { |
46 | my $self = shift; |
47 | my $work = shift; |
48 | |
49 | my $employee = first { !$_->has_work } @{ $self->employees }; |
50 | |
51 | die 'All my employees have work to do!' unless $employee; |
52 | |
c79239a2 |
53 | $employee->work($work); |
9a823f26 |
54 | } |
55 | |
56 | package main; |
57 | |
58 | my $lisa = Employee->new( name => 'Lisa' ); |
59 | MyApp::Role::Job::Manager->meta->apply($lisa); |
60 | |
61 | my $homer = Employee->new( name => 'Homer' ); |
62 | my $bart = Employee->new( name => 'Bart' ); |
63 | my $marge = Employee->new( name => 'Marge' ); |
64 | |
65 | $lisa->employees( [ $homer, $bart, $marge ] ); |
66 | $lisa->assign_work('mow the lawn'); |
67 | |
68 | =head1 DESCRIPTION |
69 | |
70 | In this recipe, we show how a role can be applied to an object. In |
71 | this specific case, we are giving an employee managerial |
72 | responsibilities. |
73 | |
74 | Applying a role to an object is simple. The L<Moose::Meta::Role> |
75 | object provides an C<apply> method. This method will do the right |
76 | thing when given an object instance. |
77 | |
78 | MyApp::Role::Job::Manager->meta->apply($lisa); |
79 | |
80 | We could also use the C<apply_all_roles> function from L<Moose::Util>. |
81 | |
82 | apply_all_roles( $person, MyApp::Role::Job::Manager->meta ); |
83 | |
84 | The main advantage of using C<apply_all_roles> is that it can be used |
85 | to apply more than one role at a time. |
86 | |
87 | We could also pass parameters to the role we're applying: |
88 | |
89 | MyApp::Role::Job::Manager->meta->apply( |
90 | $lisa, |
91 | alias => { assign_work => 'get_off_your_lazy_behind' }, |
92 | ); |
93 | |
94 | We saw examples of how method exclusion and alias working in L<roles |
95 | recipe 2|Moose::Cookbook::Roles::Recipe2>. |
96 | |
97 | =head1 CONCLUSION |
98 | |
99 | Applying a role to an object instance is a useful tool for adding |
100 | behavior to existing objects. In our example, it is effective used to |
101 | model a promotion. |
102 | |
103 | It can also be useful as a sort of controlled monkey-patching for |
104 | existing code, particularly non-Moose code. For example, you could |
105 | create a debugging role and apply it to an object at runtime. |
106 | |
107 | =head1 AUTHOR |
108 | |
109 | Dave Rolsky E<lt>autarch@urth.orgE<gt> |
110 | |
111 | =head1 COPYRIGHT AND LICENSE |
112 | |
113 | Copyright 2006-2009 by Infinity Interactive, Inc. |
114 | |
115 | L<http://www.iinteractive.com> |
116 | |
117 | This library is free software; you can redistribute it and/or modify |
118 | it under the same terms as Perl itself. |
119 | |
c79239a2 |
120 | |
121 | =begin testing |
122 | |
123 | { |
124 | my $lisa = Employee->new( name => 'Lisa' ); |
125 | MyApp::Role::Job::Manager->meta->apply($lisa); |
126 | |
127 | my $homer = Employee->new( name => 'Homer' ); |
128 | my $bart = Employee->new( name => 'Bart' ); |
129 | my $marge = Employee->new( name => 'Marge' ); |
130 | |
131 | $lisa->employees( [ $homer, $bart, $marge ] ); |
132 | $lisa->assign_work('mow the lawn'); |
133 | |
134 | ok( $lisa->does('MyApp::Role::Job::Manager'), |
135 | 'lisa now does the manager role' ); |
136 | |
137 | is( $homer->work, 'mow the lawn', |
138 | 'homer was assigned a task by lisa' ); |
139 | } |
140 | |
141 | =end testing |
142 | |
9a823f26 |
143 | =cut |