Abstracts
[gitmo/MooseX-Role-Parameterized.git] / lib / MooseX / Role / Parameterized / Tutorial.pm
1 package MooseX::Role::Parameterized::Tutorial;
2 confess "Don't use this module, read it!";
3
4 # ABSTRACT: why and how
5
6 __END__
7
8 =head1 MOTIVATION
9
10 Roles are composable units of behavior. They are useful for factoring out
11 functionality common to many classes from any part of your class hierarchy.See
12 L<Moose::Cookbook::Roles::Recipe1> for an introduction to L<Moose::Role>.
13
14 While combining roles affords you a great deal of flexibility, individual roles
15 have very little in the way of configurability.  Core Moose provides C<alias>
16 for renaming methods to avoid conflicts, and C<excludes> for ignoring methods
17 you don't want or need (see L<Moose::Cookbook::Roles::Recipe2> for more
18 about C<alias> and C<excludes>).
19
20 Because roles serve many different masters, they usually provide only the least
21 common denominator of functionality. Not all consumers of a role have a C<>.
22 Thus, more configurability than C<alias> and C<excludes> is required. Perhaps
23 your role needs to know which method to call when it is done. Or what default
24 value to use for its url attribute.
25
26 Parameterized roles offer exactly this solution.
27
28 =head1 USAGE
29
30 =head3 C<with>
31
32 The syntax of a class consuming a parameterized role has not changed from the
33 standard C<with>. You pass in parameters just like you pass in C<alias> and
34 C<excludes> to ordinary roles:
35
36     with 'MyRole::InstrumentMethod' => {
37         method_name => 'dbh_do',
38         log_to      => 'query.log',
39     };
40
41 =head3 C<parameter>
42
43 Inside your parameterized role, you specify a set of parameters. This is
44 exactly like specifying the attributes of a class. Instead of C<has> you use
45 the keyword C<parameter>, but your parameters can use any options to C<has>.
46
47     parameter 'delegation' => (
48         is        => 'ro',
49         isa       => 'HashRef|ArrayRef|RegexpRef',
50         predicate => 'has_delegation',
51     );
52
53 Behind the scenes, C<parameter> uses C<has> to add attributes to a parameter
54 class. The arguments to C<with> are used to construct a parameter object, which
55 has the attributes specified by calls to C<parameter>. The parameter object is
56 then passed to...
57
58 =head3 C<role>
59
60 C<role> takes a block of code that will be used to generate your role with its
61 parameters bound. Here is where you put your regular role code: use C<has>,
62 method modifiers, and so on. You receive as an argument the parameter object
63 constructed by C<with>. You can access the parameters just like regular
64 attributes on that object (assuming you declared them readable).
65
66 Each time you compose this parameterized role, the role {} block will be
67 executed. It will receive a new parameter object and produce an entirely new
68 role.
69
70 Due to limitations inherent in Perl, you must declare methods with
71 C<method name => sub { ... }> instead of the usual C<sub name { ... }>. Your
72 methods may, of course, close over the parameter object. This means that your
73 methods may use parameters however they wish!
74
75 =head1 IMPLEMENTATION NOTES
76
77 =head1 USES
78
79 Ideally these will become fully-explained examples in something resembling
80 L<Moose::Cookbook>. But for now, only a braindump.
81
82 =over 4
83
84 =item Configure a role's attributes
85
86 You can rename methods with core Moose, but now you can rename attributes. You
87 can now also choose type, default value, whether it's required, B<traits>, etc.
88
89     parameter traits => (
90         is      => 'ro',
91         isa     => 'ArrayRef[Str]',
92         default => sub { [] },
93     );
94
95     has action => (
96         traits => $p->traits,
97         ...
98     );
99
100 =item Inform a role of your class' attributes and methods
101
102 Core roles can require only methods with specific names. Now your roles can
103 require that you specify a method name you wish the role to instrument, or
104 which attributes to dump to a file.
105
106     parameter instrument_method => (
107         is       => 'ro',
108         isa      => 'Str',
109         required => 1,
110     );
111
112     around $p->instrument_method => sub { ... };
113
114 =item Arbitrary execution choices
115
116 Your role may be able to provide configuration in how the role's methods
117 operate. For example, you can tell the role whether to save intermediate
118 states.
119
120     parameter save_intermediate => (
121         is      => 'ro',
122         isa     => 'Bool',
123         default => 0,
124     );
125
126     method process => sub {
127         ...
128         if ($p->save_intermediate) { ... }
129         ...
130     };
131
132 =item Deciding a backend
133
134 Your role may be able to freeze and thaw your instances using L<YAML>, L<JSON>,
135 L<Storable>. Which backend to use can be a parameter.
136
137     parameter format => (
138         is => 'ro',
139         isa => (enum ['Storable', 'YAML', 'JSON']),
140         default => 'Storable',
141     );
142
143     if ($p->format eq 'Storable') {
144         method freeze => sub { ... };
145         method thaw   => sub { ... };
146     }
147     elsif ($p->format eq 'YAML') ...
148     ...
149
150 =back
151
152 =cut
153