WIP: Add a Code attribute helper.
[gitmo/Moose.git] / lib / Moose / Meta / Attribute / Native.pm
1 package Moose::Meta::Attribute::Native;
2
3 our $VERSION   = '0.89_02';
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 - Extend your attribute interfaces
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
59   # ...
60
61   my $obj = MyClass->new;
62   $obj->set_quantity(10);      # quantity => 10
63   $obj->set_mapping('foo', 4); # foo => 4
64   $obj->set_mapping('bar', 5); # bar => 5
65   $obj->set_mapping('baz', 6); # baz => 6
66
67
68   # prints 5
69   print $obj->get_mapping('bar') if $obj->exists_in_mapping('bar');
70
71   # prints 'quantity, foo, bar, baz'
72   print join ', ', $obj->ids_in_mapping;
73
74 =head1 DESCRIPTION
75
76 While L<Moose> attributes provide a way to name your accessors, readers,
77 writers, clearers and predicates, this set of traits provides commonly
78 used attribute helper methods for more specific types of data.
79
80 As seen in the L</SYNOPSIS>, you specify the data structure via the
81 C<trait> parameter. Available traits are below; see L</METHOD PROVIDERS>.
82
83 This module used to exist as the L<MooseX::AttributeHelpers> extension. It was
84 very commonly used, so we moved it into core Moose. Since this gave us a chance
85 to change the interface, you will have to change your code or continue using
86 the L<MooseX::AttributeHelpers> extension. L<MooseX::AttributeHelpers> should
87 continue to work.
88
89 =head1 PARAMETERS
90
91 =head2 handles
92
93 This is like C<< handles >> in L<Moose/has>, but only HASH references are
94 allowed.  Keys are method names that you want installed locally, and values are
95 methods from the method providers (below).  Currying with delegated methods
96 works normally for C<< handles >>.
97
98 =head1 METHOD PROVIDERS
99
100 =over
101
102 =item L<Number|Moose::Meta::Attribute::Native::Trait::Number>
103
104 Common numerical operations.
105
106     has 'integer' => (
107         traits    => ['Number'],
108         is        => 'ro',
109         isa       => 'Int',
110         default   => 5,
111         handles   => {
112             set => 'set',
113             add => 'add',
114             sub => 'sub',
115             mul => 'mul',
116             div => 'div',
117             mod => 'mod',
118             abs => 'abs',
119         }
120     );
121
122 =item L<String|Moose::Meta::Attribute::Native::Trait::String>
123
124 Common methods for string operations.
125
126     has 'text' => (
127         traits    => ['String'],
128         is        => 'rw',
129         isa       => 'Str',
130         default   => q{},
131         handles   => {
132             add_text     => 'append',
133             replace_text => 'replace',
134         }
135     );
136
137 =item L<Counter|Moose::Meta::Attribute::Native::Trait::Counter>
138
139 Methods for incrementing and decrementing a counter attribute.
140
141     has 'counter' => (
142         traits    => ['Counter'],
143         is        => 'ro',
144         isa       => 'Num',
145         default   => 0,
146         handles   => {
147             inc_counter   => 'inc',
148             dec_counter   => 'dec',
149             reset_counter => 'reset',
150         }
151     );
152
153 =item L<Bool|Moose::Meta::Attribute::Native::Trait::Bool>
154
155 Common methods for boolean values.
156
157     has 'is_lit' => (
158         traits    => ['Bool'],
159         is        => 'rw',
160         isa       => 'Bool',
161         default   => 0,
162         handles   => {
163             illuminate  => 'set',
164             darken      => 'unset',
165             flip_switch => 'toggle',
166             is_dark     => 'not',
167         }
168     );
169
170 =item L<Hash|Moose::Meta::Attribute::Native::Trait::Hash>
171
172 Common methods for hash references.
173
174     has 'options' => (
175         traits    => ['Hash'],
176         is        => 'ro',
177         isa       => 'HashRef[Str]',
178         default   => sub { {} },
179         handles   => {
180             set_option => 'set',
181             get_option => 'get',
182             has_option => 'exists',
183         }
184     );
185
186 =item L<Array|Moose::Meta::Attribute::Native::Trait::Array>
187
188 Common methods for array references.
189
190     has 'queue' => (
191        traits     => ['Array'],
192        is         => 'ro',
193        isa        => 'ArrayRef[Str]',
194        default    => sub { [] },
195        handles    => {
196            add_item  => 'push',
197            next_item => 'shift',
198        }
199     );
200
201 =back
202
203 =head1 BUGS
204
205 All complex software has bugs lurking in it, and this module is no
206 exception. If you find a bug please either email me, or add the bug
207 to cpan-RT.
208
209 =head1 AUTHOR
210
211 Stevan Little E<lt>stevan@iinteractive.comE<gt>
212
213 B<with contributions from:>
214
215 Robert (rlb3) Boone
216
217 Paul (frodwith) Driver
218
219 Shawn (Sartak) Moore
220
221 Chris (perigrin) Prather
222
223 Robert (phaylon) Sedlacek
224
225 Tom (dec) Lanyon
226
227 Yuval Kogman
228
229 Jason May
230
231 Cory (gphat) Watson
232
233 Florian (rafl) Ragwitz
234
235 Evan Carroll
236
237 Jesse (doy) Luehrs
238
239 =head1 COPYRIGHT AND LICENSE
240
241 Copyright 2007-2009 by Infinity Interactive, Inc.
242
243 L<http://www.iinteractive.com>
244
245 This library is free software; you can redistribute it and/or modify
246 it under the same terms as Perl itself.
247
248 =cut