File: Style.pod

package info (click to toggle)
libmoose-perl 0.54-1
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 1,496 kB
  • ctags: 448
  • sloc: perl: 15,125; makefile: 10
file content (202 lines) | stat: -rw-r--r-- 5,670 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
=pod

=head1 NAME

Moose::Cookbook::Style - The latest in trendy Moose cuisine

=for authors

Please annotate all bad examples with comments so that they won't be copied by accodent

=cut

=head1 Benefits of Good Style

Good Moose style, as defined by this document, helps ensure your code has the
following desirable properties:

=over 4

=item Play well with others

Your code will be more reusable and easier to extend.

=item Ease maintenance

The code will be easier to understand because it follows an accepted set of
conventions and idioms.

This will help others maintaining your code, and also help you to get support
on IRC for instance.

=item Help Moose generate better code

By using the most appropriate features, the generated code will be safer and
more efficient.

=item Benefit from meta programming

Code that operates on the metaclass will benefit from clean meta definitions.

If you are manually converting argument types with C<around 'new'> there is no
meta data explaining your intention. If on the other hand you use coercions,
there is introspectable meta data that makes this clear.

This means that e.g. MooseX extensions that work by introspecting your class
will be able to do the right thing more often, because they don't need to
guess.

=back

=head1 Don't change C<new>

It is generally considered bad style to override L<Moose::Object/new> for a
number of reasons.

The first reason is consistency. Subclasses of your class and code
instantiating your class would be simpler if your constructor works closer to
the default.

The second reason is performance. By calling C<make_immutable> on your metaclass:

    __PACKAGE__->meta->make_immutable;

And opting out of any class definition changes from that point on, you allow
Moose to create more efficient versions of certain generic methods. Moose will
generate a tight, optimal C<new> for you, based on the minimal set of features
you use.

Moose provides many features that allow you to do common object construction
tasks at the right level of abstraction.

When attributes have the ability to provide the necessary functionality, use
that. If that isn't sufficient, L<Moose::Object> has numerous features you can
use at construction time.

=head2 Use C<BUILD> instead of custom initialization or overriding C<new>

Instead of changing C<new>, do initialization in C<BUILD>.

The construction parameters are passed in, so you don't need to replicate
C<BUILDARGS>, and since C<BUILD> is called for each superclass that defines it,
you will never forget to invoke your initializers if you extend them.

=head2 Use C<default>, C<builder> or C<lazy_build>

To initialize attributes there is a plethora of methods preferable to assigning
the value at initialization time.

If you want to translate parameter data, use coercions.

If you want to ensure a parameter can't be overridden by the constructor, set
the C<init_arg> to C<undef> instead of overwriting it in C<BUILD>.

=head2 Use C<BUILDARGS> to alter C<@_> processing

If you need to change the way L<@_> is processed, use C<BUILDARGS>, instead of
wrapping C<new>. This ensures the behavior is subclassible, it keeps this logic
independent of the other aspects of construction, and can be made efficient
using C<make_immutable>.

=head1 Don't pollute the global type registry

=head2 Use fully qualified type names for your own data

L<MooseX::Types> provides a convenient method to do this.

If you define

    # Bad style:

    subtype Person => (
        as 'Object',
        where { $_->can("name") },
    );

Then the global name C<Person> is registered, and this could conflict with
other bad usage of the sort.

Instead, prefix type name with your project namespace, or class name:   

    subtype 'My::Foo::Person' => (
        as 'Object',
        where { $_->can("name") },
    );

Or with L<MooseX::Types>:

    use MooseX::Types::Moose qw(Object);

    use MooseX::Types (
        -declare => [qw(Person)],
    );
    
    subtype Person() => ( # note parenthesis, "Person" is a function, not a string
        as Object, # MooseX::Types::Moose exported it
        where { $_->can("name") },
    );

=head3 Coerce in a subtype

Likewise use fully qualified subtypes of other types for defining coercions, so
that they won't affect unrelated code, causing action at a distance.

This is important because the type registry is global, kind of like the symbol
table.

This means that code like:

    # Bad style:

    coerce ArrayRef => (
        from Str => via { [ split /,/ ] },
    );

Will add a coercion to B<all> attributes like:

    has foo => (
        isa => "ArrayRef",
        coerce => 1,
    );

in a specific way.

=head1 Clean up your package

Use C<namespace::clean> or C<no Moose> to remove the sugar exports.

This will make sure the sugar isn't accidentally called as methods on your objects.

For instance:

    $obj->can("has");

will return true, even though C<has> is not a method.

=head1 Accept no substitutes

By substitutes I mean hacks instead of "proper" solutions.

When you have a tricky requirement, refrain from abusing Moose or MooseX:: or
whatever it is you are using.

Instead, drop by IRC and discuss it. Most of the time a crazy idea can either
be simplified, or it will spawn a clean, reliable feature to whatever package
you are using.

This will improve your code and also share the benefit with others.

=head1 AUTHOR

Yuval (nothingmuch) Kogman

=head1 COPYRIGHT AND LICENSE

Copyright 2006-2008 by Infinity Interactive, Inc.

L<http://www.iinteractive.com>

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

=cut