Beginning of dzilization
[gitmo/Moose.git] / lib / Moose / Meta / Attribute / Native.pm
CommitLineData
17e5e226 1package Moose::Meta::Attribute::Native;
e3c07b19 2
e3c07b19 3our $AUTHORITY = 'cpan:STEVAN';
4
cdf3cae6 5my @trait_names = qw(Bool Counter Number String Array Hash Code);
fafc8b9b 6
7for my $trait_name (@trait_names) {
c466e58f 8 my $trait_class = "Moose::Meta::Attribute::Native::Trait::$trait_name";
fafc8b9b 9 my $meta = Class::MOP::Class->initialize(
10 "Moose::Meta::Attribute::Custom::Trait::$trait_name"
11 );
12 if ($meta->find_method_by_name('register_implementation')) {
13 my $class = $meta->name->register_implementation;
14 Moose->throw_error(
15 "An implementation for $trait_name already exists " .
16 "(found '$class' when trying to register '$trait_class')"
17 );
18 }
19 $meta->add_method(register_implementation => sub {
20 # resolve_metatrait_alias will load classes anyway, but throws away
21 # their error message; we WANT to die if there's a problem
22 Class::MOP::load_class($trait_class);
23 return $trait_class;
24 });
25}
e3c07b19 26
e3c07b19 271;
28
ad46f524 29# ABSTRACT: Delegate to native Perl types
30
e3c07b19 31__END__
32
33=pod
34
e3c07b19 35=head1 SYNOPSIS
36
37 package MyClass;
38 use Moose;
e3c07b19 39
40 has 'mapping' => (
e132fd56 41 traits => ['Hash'],
42 is => 'rw',
43 isa => 'HashRef[Str]',
44 default => sub { {} },
45 handles => {
e3c07b19 46 exists_in_mapping => 'exists',
47 ids_in_mapping => 'keys',
48 get_mapping => 'get',
49 set_mapping => 'set',
cb562ad2 50 set_quantity => [ set => 'quantity' ],
e3c07b19 51 },
52 );
53
e3c07b19 54 my $obj = MyClass->new;
55 $obj->set_quantity(10); # quantity => 10
2420461c 56 $obj->set_mapping('foo', 4); # foo => 4
57 $obj->set_mapping('bar', 5); # bar => 5
58 $obj->set_mapping('baz', 6); # baz => 6
e3c07b19 59
2420461c 60 # prints 5
61 print $obj->get_mapping('bar') if $obj->exists_in_mapping('bar');
e3c07b19 62
2420461c 63 # prints 'quantity, foo, bar, baz'
e3c07b19 64 print join ', ', $obj->ids_in_mapping;
65
66=head1 DESCRIPTION
67
e132fd56 68Native delegations allow you to delegate to native Perl data
e11cc42d 69structures as if they were objects. For example, in the L</SYNOPSIS> you can
e132fd56 70see a hash reference being treated as if it has methods named C<exists()>,
71C<keys()>, C<get()>, and C<set()>.
72
73The delegation methods (mostly) map to Perl builtins and operators. The return
74values of these delegations should be the same as the corresponding Perl
75operation. Any deviations will be explicitly documented.
76
77=head1 API
e3c07b19 78
e132fd56 79Native delegations are enabled by passing certain options to C<has> when
80creating an attribute.
e3c07b19 81
e132fd56 82=head2 traits
87b4e821 83
e132fd56 84To enable this feature, pass the appropriate name in the C<traits> array
85reference for the attribute. For example, to enable this feature for hash
86reference, we include C<'Hash'> in the list of traits.
87
88=head2 isa
89
90You will need to make sure that the attribute has an appropriate type. For
91example, to use this with a Hash you must specify that your attribute is some
92sort of C<HashRef>.
93
94If you I<don't> specify a type, each trait has a default type it will use.
e3c07b19 95
96=head2 handles
97
e132fd56 98This is just like any other delegation, but only a hash reference is allowed
99when defining native delegations. The keys are the methods to be created in
100the class which contains the attribute. The values are the methods provided by
101the associated trait. Currying works the same way as it does with any other
102delegation.
e3c07b19 103
e132fd56 104See the docs for each native trait for details on what methods are available.
105
b79a1a50 106=head2 is
107
108Some traits provide a default C<is> for historical reasons. This behavior is
c33c3630 109deprecated, and you are strongly encouraged to provide a value. If you don't
b79a1a50 110plan to read and write the attribute value directly, you can set C<< is =>
111'bare' >> to prevent standard accessor generation.
112
b6bf6592 113=head2 default or builder
114
b79a1a50 115Some traits provide a default C<default> for historical reasons. This behavior
b6bf6592 116is deprecated, and you are strongly encouraged to provide a default value or
117make the attribute required.
118
e132fd56 119=head1 TRAITS FOR NATIVE DELEGATIONS
e3c07b19 120
121=over
122
66cce11c 123=item L<Array|Moose::Meta::Attribute::Native::Trait::Array>
e3c07b19 124
66cce11c 125 has 'queue' => (
e132fd56 126 traits => ['Array'],
127 is => 'ro',
128 isa => 'ArrayRef[Str]',
129 default => sub { [] },
130 handles => {
66cce11c 131 add_item => 'push',
132 next_item => 'shift',
39ab25ce 133 # ...
52e0d71f 134 }
135 );
136
66cce11c 137=item L<Bool|Moose::Meta::Attribute::Native::Trait::Bool>
e3c07b19 138
66cce11c 139 has 'is_lit' => (
e132fd56 140 traits => ['Bool'],
141 is => 'ro',
142 isa => 'Bool',
143 default => 0,
144 handles => {
66cce11c 145 illuminate => 'set',
146 darken => 'unset',
147 flip_switch => 'toggle',
148 is_dark => 'not',
149 # ...
150 }
151 );
152
153=item L<Code|Moose::Meta::Attribute::Native::Trait::Code>
154
66cce11c 155 has 'callback' => (
e132fd56 156 traits => ['Code'],
157 is => 'ro',
158 isa => 'CodeRef',
159 default => sub {
160 sub {'called'}
161 },
162 handles => {
66cce11c 163 call => 'execute',
39ab25ce 164 # ...
52e0d71f 165 }
166 );
167
c466e58f 168=item L<Counter|Moose::Meta::Attribute::Native::Trait::Counter>
e3c07b19 169
52e0d71f 170 has 'counter' => (
e132fd56 171 traits => ['Counter'],
172 is => 'ro',
173 isa => 'Num',
174 default => 0,
175 handles => {
52e0d71f 176 inc_counter => 'inc',
177 dec_counter => 'dec',
178 reset_counter => 'reset',
39ab25ce 179 # ...
52e0d71f 180 }
181 );
182
c466e58f 183=item L<Hash|Moose::Meta::Attribute::Native::Trait::Hash>
e3c07b19 184
52e0d71f 185 has 'options' => (
e132fd56 186 traits => ['Hash'],
187 is => 'ro',
188 isa => 'HashRef[Str]',
189 default => sub { {} },
190 handles => {
9958cbe1 191 set_option => 'set',
192 get_option => 'get',
193 has_option => 'exists',
39ab25ce 194 # ...
52e0d71f 195 }
196 );
e3c07b19 197
66cce11c 198=item L<Number|Moose::Meta::Attribute::Native::Trait::Number>
e3c07b19 199
66cce11c 200 has 'integer' => (
e132fd56 201 traits => ['Number'],
202 is => 'ro',
203 isa => 'Int',
204 default => 5,
205 handles => {
66cce11c 206 set => 'set',
207 add => 'add',
208 sub => 'sub',
209 mul => 'mul',
210 div => 'div',
211 mod => 'mod',
212 abs => 'abs',
754a4833 213 # ...
214 }
52e0d71f 215 );
e3c07b19 216
66cce11c 217=item L<String|Moose::Meta::Attribute::Native::Trait::String>
b86a4688 218
66cce11c 219 has 'text' => (
e132fd56 220 traits => ['String'],
221 is => 'ro',
222 isa => 'Str',
223 default => q{},
224 handles => {
66cce11c 225 add_text => 'append',
226 replace_text => 'replace',
754a4833 227 # ...
228 }
b86a4688 229 );
230
e3c07b19 231=back
232
e132fd56 233=head1 COMPATIBILITY WITH MooseX::AttributeHelpers
234
235This feature used to be a separated CPAN distribution called
236L<MooseX::AttributeHelpers>.
237
238When the feature was incorporated into the Moose core, some of the API details
239were changed. The underlying capabilities are the same, but some details of
240the API were changed.
241
e3c07b19 242=head1 BUGS
243
d4048ef3 244See L<Moose/BUGS> for details on reporting bugs.
e3c07b19 245
e3c07b19 246=cut