Mention default default in docs
[gitmo/Moose.git] / lib / Moose / Meta / Attribute / Native.pm
1 package Moose::Meta::Attribute::Native;
2
3 our $VERSION   = '1.15';
4 $VERSION = eval $VERSION;
5 our $AUTHORITY = 'cpan:STEVAN';
6
7 my @trait_names = qw(Bool Counter Number String Array Hash Code);
8
9 for my $trait_name (@trait_names) {
10     my $trait_class = "Moose::Meta::Attribute::Native::Trait::$trait_name";
11     my $meta = Class::MOP::Class->initialize(
12         "Moose::Meta::Attribute::Custom::Trait::$trait_name"
13     );
14     if ($meta->find_method_by_name('register_implementation')) {
15         my $class = $meta->name->register_implementation;
16         Moose->throw_error(
17             "An implementation for $trait_name already exists " .
18             "(found '$class' when trying to register '$trait_class')"
19         );
20     }
21     $meta->add_method(register_implementation => sub {
22         # resolve_metatrait_alias will load classes anyway, but throws away
23         # their error message; we WANT to die if there's a problem
24         Class::MOP::load_class($trait_class);
25         return $trait_class;
26     });
27 }
28
29 1;
30
31 __END__
32
33 =pod
34
35 =head1 NAME
36
37 Moose::Meta::Attribute::Native - Delegate to native Perl types
38
39 =head1 SYNOPSIS
40
41   package MyClass;
42   use Moose;
43
44   has 'mapping' => (
45       traits  => ['Hash'],
46       is      => 'rw',
47       isa     => 'HashRef[Str]',
48       default => sub { {} },
49       handles => {
50           exists_in_mapping => 'exists',
51           ids_in_mapping    => 'keys',
52           get_mapping       => 'get',
53           set_mapping       => 'set',
54           set_quantity      => [ set => 'quantity' ],
55       },
56   );
57
58   my $obj = MyClass->new;
59   $obj->set_quantity(10);      # quantity => 10
60   $obj->set_mapping('foo', 4); # foo => 4
61   $obj->set_mapping('bar', 5); # bar => 5
62   $obj->set_mapping('baz', 6); # baz => 6
63
64   # prints 5
65   print $obj->get_mapping('bar') if $obj->exists_in_mapping('bar');
66
67   # prints 'quantity, foo, bar, baz'
68   print join ', ', $obj->ids_in_mapping;
69
70 =head1 DESCRIPTION
71
72 Native delegations allow you to delegate to native Perl data
73 structure as if they were objects. For example, in the L</SYNOPSIS> you can
74 see a hash reference being treated as if it has methods named C<exists()>,
75 C<keys()>, C<get()>, and C<set()>.
76
77 The delegation methods (mostly) map to Perl builtins and operators. The return
78 values of these delegations should be the same as the corresponding Perl
79 operation. Any deviations will be explicitly documented.
80
81 =head1 API
82
83 Native delegations are enabled by passing certain options to C<has> when
84 creating an attribute.
85
86 =head2 traits
87
88 To enable this feature, pass the appropriate name in the C<traits> array
89 reference for the attribute. For example, to enable this feature for hash
90 reference, we include C<'Hash'> in the list of traits.
91
92 =head2 isa
93
94 You will need to make sure that the attribute has an appropriate type. For
95 example, to use this with a Hash you must specify that your attribute is some
96 sort of C<HashRef>.
97
98 If you I<don't> specify a type, each trait has a default type it will use.
99
100 =head2 handles
101
102 This is just like any other delegation, but only a hash reference is allowed
103 when defining native delegations. The keys are the methods to be created in
104 the class which contains the attribute. The values are the methods provided by
105 the associated trait. Currying works the same way as it does with any other
106 delegation.
107
108 See the docs for each native trait for details on what methods are available.
109
110 =head2 default or builder
111
112 Some traits provide a "default default" for historical reasons. This behavior
113 is deprecated, and you are strongly encouraged to provide a default value or
114 make the attribute required.
115
116 =head1 TRAITS FOR NATIVE DELEGATIONS
117
118 =over
119
120 =item L<Array|Moose::Meta::Attribute::Native::Trait::Array>
121
122     has 'queue' => (
123         traits  => ['Array'],
124         is      => 'ro',
125         isa     => 'ArrayRef[Str]',
126         default => sub { [] },
127         handles => {
128             add_item  => 'push',
129             next_item => 'shift',
130             # ...
131         }
132     );
133
134 =item L<Bool|Moose::Meta::Attribute::Native::Trait::Bool>
135
136     has 'is_lit' => (
137         traits  => ['Bool'],
138         is      => 'ro',
139         isa     => 'Bool',
140         default => 0,
141         handles => {
142             illuminate  => 'set',
143             darken      => 'unset',
144             flip_switch => 'toggle',
145             is_dark     => 'not',
146             # ...
147         }
148     );
149
150 =item L<Code|Moose::Meta::Attribute::Native::Trait::Code>
151
152     has 'callback' => (
153         traits  => ['Code'],
154         is      => 'ro',
155         isa     => 'CodeRef',
156         default => sub {
157             sub {'called'}
158         },
159         handles => {
160             call => 'execute',
161             # ...
162         }
163     );
164
165 =item L<Counter|Moose::Meta::Attribute::Native::Trait::Counter>
166
167     has 'counter' => (
168         traits  => ['Counter'],
169         is      => 'ro',
170         isa     => 'Num',
171         default => 0,
172         handles => {
173             inc_counter   => 'inc',
174             dec_counter   => 'dec',
175             reset_counter => 'reset',
176             # ...
177         }
178     );
179
180 =item L<Hash|Moose::Meta::Attribute::Native::Trait::Hash>
181
182     has 'options' => (
183         traits  => ['Hash'],
184         is      => 'ro',
185         isa     => 'HashRef[Str]',
186         default => sub { {} },
187         handles => {
188             set_option => 'set',
189             get_option => 'get',
190             has_option => 'exists',
191             # ...
192         }
193     );
194
195 =item L<Number|Moose::Meta::Attribute::Native::Trait::Number>
196
197     has 'integer' => (
198         traits  => ['Number'],
199         is      => 'ro',
200         isa     => 'Int',
201         default => 5,
202         handles => {
203             set => 'set',
204             add => 'add',
205             sub => 'sub',
206             mul => 'mul',
207             div => 'div',
208             mod => 'mod',
209             abs => 'abs',
210             # ...
211         }
212     );
213
214 =item L<String|Moose::Meta::Attribute::Native::Trait::String>
215
216     has 'text' => (
217         traits  => ['String'],
218         is      => 'ro',
219         isa     => 'Str',
220         default => q{},
221         handles => {
222             add_text     => 'append',
223             replace_text => 'replace',
224             # ...
225         }
226     );
227
228 =back
229
230 =head1 COMPATIBILITY WITH MooseX::AttributeHelpers
231
232 This feature used to be a separated CPAN distribution called
233 L<MooseX::AttributeHelpers>.
234
235 When the feature was incorporated into the Moose core, some of the API details
236 were changed. The underlying capabilities are the same, but some details of
237 the API were changed.
238
239 =head1 BUGS
240
241 See L<Moose/BUGS> for details on reporting bugs.
242
243 =head1 AUTHOR
244
245 Stevan Little E<lt>stevan@iinteractive.comE<gt>
246
247 B<with contributions from:>
248
249 Robert (rlb3) Boone
250
251 Paul (frodwith) Driver
252
253 Shawn (Sartak) Moore
254
255 Chris (perigrin) Prather
256
257 Robert (phaylon) Sedlacek
258
259 Tom (dec) Lanyon
260
261 Yuval Kogman
262
263 Jason May
264
265 Cory (gphat) Watson
266
267 Florian (rafl) Ragwitz
268
269 Evan Carroll
270
271 Jesse (doy) Luehrs
272
273 Jay Hannah
274
275 Robert Buels
276
277 =head1 COPYRIGHT AND LICENSE
278
279 Copyright 2007-2009 by Infinity Interactive, Inc.
280
281 L<http://www.iinteractive.com>
282
283 This library is free software; you can redistribute it and/or modify
284 it under the same terms as Perl itself.
285
286 =cut