bump version to 0.89
[gitmo/Moose.git] / lib / Moose / Meta / Attribute.pm
1
2 package Moose::Meta::Attribute;
3
4 use strict;
5 use warnings;
6
7 use Scalar::Util 'blessed', 'weaken';
8 use overload     ();
9
10 our $VERSION   = '0.89';
11 our $AUTHORITY = 'cpan:STEVAN';
12
13 use Moose::Meta::Method::Accessor;
14 use Moose::Meta::Method::Delegation;
15 use Moose::Util ();
16 use Moose::Util::TypeConstraints ();
17
18 use base 'Class::MOP::Attribute';
19
20 # options which are not directly used
21 # but we store them for metadata purposes
22 __PACKAGE__->meta->add_attribute('isa'  => (reader    => '_isa_metadata'));
23 __PACKAGE__->meta->add_attribute('does' => (reader    => '_does_metadata'));
24 __PACKAGE__->meta->add_attribute('is'   => (reader    => '_is_metadata'));
25
26 # these are actual options for the attrs
27 __PACKAGE__->meta->add_attribute('required'   => (reader => 'is_required'      ));
28 __PACKAGE__->meta->add_attribute('lazy'       => (reader => 'is_lazy'          ));
29 __PACKAGE__->meta->add_attribute('lazy_build' => (reader => 'is_lazy_build'    ));
30 __PACKAGE__->meta->add_attribute('coerce'     => (reader => 'should_coerce'    ));
31 __PACKAGE__->meta->add_attribute('weak_ref'   => (reader => 'is_weak_ref'      ));
32 __PACKAGE__->meta->add_attribute('auto_deref' => (reader => 'should_auto_deref'));
33 __PACKAGE__->meta->add_attribute('type_constraint' => (
34     reader    => 'type_constraint',
35     predicate => 'has_type_constraint',
36 ));
37 __PACKAGE__->meta->add_attribute('trigger' => (
38     reader    => 'trigger',
39     predicate => 'has_trigger',
40 ));
41 __PACKAGE__->meta->add_attribute('handles' => (
42     reader    => 'handles',
43     predicate => 'has_handles',
44 ));
45 __PACKAGE__->meta->add_attribute('documentation' => (
46     reader    => 'documentation',
47     predicate => 'has_documentation',
48 ));
49 __PACKAGE__->meta->add_attribute('traits' => (
50     reader    => 'applied_traits',
51     predicate => 'has_applied_traits',
52 ));
53
54 # we need to have a ->does method in here to
55 # more easily support traits, and the introspection
56 # of those traits. We extend the does check to look
57 # for metatrait aliases.
58 sub does {
59     my ($self, $role_name) = @_;
60     my $name = eval {
61         Moose::Util::resolve_metatrait_alias(Attribute => $role_name)
62     };
63     return 0 if !defined($name); # failed to load class
64     return $self->Moose::Object::does($name);
65 }
66
67 sub throw_error {
68     my $self = shift;
69     my $class = ( ref $self && $self->associated_class ) || "Moose::Meta::Class";
70     unshift @_, "message" if @_ % 2 == 1;
71     unshift @_, attr => $self if ref $self;
72     unshift @_, $class;
73     my $handler = $class->can("throw_error"); # to avoid incrementing depth by 1
74     goto $handler;
75 }
76
77 sub new {
78     my ($class, $name, %options) = @_;
79     $class->_process_options($name, \%options) unless $options{__hack_no_process_options}; # used from clone()... YECHKKK FIXME ICKY YUCK GROSS
80     
81     delete $options{__hack_no_process_options};
82
83     my %attrs =
84         ( map { $_ => 1 }
85           grep { defined }
86           map { $_->init_arg() }
87           $class->meta()->get_all_attributes()
88         );
89
90     my @bad = sort grep { ! $attrs{$_} }  keys %options;
91
92     if (@bad)
93     {
94         Carp::cluck "Found unknown argument(s) passed to '$name' attribute constructor in '$class': @bad";
95     }
96
97     return $class->SUPER::new($name, %options);
98 }
99
100 sub interpolate_class_and_new {
101     my ($class, $name, %args) = @_;
102
103     my ( $new_class, @traits ) = $class->interpolate_class(\%args);
104
105     $new_class->new($name, %args, ( scalar(@traits) ? ( traits => \@traits ) : () ) );
106 }
107
108 sub interpolate_class {
109     my ($class, $options) = @_;
110
111     $class = ref($class) || $class;
112
113     if ( my $metaclass_name = delete $options->{metaclass} ) {
114         my $new_class = Moose::Util::resolve_metaclass_alias( Attribute => $metaclass_name );
115
116         if ( $class ne $new_class ) {
117             if ( $new_class->can("interpolate_class") ) {
118                 return $new_class->interpolate_class($options);
119             } else {
120                 $class = $new_class;
121             }
122         }
123     }
124
125     my @traits;
126
127     if (my $traits = $options->{traits}) {
128         my $i = 0;
129         while ($i < @$traits) {
130             my $trait = $traits->[$i++];
131             next if ref($trait); # options to a trait we discarded
132
133             $trait = Moose::Util::resolve_metatrait_alias(Attribute => $trait)
134                   || $trait;
135
136             next if $class->does($trait);
137
138             push @traits, $trait;
139
140             # are there options?
141             push @traits, $traits->[$i++]
142                 if $traits->[$i] && ref($traits->[$i]);
143         }
144
145         if (@traits) {
146             my $anon_class = Moose::Meta::Class->create_anon_class(
147                 superclasses => [ $class ],
148                 roles        => [ @traits ],
149                 cache        => 1,
150             );
151
152             $class = $anon_class->name;
153         }
154     }
155
156     return ( wantarray ? ( $class, @traits ) : $class );
157 }
158
159 # ...
160
161 my @legal_options_for_inheritance = qw(
162     default coerce required
163     documentation lazy handles
164     builder type_constraint
165     definition_context
166     lazy_build weak_ref
167 );
168
169 sub legal_options_for_inheritance { @legal_options_for_inheritance }
170
171 # NOTE/TODO
172 # This method *must* be able to handle
173 # Class::MOP::Attribute instances as
174 # well. Yes, I know that is wrong, but
175 # apparently we didn't realize it was
176 # doing that and now we have some code
177 # which is dependent on it. The real
178 # solution of course is to push this
179 # feature back up into Class::MOP::Attribute
180 # but I not right now, I am too lazy.
181 # However if you are reading this and
182 # looking for something to do,.. please
183 # be my guest.
184 # - stevan
185 sub clone_and_inherit_options {
186     my ($self, %options) = @_;
187
188     my %copy = %options;
189
190     my %actual_options;
191
192     # NOTE:
193     # we may want to extends a Class::MOP::Attribute
194     # in which case we need to be able to use the
195     # core set of legal options that have always
196     # been here. But we allows Moose::Meta::Attribute
197     # instances to changes them.
198     # - SL
199     my @legal_options = $self->can('legal_options_for_inheritance')
200         ? $self->legal_options_for_inheritance
201         : @legal_options_for_inheritance;
202
203     foreach my $legal_option (@legal_options) {
204         if (exists $options{$legal_option}) {
205             $actual_options{$legal_option} = $options{$legal_option};
206             delete $options{$legal_option};
207         }
208     }
209
210     if ($options{isa}) {
211         my $type_constraint;
212         if (blessed($options{isa}) && $options{isa}->isa('Moose::Meta::TypeConstraint')) {
213             $type_constraint = $options{isa};
214         }
215         else {
216             $type_constraint = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options{isa});
217             (defined $type_constraint)
218                 || $self->throw_error("Could not find the type constraint '" . $options{isa} . "'", data => $options{isa});
219         }
220
221         $actual_options{type_constraint} = $type_constraint;
222         delete $options{isa};
223     }
224
225     if ($options{does}) {
226         my $type_constraint;
227         if (blessed($options{does}) && $options{does}->isa('Moose::Meta::TypeConstraint')) {
228             $type_constraint = $options{does};
229         }
230         else {
231             $type_constraint = Moose::Util::TypeConstraints::find_or_create_does_type_constraint($options{does});
232             (defined $type_constraint)
233                 || $self->throw_error("Could not find the type constraint '" . $options{does} . "'", data => $options{does});
234         }
235
236         $actual_options{type_constraint} = $type_constraint;
237         delete $options{does};
238     }
239
240     # NOTE:
241     # this doesn't apply to Class::MOP::Attributes,
242     # so we can ignore it for them.
243     # - SL
244     if ($self->can('interpolate_class')) {
245         ( $actual_options{metaclass}, my @traits ) = $self->interpolate_class(\%options);
246
247         my %seen;
248         my @all_traits = grep { $seen{$_}++ } @{ $self->applied_traits || [] }, @traits;
249         $actual_options{traits} = \@all_traits if @all_traits;
250
251         delete @options{qw(metaclass traits)};
252     }
253
254     (scalar keys %options == 0)
255         || $self->throw_error("Illegal inherited options => (" . (join ', ' => keys %options) . ")", data => \%options);
256
257
258     $self->clone(%actual_options);
259 }
260
261 sub clone {
262     my ( $self, %params ) = @_;
263
264     my $class = delete $params{metaclass} || ref $self;
265
266     my ( @init, @non_init );
267
268     foreach my $attr ( grep { $_->has_value($self) } Class::MOP::class_of($self)->get_all_attributes ) {
269         push @{ $attr->has_init_arg ? \@init : \@non_init }, $attr;
270     }
271
272     my %new_params = ( ( map { $_->init_arg => $_->get_value($self) } @init ), %params );
273
274     my $name = delete $new_params{name};
275
276     my $clone = $class->new($name, %new_params, __hack_no_process_options => 1 );
277
278     foreach my $attr ( @non_init ) {
279         $attr->set_value($clone, $attr->get_value($self));
280     }
281
282     return $clone;
283 }
284
285 sub _process_options {
286     my ($class, $name, $options) = @_;
287
288     if (exists $options->{is}) {
289
290         ### -------------------------
291         ## is => ro, writer => _foo    # turns into (reader => foo, writer => _foo) as before
292         ## is => rw, writer => _foo    # turns into (reader => foo, writer => _foo)
293         ## is => rw, accessor => _foo  # turns into (accessor => _foo)
294         ## is => ro, accessor => _foo  # error, accesor is rw
295         ### -------------------------
296
297         if ($options->{is} eq 'ro') {
298             $class->throw_error("Cannot define an accessor name on a read-only attribute, accessors are read/write", data => $options)
299                 if exists $options->{accessor};
300             $options->{reader} ||= $name;
301         }
302         elsif ($options->{is} eq 'rw') {
303             if ($options->{writer}) {
304                 $options->{reader} ||= $name;
305             }
306             else {
307                 $options->{accessor} ||= $name;
308             }
309         }
310         elsif ($options->{is} eq 'bare') {
311             # do nothing, but don't complain (later) about missing methods
312         }
313         else {
314             $class->throw_error("I do not understand this option (is => " . $options->{is} . ") on attribute ($name)", data => $options->{is});
315         }
316     }
317
318     if (exists $options->{isa}) {
319         if (exists $options->{does}) {
320             if (eval { $options->{isa}->can('does') }) {
321                 ($options->{isa}->does($options->{does}))
322                     || $class->throw_error("Cannot have an isa option and a does option if the isa does not do the does on attribute ($name)", data => $options);
323             }
324             else {
325                 $class->throw_error("Cannot have an isa option which cannot ->does() on attribute ($name)", data => $options);
326             }
327         }
328
329         # allow for anon-subtypes here ...
330         if (blessed($options->{isa}) && $options->{isa}->isa('Moose::Meta::TypeConstraint')) {
331             $options->{type_constraint} = $options->{isa};
332         }
333         else {
334             $options->{type_constraint} = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options->{isa});
335         }
336     }
337     elsif (exists $options->{does}) {
338         # allow for anon-subtypes here ...
339         if (blessed($options->{does}) && $options->{does}->isa('Moose::Meta::TypeConstraint')) {
340                 $options->{type_constraint} = $options->{does};
341         }
342         else {
343             $options->{type_constraint} = Moose::Util::TypeConstraints::find_or_create_does_type_constraint($options->{does});
344         }
345     }
346
347     if (exists $options->{coerce} && $options->{coerce}) {
348         (exists $options->{type_constraint})
349             || $class->throw_error("You cannot have coercion without specifying a type constraint on attribute ($name)", data => $options);
350         $class->throw_error("You cannot have a weak reference to a coerced value on attribute ($name)", data => $options)
351             if $options->{weak_ref};
352     }
353
354     if (exists $options->{trigger}) {
355         ('CODE' eq ref $options->{trigger})
356             || $class->throw_error("Trigger must be a CODE ref on attribute ($name)", data => $options->{trigger});
357     }
358
359     if (exists $options->{auto_deref} && $options->{auto_deref}) {
360         (exists $options->{type_constraint})
361             || $class->throw_error("You cannot auto-dereference without specifying a type constraint on attribute ($name)", data => $options);
362         ($options->{type_constraint}->is_a_type_of('ArrayRef') ||
363          $options->{type_constraint}->is_a_type_of('HashRef'))
364             || $class->throw_error("You cannot auto-dereference anything other than a ArrayRef or HashRef on attribute ($name)", data => $options);
365     }
366
367     if (exists $options->{lazy_build} && $options->{lazy_build} == 1) {
368         $class->throw_error("You can not use lazy_build and default for the same attribute ($name)", data => $options)
369             if exists $options->{default};
370         $options->{lazy}      = 1;
371         $options->{builder} ||= "_build_${name}";
372         if ($name =~ /^_/) {
373             $options->{clearer}   ||= "_clear${name}";
374             $options->{predicate} ||= "_has${name}";
375         }
376         else {
377             $options->{clearer}   ||= "clear_${name}";
378             $options->{predicate} ||= "has_${name}";
379         }
380     }
381
382     if (exists $options->{lazy} && $options->{lazy}) {
383         (exists $options->{default} || defined $options->{builder} )
384             || $class->throw_error("You cannot have lazy attribute ($name) without specifying a default value for it", data => $options);
385     }
386
387     if ( $options->{required} && !( ( !exists $options->{init_arg} || defined $options->{init_arg} ) || exists $options->{default} || defined $options->{builder} ) ) {
388         $class->throw_error("You cannot have a required attribute ($name) without a default, builder, or an init_arg", data => $options);
389     }
390
391 }
392
393 sub initialize_instance_slot {
394     my ($self, $meta_instance, $instance, $params) = @_;
395     my $init_arg = $self->init_arg();
396     # try to fetch the init arg from the %params ...
397
398     my $val;
399     my $value_is_set;
400     if ( defined($init_arg) and exists $params->{$init_arg}) {
401         $val = $params->{$init_arg};
402         $value_is_set = 1;
403     }
404     else {
405         # skip it if it's lazy
406         return if $self->is_lazy;
407         # and die if it's required and doesn't have a default value
408         $self->throw_error("Attribute (" . $self->name . ") is required", object => $instance, data => $params)
409             if $self->is_required && !$self->has_default && !$self->has_builder;
410
411         # if nothing was in the %params, we can use the
412         # attribute's default value (if it has one)
413         if ($self->has_default) {
414             $val = $self->default($instance);
415             $value_is_set = 1;
416         }
417         elsif ($self->has_builder) {
418             $val = $self->_call_builder($instance);
419             $value_is_set = 1;
420         }
421     }
422
423     return unless $value_is_set;
424
425     $val = $self->_coerce_and_verify( $val, $instance );
426
427     $self->set_initial_value($instance, $val);
428     $meta_instance->weaken_slot_value($instance, $self->name)
429         if ref $val && $self->is_weak_ref;
430 }
431
432 sub _call_builder {
433     my ( $self, $instance ) = @_;
434
435     my $builder = $self->builder();
436
437     return $instance->$builder()
438         if $instance->can( $self->builder );
439
440     $self->throw_error(  blessed($instance)
441             . " does not support builder method '"
442             . $self->builder
443             . "' for attribute '"
444             . $self->name
445             . "'",
446             object => $instance,
447      );
448 }
449
450 ## Slot management
451
452 # FIXME:
453 # this duplicates too much code from
454 # Class::MOP::Attribute, we need to
455 # refactor these bits eventually.
456 # - SL
457 sub _set_initial_slot_value {
458     my ($self, $meta_instance, $instance, $value) = @_;
459
460     my $slot_name = $self->name;
461
462     return $meta_instance->set_slot_value($instance, $slot_name, $value)
463         unless $self->has_initializer;
464
465     my ($type_constraint, $can_coerce);
466     if ($self->has_type_constraint) {
467         $type_constraint = $self->type_constraint;
468         $can_coerce      = ($self->should_coerce && $type_constraint->has_coercion);
469     }
470
471     my $callback = sub {
472         my $val = $self->_coerce_and_verify( shift, $instance );;
473
474         $meta_instance->set_slot_value($instance, $slot_name, $val);
475     };
476
477     my $initializer = $self->initializer;
478
479     # most things will just want to set a value, so make it first arg
480     $instance->$initializer($value, $callback, $self);
481 }
482
483 sub set_value {
484     my ($self, $instance, @args) = @_;
485     my $value = $args[0];
486
487     my $attr_name = $self->name;
488
489     if ($self->is_required and not @args) {
490         $self->throw_error("Attribute ($attr_name) is required", object => $instance);
491     }
492
493     $value = $self->_coerce_and_verify( $value, $instance );
494
495     my $meta_instance = Class::MOP::Class->initialize(blessed($instance))
496                                          ->get_meta_instance;
497
498     my @old;
499     if ( $self->has_trigger && $self->has_value($instance) ) {
500         @old = $self->get_value($instance, 'for trigger');
501     }
502
503     $meta_instance->set_slot_value($instance, $attr_name, $value);
504
505     if (ref $value && $self->is_weak_ref) {
506         $meta_instance->weaken_slot_value($instance, $attr_name);
507     }
508
509     if ($self->has_trigger) {
510         $self->trigger->($instance, $value, @old);
511     }
512 }
513
514 sub get_value {
515     my ($self, $instance, $for_trigger) = @_;
516
517     if ($self->is_lazy) {
518         unless ($self->has_value($instance)) {
519             my $value;
520             if ($self->has_default) {
521                 $value = $self->default($instance);
522             } elsif ( $self->has_builder ) {
523                 $value = $self->_call_builder($instance);
524             }
525
526             $value = $self->_coerce_and_verify( $value, $instance );
527
528             $self->set_initial_value($instance, $value);
529         }
530     }
531
532     if ( $self->should_auto_deref && ! $for_trigger ) {
533
534         my $type_constraint = $self->type_constraint;
535
536         if ($type_constraint->is_a_type_of('ArrayRef')) {
537             my $rv = $self->SUPER::get_value($instance);
538             return unless defined $rv;
539             return wantarray ? @{ $rv } : $rv;
540         }
541         elsif ($type_constraint->is_a_type_of('HashRef')) {
542             my $rv = $self->SUPER::get_value($instance);
543             return unless defined $rv;
544             return wantarray ? %{ $rv } : $rv;
545         }
546         else {
547             $self->throw_error("Can not auto de-reference the type constraint '" . $type_constraint->name . "'", object => $instance, type_constraint => $type_constraint);
548         }
549
550     }
551     else {
552
553         return $self->SUPER::get_value($instance);
554     }
555 }
556
557 ## installing accessors
558
559 sub accessor_metaclass { 'Moose::Meta::Method::Accessor' }
560
561 sub install_accessors {
562     my $self = shift;
563     $self->SUPER::install_accessors(@_);
564     $self->install_delegation if $self->has_handles;
565     return;
566 }
567
568 sub _check_associated_methods {
569     my $self = shift;
570     unless (
571         @{ $self->associated_methods }
572         || ($self->_is_metadata || '') eq 'bare'
573     ) {
574         Carp::cluck(
575             'Attribute (' . $self->name . ') of class '
576             . $self->associated_class->name
577             . ' has no associated methods'
578             . ' (did you mean to provide an "is" argument?)'
579             . "\n"
580         )
581     }
582 }
583
584 sub _process_accessors {
585     my $self = shift;
586     my ($type, $accessor, $generate_as_inline_methods) = @_;
587     $accessor = (keys %$accessor)[0] if (ref($accessor)||'') eq 'HASH';
588     my $method = $self->associated_class->get_method($accessor);
589     if ($method && !$method->isa('Class::MOP::Method::Accessor')
590      && (!$self->definition_context
591       || $method->package_name eq $self->definition_context->{package})) {
592         Carp::cluck(
593             "You are overwriting a locally defined method ($accessor) with "
594           . "an accessor"
595         );
596     }
597     $self->SUPER::_process_accessors(@_);
598 }
599
600 sub remove_accessors {
601     my $self = shift;
602     $self->SUPER::remove_accessors(@_);
603     $self->remove_delegation if $self->has_handles;
604     return;
605 }
606
607 sub install_delegation {
608     my $self = shift;
609
610     # NOTE:
611     # Here we canonicalize the 'handles' option
612     # this will sort out any details and always
613     # return an hash of methods which we want
614     # to delagate to, see that method for details
615     my %handles = $self->_canonicalize_handles;
616
617
618     # install the delegation ...
619     my $associated_class = $self->associated_class;
620     foreach my $handle (keys %handles) {
621         my $method_to_call = $handles{$handle};
622         my $class_name = $associated_class->name;
623         my $name = "${class_name}::${handle}";
624
625             (!$associated_class->has_method($handle))
626                 || $self->throw_error("You cannot overwrite a locally defined method ($handle) with a delegation", method_name => $handle);
627
628         # NOTE:
629         # handles is not allowed to delegate
630         # any of these methods, as they will
631         # override the ones in your class, which
632         # is almost certainly not what you want.
633
634         # FIXME warn when $handle was explicitly specified, but not if the source is a regex or something
635         #cluck("Not delegating method '$handle' because it is a core method") and
636         next if $class_name->isa("Moose::Object") and $handle =~ /^BUILD|DEMOLISH$/ || Moose::Object->can($handle);
637
638         my $method = $self->_make_delegation_method($handle, $method_to_call);
639
640         $self->associated_class->add_method($method->name, $method);
641         $self->associate_method($method);
642     }
643 }
644
645 sub remove_delegation {
646     my $self = shift;
647     my %handles = $self->_canonicalize_handles;
648     my $associated_class = $self->associated_class;
649     foreach my $handle (keys %handles) {
650         $self->associated_class->remove_method($handle);
651     }
652 }
653
654 # private methods to help delegation ...
655
656 sub _canonicalize_handles {
657     my $self    = shift;
658     my $handles = $self->handles;
659     if (my $handle_type = ref($handles)) {
660         if ($handle_type eq 'HASH') {
661             return %{$handles};
662         }
663         elsif ($handle_type eq 'ARRAY') {
664             return map { $_ => $_ } @{$handles};
665         }
666         elsif ($handle_type eq 'Regexp') {
667             ($self->has_type_constraint)
668                 || $self->throw_error("Cannot delegate methods based on a Regexp without a type constraint (isa)", data => $handles);
669             return map  { ($_ => $_) }
670                    grep { /$handles/ } $self->_get_delegate_method_list;
671         }
672         elsif ($handle_type eq 'CODE') {
673             return $handles->($self, $self->_find_delegate_metaclass);
674         }
675         elsif (blessed($handles) && $handles->isa('Moose::Meta::TypeConstraint::DuckType')) {
676             return map { $_ => $_ } @{ $handles->methods };
677         }
678         else {
679             $self->throw_error("Unable to canonicalize the 'handles' option with $handles", data => $handles);
680         }
681     }
682     else {
683         Class::MOP::load_class($handles);
684         my $role_meta = Class::MOP::class_of($handles);
685
686         (blessed $role_meta && $role_meta->isa('Moose::Meta::Role'))
687             || $self->throw_error("Unable to canonicalize the 'handles' option with $handles because its metaclass is not a Moose::Meta::Role", data => $handles);
688
689         return map { $_ => $_ } (
690             $role_meta->get_method_list,
691             map { $_->name } $role_meta->get_required_method_list,
692         );
693     }
694 }
695
696 sub _find_delegate_metaclass {
697     my $self = shift;
698     if (my $class = $self->_isa_metadata) {
699         # we might be dealing with a non-Moose class,
700         # and need to make our own metaclass. if there's
701         # already a metaclass, it will be returned
702         return Moose::Meta::Class->initialize($class);
703     }
704     elsif (my $role = $self->_does_metadata) {
705         return Class::MOP::class_of($role);
706     }
707     else {
708         $self->throw_error("Cannot find delegate metaclass for attribute " . $self->name);
709     }
710 }
711
712 sub _get_delegate_method_list {
713     my $self = shift;
714     my $meta = $self->_find_delegate_metaclass;
715     if ($meta->isa('Class::MOP::Class')) {
716         return map  { $_->name }  # NOTE: !never! delegate &meta
717                grep { $_->package_name ne 'Moose::Object' && $_->name ne 'meta' }
718                     $meta->get_all_methods;
719     }
720     elsif ($meta->isa('Moose::Meta::Role')) {
721         return $meta->get_method_list;
722     }
723     else {
724         $self->throw_error("Unable to recognize the delegate metaclass '$meta'", data => $meta);
725     }
726 }
727
728 sub delegation_metaclass { 'Moose::Meta::Method::Delegation' }
729
730 sub _make_delegation_method {
731     my ( $self, $handle_name, $method_to_call ) = @_;
732
733     my $method_body;
734
735     $method_body = $method_to_call
736         if 'CODE' eq ref($method_to_call);
737
738     return $self->delegation_metaclass->new(
739         name               => $handle_name,
740         package_name       => $self->associated_class->name,
741         attribute          => $self,
742         delegate_to_method => $method_to_call,
743     );
744 }
745
746 sub _coerce_and_verify {
747     my $self     = shift;
748     my $val      = shift;
749     my $instance = shift;
750
751     return $val unless $self->has_type_constraint;
752
753     my $type_constraint = $self->type_constraint;
754     if ($self->should_coerce && $type_constraint->has_coercion) {
755         $val = $type_constraint->coerce($val);
756     }
757
758     $self->verify_against_type_constraint($val, instance => $instance);
759
760     return $val;
761 }
762
763 sub verify_against_type_constraint {
764     my $self = shift;
765     my $val  = shift;
766
767     return 1 if !$self->has_type_constraint;
768
769     my $type_constraint = $self->type_constraint;
770
771     $type_constraint->check($val)
772         || $self->throw_error("Attribute ("
773                  . $self->name
774                  . ") does not pass the type constraint because: "
775                  . $type_constraint->get_message($val), data => $val, @_);
776 }
777
778 package Moose::Meta::Attribute::Custom::Moose;
779 sub register_implementation { 'Moose::Meta::Attribute' }
780
781 1;
782
783 __END__
784
785 =pod
786
787 =head1 NAME
788
789 Moose::Meta::Attribute - The Moose attribute metaclass
790
791 =head1 DESCRIPTION
792
793 This class is a subclass of L<Class::MOP::Attribute> that provides
794 additional Moose-specific functionality.
795
796 To really understand this class, you will need to start with the
797 L<Class::MOP::Attribute> documentation. This class can be understood
798 as a set of additional features on top of the basic feature provided
799 by that parent class.
800
801 =head1 INHERITANCE
802
803 C<Moose::Meta::Attribute> is a subclass of L<Class::MOP::Attribute>.
804
805 =head1 METHODS
806
807 Many of the documented below override methods in
808 L<Class::MOP::Attribute> and add Moose specific features.
809
810 =head2 Creation
811
812 =over 4
813
814 =item B<< Moose::Meta::Attribute->new(%options) >>
815
816 This method overrides the L<Class::MOP::Attribute> constructor.
817
818 Many of the options below are described in more detail in the
819 L<Moose::Manual::Attributes> document.
820
821 It adds the following options to the constructor:
822
823 =over 8
824
825 =item * is => 'ro', 'rw', 'bare'
826
827 This provides a shorthand for specifying the C<reader>, C<writer>, or
828 C<accessor> names. If the attribute is read-only ('ro') then it will
829 have a C<reader> method with the same attribute as the name.
830
831 If it is read-write ('rw') then it will have an C<accessor> method
832 with the same name. If you provide an explicit C<writer> for a
833 read-write attribute, then you will have a C<reader> with the same
834 name as the attribute, and a C<writer> with the name you provided.
835
836 Use 'bare' when you are deliberately not installing any methods
837 (accessor, reader, etc.) associated with this attribute; otherwise,
838 Moose will issue a deprecation warning when this attribute is added to a
839 metaclass.
840
841 =item * isa => $type
842
843 This option accepts a type. The type can be a string, which should be
844 a type name. If the type name is unknown, it is assumed to be a class
845 name.
846
847 This option can also accept a L<Moose::Meta::TypeConstraint> object.
848
849 If you I<also> provide a C<does> option, then your C<isa> option must
850 be a class name, and that class must do the role specified with
851 C<does>.
852
853 =item * does => $role
854
855 This is short-hand for saying that the attribute's type must be an
856 object which does the named role.
857
858 =item * coerce => $bool
859
860 This option is only valid for objects with a type constraint
861 (C<isa>). If this is true, then coercions will be applied whenever
862 this attribute is set.
863
864 You can make both this and the C<weak_ref> option true.
865
866 =item * trigger => $sub
867
868 This option accepts a subroutine reference, which will be called after
869 the attribute is set.
870
871 =item * required => $bool
872
873 An attribute which is required must be provided to the constructor. An
874 attribute which is required can also have a C<default> or C<builder>,
875 which will satisfy its required-ness.
876
877 A required attribute must have a C<default>, C<builder> or a
878 non-C<undef> C<init_arg>
879
880 =item * lazy => $bool
881
882 A lazy attribute must have a C<default> or C<builder>. When an
883 attribute is lazy, the default value will not be calculated until the
884 attribute is read.
885
886 =item * weak_ref => $bool
887
888 If this is true, the attribute's value will be stored as a weak
889 reference.
890
891 =item * auto_deref => $bool
892
893 If this is true, then the reader will dereference the value when it is
894 called. The attribute must have a type constraint which defines the
895 attribute as an array or hash reference.
896
897 =item * lazy_build => $bool
898
899 Setting this to true makes the attribute lazy and provides a number of
900 default methods.
901
902   has 'size' => (
903       is         => 'ro',
904       lazy_build => 1,
905   );
906
907 is equivalent to this:
908
909   has 'size' => (
910       is        => 'ro',
911       lazy      => 1,
912       builder   => '_build_size',
913       clearer   => 'clear_size',
914       predicate => 'has_size',
915   );
916
917 =item * documentation
918
919 An arbitrary string that can be retrieved later by calling C<<
920 $attr->documentation >>.
921
922 =back
923
924 =item B<< $attr->clone(%options) >>
925
926 This creates a new attribute based on attribute being cloned. You must
927 supply a C<name> option to provide a new name for the attribute.
928
929 The C<%options> can only specify options handled by
930 L<Class::MOP::Attribute>.
931
932 =back
933
934 =head2 Value management
935
936 =over 4
937
938 =item B<< $attr->initialize_instance_slot($meta_instance, $instance, $params) >>
939
940 This method is used internally to initialize the attribute's slot in
941 the object C<$instance>.
942
943 This overrides the L<Class::MOP::Attribute> method to handle lazy
944 attributes, weak references, and type constraints.
945
946 =item B<get_value>
947
948 =item B<set_value>
949
950   eval { $point->meta->get_attribute('x')->set_value($point, 'forty-two') };
951   if($@) {
952     print "Oops: $@\n";
953   }
954
955 I<Attribute (x) does not pass the type constraint (Int) with 'forty-two'>
956
957 Before setting the value, a check is made on the type constraint of
958 the attribute, if it has one, to see if the value passes it. If the
959 value fails to pass, the set operation dies with a L<throw_error>.
960
961 Any coercion to convert values is done before checking the type constraint.
962
963 To check a value against a type constraint before setting it, fetch the
964 attribute instance using L<Class::MOP::Class/find_attribute_by_name>,
965 fetch the type_constraint from the attribute using L<Moose::Meta::Attribute/type_constraint>
966 and call L<Moose::Meta::TypeConstraint/check>. See L<Moose::Cookbook::Basics::Recipe4>
967 for an example.
968
969 =back
970
971 =head2 Attribute Accessor generation
972
973 =over 4
974
975 =item B<< $attr->install_accessors >>
976
977 This method overrides the parent to also install delegation methods.
978
979 If, after installing all methods, the attribute object has no associated
980 methods, it throws an error unless C<< is => 'bare' >> was passed to the
981 attribute constructor.  (Trying to add an attribute that has no associated
982 methods is almost always an error.)
983
984 =item B<< $attr->remove_accessors >>
985
986 This method overrides the parent to also remove delegation methods.
987
988 =item B<< $attr->install_delegation >>
989
990 This method adds its delegation methods to the attribute's associated
991 class, if it has any to add.
992
993 =item B<< $attr->remove_delegation >>
994
995 This method remove its delegation methods from the attribute's
996 associated class.
997
998 =item B<< $attr->accessor_metaclass >>
999
1000 Returns the accessor metaclass name, which defaults to
1001 L<Moose::Meta::Method::Accessor>.
1002
1003 =item B<< $attr->delegation_metaclass >>
1004
1005 Returns the delegation metaclass name, which defaults to
1006 L<Moose::Meta::Method::Delegation>.
1007
1008 =back
1009
1010 =head2 Additional Moose features
1011
1012 These methods are not found in the superclass. They support features
1013 provided by Moose.
1014
1015 =over 4
1016
1017 =item B<< $attr->does($role) >>
1018
1019 This indicates whether the I<attribute itself> does the given
1020 role. The role can be given as a full class name, or as a resolvable
1021 trait name.
1022
1023 Note that this checks the attribute itself, not its type constraint,
1024 so it is checking the attribute's metaclass and any traits applied to
1025 the attribute.
1026
1027 =item B<< Moose::Meta::Class->interpolate_class_and_new($name, %options) >>
1028
1029 This is an alternate constructor that handles the C<metaclass> and
1030 C<traits> options.
1031
1032 Effectively, this method is a factory that finds or creates the
1033 appropriate class for the given C<metaclass> and/or C<traits>.
1034
1035 Once it has the appropriate class, it will call C<< $class->new($name,
1036 %options) >> on that class.
1037
1038 =item B<< $attr->clone_and_inherit_options(%options) >>
1039
1040 This method supports the C<has '+foo'> feature. It does various bits
1041 of processing on the supplied C<%options> before ultimately calling
1042 the C<clone> method.
1043
1044 One of its main tasks is to make sure that the C<%options> provided
1045 only includes the options returned by the
1046 C<legal_options_for_inheritance> method.
1047
1048 =item B<< $attr->legal_options_for_inheritance >>
1049
1050 This returns a whitelist of options that can be overridden in a
1051 subclass's attribute definition.
1052
1053 This exists to allow a custom metaclass to change or add to the list
1054 of options which can be changed.
1055
1056 =item B<< $attr->type_constraint >>
1057
1058 Returns the L<Moose::Meta::TypeConstraint> object for this attribute,
1059 if it has one.
1060
1061 =item B<< $attr->has_type_constraint >>
1062
1063 Returns true if this attribute has a type constraint.
1064
1065 =item B<< $attr->verify_against_type_constraint($value) >>
1066
1067 Given a value, this method returns true if the value is valid for the
1068 attribute's type constraint. If the value is not valid, it throws an
1069 error.
1070
1071 =item B<< $attr->handles >>
1072
1073 This returns the value of the C<handles> option passed to the
1074 constructor.
1075
1076 =item B<< $attr->has_handles >>
1077
1078 Returns true if this attribute performs delegation.
1079
1080 =item B<< $attr->is_weak_ref >>
1081
1082 Returns true if this attribute stores its value as a weak reference.
1083
1084 =item B<< $attr->is_required >>
1085
1086 Returns true if this attribute is required to have a value.
1087
1088 =item B<< $attr->is_lazy >>
1089
1090 Returns true if this attribute is lazy.
1091
1092 =item B<< $attr->is_lazy_build >>
1093
1094 Returns true if the C<lazy_build> option was true when passed to the
1095 constructor.
1096
1097 =item B<< $attr->should_coerce >>
1098
1099 Returns true if the C<coerce> option passed to the constructor was
1100 true.
1101
1102 =item B<< $attr->should_auto_deref >>
1103
1104 Returns true if the C<auto_deref> option passed to the constructor was
1105 true.
1106
1107 =item B<< $attr->trigger >>
1108
1109 This is the subroutine reference that was in the C<trigger> option
1110 passed to the constructor, if any.
1111
1112 =item B<< $attr->has_trigger >>
1113
1114 Returns true if this attribute has a trigger set.
1115
1116 =item B<< $attr->documentation >>
1117
1118 Returns the value that was in the C<documentation> option passed to
1119 the constructor, if any.
1120
1121 =item B<< $attr->has_documentation >>
1122
1123 Returns true if this attribute has any documentation.
1124
1125 =item B<< $attr->applied_traits >>
1126
1127 This returns an array reference of all the traits which were applied
1128 to this attribute. If none were applied, this returns C<undef>.
1129
1130 =item B<< $attr->has_applied_traits >>
1131
1132 Returns true if this attribute has any traits applied.
1133
1134 =back
1135
1136 =head1 BUGS
1137
1138 All complex software has bugs lurking in it, and this module is no
1139 exception. If you find a bug please either email me, or add the bug
1140 to cpan-RT.
1141
1142 =head1 AUTHOR
1143
1144 Stevan Little E<lt>stevan@iinteractive.comE<gt>
1145
1146 Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
1147
1148 =head1 COPYRIGHT AND LICENSE
1149
1150 Copyright 2006-2009 by Infinity Interactive, Inc.
1151
1152 L<http://www.iinteractive.com>
1153
1154 This library is free software; you can redistribute it and/or modify
1155 it under the same terms as Perl itself.
1156
1157 =cut