6 Moose::Cookbook::Roles::Recipe2 - Advanced Role Composition - method exclusion and aliasing
19 requires 'save_state', 'load_state';
25 package Restartable::ButUnreliable;
28 with 'Restartable' => {
33 -excludes => [ 'stop', 'start' ],
39 $self->explode() if rand(1) > .5;
47 $self->explode() if rand(1) > .5;
52 package Restartable::ButBroken;
55 with 'Restartable' => { -excludes => [ 'stop', 'start' ] };
71 In this example, we demonstrate how to exercise fine-grained control
72 over what methods we consume from a role. We have a C<Restartable>
73 role which provides an C<is_paused> attribute, and two methods,
76 Then we have two more roles which implement the same interface, each
77 putting their own spin on the C<stop> and C<start> methods.
79 In the C<Restartable::ButUnreliable> role, we want to provide a new
80 implementation of C<stop> and C<start>, but still have access to the
81 original implementation. To do this, we alias the methods from
82 C<Restartable> to private methods, and provide wrappers around the
85 Note that aliasing simply I<adds> a name, so we also need to exclude the
86 methods with their original names.
88 with 'Restartable' => {
93 -excludes => [ 'stop', 'start' ],
96 In the C<Restartable::ButBroken> role, we want to provide an entirely
97 new behavior for C<stop> and C<start>. We exclude them entirely when
98 composing the C<Restartable> role into C<Restartable::ButBroken>.
100 It's worth noting that the C<-excludes> parameter also accepts a single
101 string as an argument if you just want to exclude one method.
103 with 'Restartable' => { -excludes => [ 'stop', 'start' ] };
107 Exclusion and renaming are a power tool that can be handy, especially
108 when building roles out of other roles. In this example, all of our
109 roles implement the C<Restartable> role. Each role provides same API,
110 but each has a different implementation under the hood.
112 You can also use the method aliasing and excluding features when
113 composing a role into a class.
121 The mention of wrapper should tell you that we could do the same thing
122 using method modifiers, but for the sake of this example, we don't.
128 Dave Rolsky E<lt>autarch@urth.orgE<gt>
130 =head1 COPYRIGHT AND LICENSE
132 Copyright 2006-2010 by Infinity Interactive, Inc.
134 L<http://www.iinteractive.com>
136 This library is free software; you can redistribute it and/or modify
137 it under the same terms as Perl itself.
142 my $unreliable = Moose::Meta::Class->create_anon_class(
144 roles => [qw/Restartable::ButUnreliable/],
146 explode => sub { }, # nop.
147 'save_state' => sub { },
148 'load_state' => sub { },
151 ok( $unreliable, 'made anon class with Restartable::ButUnreliable role' );
152 can_ok( $unreliable, qw/start stop/ );
157 my $broken = Moose::Meta::Class->create_anon_class(
159 roles => [qw/Restartable::ButBroken/],
161 explode => sub { $cnt++ },
162 'save_state' => sub { },
163 'load_state' => sub { },
167 ok( $broken, 'made anon class with Restartable::ButBroken role' );
171 is( $cnt, 1, '... start called explode' );
175 is( $cnt, 2, '... stop also called explode' );