close over the coercion sub separately
[gitmo/Moose.git] / lib / Moose / Meta / Attribute.pm
1
2 package Moose::Meta::Attribute;
3
4 use strict;
5 use warnings;
6
7 use Class::MOP ();
8 use B ();
9 use Scalar::Util 'blessed', 'weaken';
10 use List::MoreUtils 'any';
11 use Try::Tiny;
12 use overload     ();
13
14 use Moose::Deprecated;
15 use Moose::Meta::Method::Accessor;
16 use Moose::Meta::Method::Delegation;
17 use Moose::Util ();
18 use Moose::Util::TypeConstraints ();
19 use Class::MOP::MiniTrait;
20
21 use base 'Class::MOP::Attribute', 'Moose::Meta::Mixin::AttributeCore';
22
23 Class::MOP::MiniTrait::apply(__PACKAGE__, 'Moose::Meta::Object::Trait');
24
25 __PACKAGE__->meta->add_attribute('traits' => (
26     reader    => 'applied_traits',
27     predicate => 'has_applied_traits',
28 ));
29
30 # we need to have a ->does method in here to
31 # more easily support traits, and the introspection
32 # of those traits. We extend the does check to look
33 # for metatrait aliases.
34 sub does {
35     my ($self, $role_name) = @_;
36     my $name = try {
37         Moose::Util::resolve_metatrait_alias(Attribute => $role_name)
38     };
39     return 0 if !defined($name); # failed to load class
40     return $self->Moose::Object::does($name);
41 }
42
43 sub throw_error {
44     my $self = shift;
45     my $class = ( ref $self && $self->associated_class ) || "Moose::Meta::Class";
46     unshift @_, "message" if @_ % 2 == 1;
47     unshift @_, attr => $self if ref $self;
48     unshift @_, $class;
49     my $handler = $class->can("throw_error"); # to avoid incrementing depth by 1
50     goto $handler;
51 }
52
53 sub _inline_throw_error {
54     my ( $self, $msg, $args ) = @_;
55     "\$meta->throw_error($msg" . ($args ? ", $args" : "") . ")"; # FIXME makes deparsing *REALLY* hard
56 }
57
58 sub new {
59     my ($class, $name, %options) = @_;
60     $class->_process_options($name, \%options) unless $options{__hack_no_process_options}; # used from clone()... YECHKKK FIXME ICKY YUCK GROSS
61     
62     delete $options{__hack_no_process_options};
63
64     my %attrs =
65         ( map { $_ => 1 }
66           grep { defined }
67           map { $_->init_arg() }
68           $class->meta()->get_all_attributes()
69         );
70
71     my @bad = sort grep { ! $attrs{$_} }  keys %options;
72
73     if (@bad)
74     {
75         Carp::cluck "Found unknown argument(s) passed to '$name' attribute constructor in '$class': @bad";
76     }
77
78     return $class->SUPER::new($name, %options);
79 }
80
81 sub interpolate_class_and_new {
82     my ($class, $name, %args) = @_;
83
84     my ( $new_class, @traits ) = $class->interpolate_class(\%args);
85
86     $new_class->new($name, %args, ( scalar(@traits) ? ( traits => \@traits ) : () ) );
87 }
88
89 sub interpolate_class {
90     my ($class, $options) = @_;
91
92     $class = ref($class) || $class;
93
94     if ( my $metaclass_name = delete $options->{metaclass} ) {
95         my $new_class = Moose::Util::resolve_metaclass_alias( Attribute => $metaclass_name );
96
97         if ( $class ne $new_class ) {
98             if ( $new_class->can("interpolate_class") ) {
99                 return $new_class->interpolate_class($options);
100             } else {
101                 $class = $new_class;
102             }
103         }
104     }
105
106     my @traits;
107
108     if (my $traits = $options->{traits}) {
109         my $i = 0;
110         while ($i < @$traits) {
111             my $trait = $traits->[$i++];
112             next if ref($trait); # options to a trait we discarded
113
114             $trait = Moose::Util::resolve_metatrait_alias(Attribute => $trait)
115                   || $trait;
116
117             next if $class->does($trait);
118
119             push @traits, $trait;
120
121             # are there options?
122             push @traits, $traits->[$i++]
123                 if $traits->[$i] && ref($traits->[$i]);
124         }
125
126         if (@traits) {
127             my $anon_class = Moose::Meta::Class->create_anon_class(
128                 superclasses => [ $class ],
129                 roles        => [ @traits ],
130                 cache        => 1,
131             );
132
133             $class = $anon_class->name;
134         }
135     }
136
137     return ( wantarray ? ( $class, @traits ) : $class );
138 }
139
140 # ...
141
142 # method-generating options shouldn't be overridden
143 sub illegal_options_for_inheritance {
144     qw(reader writer accessor clearer predicate)
145 }
146
147 # NOTE/TODO
148 # This method *must* be able to handle
149 # Class::MOP::Attribute instances as
150 # well. Yes, I know that is wrong, but
151 # apparently we didn't realize it was
152 # doing that and now we have some code
153 # which is dependent on it. The real
154 # solution of course is to push this
155 # feature back up into Class::MOP::Attribute
156 # but I not right now, I am too lazy.
157 # However if you are reading this and
158 # looking for something to do,.. please
159 # be my guest.
160 # - stevan
161 sub clone_and_inherit_options {
162     my ($self, %options) = @_;
163
164     # NOTE:
165     # we may want to extends a Class::MOP::Attribute
166     # in which case we need to be able to use the
167     # core set of legal options that have always
168     # been here. But we allows Moose::Meta::Attribute
169     # instances to changes them.
170     # - SL
171     my @illegal_options = $self->can('illegal_options_for_inheritance')
172         ? $self->illegal_options_for_inheritance
173         : ();
174
175     my @found_illegal_options = grep { exists $options{$_} && exists $self->{$_} ? $_ : undef } @illegal_options;
176     (scalar @found_illegal_options == 0)
177         || $self->throw_error("Illegal inherited options => (" . (join ', ' => @found_illegal_options) . ")", data => \%options);
178
179     if ($options{isa}) {
180         my $type_constraint;
181         if (blessed($options{isa}) && $options{isa}->isa('Moose::Meta::TypeConstraint')) {
182             $type_constraint = $options{isa};
183         }
184         else {
185             $type_constraint = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options{isa});
186             (defined $type_constraint)
187                 || $self->throw_error("Could not find the type constraint '" . $options{isa} . "'", data => $options{isa});
188         }
189
190         $options{type_constraint} = $type_constraint;
191     }
192
193     if ($options{does}) {
194         my $type_constraint;
195         if (blessed($options{does}) && $options{does}->isa('Moose::Meta::TypeConstraint')) {
196             $type_constraint = $options{does};
197         }
198         else {
199             $type_constraint = Moose::Util::TypeConstraints::find_or_create_does_type_constraint($options{does});
200             (defined $type_constraint)
201                 || $self->throw_error("Could not find the type constraint '" . $options{does} . "'", data => $options{does});
202         }
203
204         $options{type_constraint} = $type_constraint;
205     }
206
207     # NOTE:
208     # this doesn't apply to Class::MOP::Attributes,
209     # so we can ignore it for them.
210     # - SL
211     if ($self->can('interpolate_class')) {
212         ( $options{metaclass}, my @traits ) = $self->interpolate_class(\%options);
213
214         my %seen;
215         my @all_traits = grep { $seen{$_}++ } @{ $self->applied_traits || [] }, @traits;
216         $options{traits} = \@all_traits if @all_traits;
217     }
218
219     # This method can be called on a CMOP::Attribute object, so we need to
220     # make sure we can call this method.
221     $self->_process_lazy_build_option( $self->name, \%options )
222         if $self->can('_process_lazy_build_option');
223
224     $self->clone(%options);
225 }
226
227 sub clone {
228     my ( $self, %params ) = @_;
229
230     my $class = delete $params{metaclass} || ref $self;
231
232     my ( @init, @non_init );
233
234     foreach my $attr ( grep { $_->has_value($self) } Class::MOP::class_of($self)->get_all_attributes ) {
235         push @{ $attr->has_init_arg ? \@init : \@non_init }, $attr;
236     }
237
238     my %new_params = ( ( map { $_->init_arg => $_->get_value($self) } @init ), %params );
239
240     my $name = delete $new_params{name};
241
242     my $clone = $class->new($name, %new_params, __hack_no_process_options => 1 );
243
244     foreach my $attr ( @non_init ) {
245         $attr->set_value($clone, $attr->get_value($self));
246     }
247
248     return $clone;
249 }
250
251 sub _process_options {
252     my ( $class, $name, $options ) = @_;
253
254     $class->_process_is_option( $name, $options );
255     $class->_process_isa_option( $name, $options );
256     $class->_process_does_option( $name, $options );
257     $class->_process_coerce_option( $name, $options );
258     $class->_process_trigger_option( $name, $options );
259     $class->_process_auto_deref_option( $name, $options );
260     $class->_process_lazy_build_option( $name, $options );
261     $class->_process_lazy_option( $name, $options );
262     $class->_process_required_option( $name, $options );
263 }
264
265 sub _process_is_option {
266     my ( $class, $name, $options ) = @_;
267
268     return unless $options->{is};
269
270     ### -------------------------
271     ## is => ro, writer => _foo    # turns into (reader => foo, writer => _foo) as before
272     ## is => rw, writer => _foo    # turns into (reader => foo, writer => _foo)
273     ## is => rw, accessor => _foo  # turns into (accessor => _foo)
274     ## is => ro, accessor => _foo  # error, accesor is rw
275     ### -------------------------
276
277     if ( $options->{is} eq 'ro' ) {
278         $class->throw_error(
279             "Cannot define an accessor name on a read-only attribute, accessors are read/write",
280             data => $options )
281             if exists $options->{accessor};
282         $options->{reader} ||= $name;
283     }
284     elsif ( $options->{is} eq 'rw' ) {
285         if ( $options->{writer} ) {
286             $options->{reader} ||= $name;
287         }
288         else {
289             $options->{accessor} ||= $name;
290         }
291     }
292     elsif ( $options->{is} eq 'bare' ) {
293         return;
294         # do nothing, but don't complain (later) about missing methods
295     }
296     else {
297         $class->throw_error( "I do not understand this option (is => "
298                 . $options->{is}
299                 . ") on attribute ($name)", data => $options->{is} );
300     }
301 }
302
303 sub _process_isa_option {
304     my ( $class, $name, $options ) = @_;
305
306     return unless exists $options->{isa};
307
308     if ( exists $options->{does} ) {
309         if ( try { $options->{isa}->can('does') } ) {
310             ( $options->{isa}->does( $options->{does} ) )
311                 || $class->throw_error(
312                 "Cannot have an isa option and a does option if the isa does not do the does on attribute ($name)",
313                 data => $options );
314         }
315         else {
316             $class->throw_error(
317                 "Cannot have an isa option which cannot ->does() on attribute ($name)",
318                 data => $options );
319         }
320     }
321
322     # allow for anon-subtypes here ...
323     if ( blessed( $options->{isa} )
324         && $options->{isa}->isa('Moose::Meta::TypeConstraint') ) {
325         $options->{type_constraint} = $options->{isa};
326     }
327     else {
328         $options->{type_constraint}
329             = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint(
330             $options->{isa} );
331     }
332 }
333
334 sub _process_does_option {
335     my ( $class, $name, $options ) = @_;
336
337     return unless exists $options->{does} && ! exists $options->{isa};
338
339     # allow for anon-subtypes here ...
340     if ( blessed( $options->{does} )
341         && $options->{does}->isa('Moose::Meta::TypeConstraint') ) {
342         $options->{type_constraint} = $options->{does};
343     }
344     else {
345         $options->{type_constraint}
346             = Moose::Util::TypeConstraints::find_or_create_does_type_constraint(
347             $options->{does} );
348     }
349 }
350
351 sub _process_coerce_option {
352     my ( $class, $name, $options ) = @_;
353
354     return unless $options->{coerce};
355
356     ( exists $options->{type_constraint} )
357         || $class->throw_error(
358         "You cannot have coercion without specifying a type constraint on attribute ($name)",
359         data => $options );
360
361     $class->throw_error(
362         "You cannot have a weak reference to a coerced value on attribute ($name)",
363         data => $options )
364         if $options->{weak_ref};
365
366     unless ( $options->{type_constraint}->has_coercion ) {
367         my $type = $options->{type_constraint}->name;
368
369         Moose::Deprecated::deprecated(
370             feature => 'coerce without coercion',
371             message =>
372                 "You cannot coerce an attribute ($name) unless its type ($type) has a coercion"
373         );
374     }
375 }
376
377 sub _process_trigger_option {
378     my ( $class, $name, $options ) = @_;
379
380     return unless exists $options->{trigger};
381
382     ( 'CODE' eq ref $options->{trigger} )
383         || $class->throw_error("Trigger must be a CODE ref on attribute ($name)", data => $options->{trigger});
384 }
385
386 sub _process_auto_deref_option {
387     my ( $class, $name, $options ) = @_;
388
389     return unless $options->{auto_deref};
390
391     ( exists $options->{type_constraint} )
392         || $class->throw_error(
393         "You cannot auto-dereference without specifying a type constraint on attribute ($name)",
394         data => $options );
395
396     ( $options->{type_constraint}->is_a_type_of('ArrayRef')
397       || $options->{type_constraint}->is_a_type_of('HashRef') )
398         || $class->throw_error(
399         "You cannot auto-dereference anything other than a ArrayRef or HashRef on attribute ($name)",
400         data => $options );
401 }
402
403 sub _process_lazy_build_option {
404     my ( $class, $name, $options ) = @_;
405
406     return unless $options->{lazy_build};
407
408     $class->throw_error(
409         "You can not use lazy_build and default for the same attribute ($name)",
410         data => $options )
411         if exists $options->{default};
412
413     $options->{lazy} = 1;
414     $options->{builder} ||= "_build_${name}";
415
416     if ( $name =~ /^_/ ) {
417         $options->{clearer}   ||= "_clear${name}";
418         $options->{predicate} ||= "_has${name}";
419     }
420     else {
421         $options->{clearer}   ||= "clear_${name}";
422         $options->{predicate} ||= "has_${name}";
423     }
424 }
425
426 sub _process_lazy_option {
427     my ( $class, $name, $options ) = @_;
428
429     return unless $options->{lazy};
430
431     ( exists $options->{default} || defined $options->{builder} )
432         || $class->throw_error(
433         "You cannot have a lazy attribute ($name) without specifying a default value for it",
434         data => $options );
435 }
436
437 sub _process_required_option {
438     my ( $class, $name, $options ) = @_;
439
440     if (
441         $options->{required}
442         && !(
443             ( !exists $options->{init_arg} || defined $options->{init_arg} )
444             || exists $options->{default}
445             || defined $options->{builder}
446         )
447         ) {
448         $class->throw_error(
449             "You cannot have a required attribute ($name) without a default, builder, or an init_arg",
450             data => $options );
451     }
452 }
453
454 sub initialize_instance_slot {
455     my ($self, $meta_instance, $instance, $params) = @_;
456     my $init_arg = $self->init_arg();
457     # try to fetch the init arg from the %params ...
458
459     my $val;
460     my $value_is_set;
461     if ( defined($init_arg) and exists $params->{$init_arg}) {
462         $val = $params->{$init_arg};
463         $value_is_set = 1;
464     }
465     else {
466         # skip it if it's lazy
467         return if $self->is_lazy;
468         # and die if it's required and doesn't have a default value
469         $self->throw_error("Attribute (" . $self->name . ") is required", object => $instance, data => $params)
470             if $self->is_required && !$self->has_default && !$self->has_builder;
471
472         # if nothing was in the %params, we can use the
473         # attribute's default value (if it has one)
474         if ($self->has_default) {
475             $val = $self->default($instance);
476             $value_is_set = 1;
477         }
478         elsif ($self->has_builder) {
479             $val = $self->_call_builder($instance);
480             $value_is_set = 1;
481         }
482     }
483
484     return unless $value_is_set;
485
486     $val = $self->_coerce_and_verify( $val, $instance );
487
488     $self->set_initial_value($instance, $val);
489
490     if ( ref $val && $self->is_weak_ref ) {
491         $self->_weaken_value($instance);
492     }
493 }
494
495 sub _call_builder {
496     my ( $self, $instance ) = @_;
497
498     my $builder = $self->builder();
499
500     return $instance->$builder()
501         if $instance->can( $self->builder );
502
503     $self->throw_error(  blessed($instance)
504             . " does not support builder method '"
505             . $self->builder
506             . "' for attribute '"
507             . $self->name
508             . "'",
509             object => $instance,
510      );
511 }
512
513 ## Slot management
514
515 sub _make_initializer_writer_callback {
516     my $self = shift;
517     my ($meta_instance, $instance, $slot_name) = @_;
518     my $old_callback = $self->SUPER::_make_initializer_writer_callback(@_);
519     return sub {
520         $old_callback->($self->_coerce_and_verify($_[0], $instance));
521     };
522 }
523
524 sub set_value {
525     my ($self, $instance, @args) = @_;
526     my $value = $args[0];
527
528     my $attr_name = quotemeta($self->name);
529
530     if ($self->is_required and not @args) {
531         $self->throw_error("Attribute ($attr_name) is required", object => $instance);
532     }
533
534     $value = $self->_coerce_and_verify( $value, $instance );
535
536     my @old;
537     if ( $self->has_trigger && $self->has_value($instance) ) {
538         @old = $self->get_value($instance, 'for trigger');
539     }
540
541     $self->SUPER::set_value($instance, $value);
542
543     if ( ref $value && $self->is_weak_ref ) {
544         $self->_weaken_value($instance);
545     }
546
547     if ($self->has_trigger) {
548         $self->trigger->($instance, $value, @old);
549     }
550 }
551
552 sub _inline_set_value {
553     my $self = shift;
554     my ($instance, $value, $tc, $coercion, $tc_obj, $for_constructor) = @_;
555
556     my $old     = '@old';
557     my $copy    = '$val';
558     $tc       ||= '$type_constraint';
559     $coercion ||= '$type_coercion';
560     $tc_obj   ||= '$type_constraint_obj';
561
562     my @code;
563     if ($self->_writer_value_needs_copy) {
564         push @code, $self->_inline_copy_value($value, $copy);
565         $value = $copy;
566     }
567
568     # constructors already handle required checks
569     push @code, $self->_inline_check_required
570         unless $for_constructor;
571
572     push @code, $self->_inline_tc_code($value, $tc, $coercion, $tc_obj);
573
574     # constructors do triggers all at once at the end
575     push @code, $self->_inline_get_old_value_for_trigger($instance, $old)
576         unless $for_constructor;
577
578     push @code, (
579         $self->SUPER::_inline_set_value($instance, $value),
580         $self->_inline_weaken_value($instance, $value),
581     );
582
583     # constructors do triggers all at once at the end
584     push @code, $self->_inline_trigger($instance, $value, $old)
585         unless $for_constructor;
586
587     return @code;
588 }
589
590 sub _writer_value_needs_copy {
591     my $self = shift;
592     return $self->should_coerce;
593 }
594
595 sub _inline_copy_value {
596     my $self = shift;
597     my ($value, $copy) = @_;
598
599     return 'my ' . $copy . ' = ' . $value . ';'
600 }
601
602 sub _inline_check_required {
603     my $self = shift;
604
605     return unless $self->is_required;
606
607     my $attr_name = quotemeta($self->name);
608
609     return (
610         'if (@_ < 2) {',
611             $self->_inline_throw_error(
612                 '"Attribute (' . $attr_name . ') is required, so cannot '
613               . 'be set to undef"' # defined $_[1] is not good enough
614             ) . ';',
615         '}',
616     );
617 }
618
619 sub _inline_tc_code {
620     my $self = shift;
621     my ($value, $tc, $coercion, $tc_obj, $is_lazy) = @_;
622     return (
623         $self->_inline_check_coercion(
624             $value, $tc, $coercion, $is_lazy,
625         ),
626         $self->_inline_check_constraint(
627             $value, $tc, $tc_obj, $is_lazy,
628         ),
629     );
630 }
631
632 sub _inline_check_coercion {
633     my $self = shift;
634     my ($value, $tc, $coercion) = @_;
635
636     return unless $self->should_coerce && $self->type_constraint->has_coercion;
637
638     if ( $self->type_constraint->can_be_inlined ) {
639         return (
640             'if (! (' . $self->type_constraint->_inline_check($value) . ')) {',
641                 $value . ' = ' . $coercion . '->(' . $value . ');',
642             '}',
643         );
644     }
645     else {
646         return (
647             'if (!' . $tc . '->(' . $value . ')) {',
648                 $value . ' = ' . $coercion . '->(' . $value . ');',
649             '}',
650         );
651     }
652 }
653
654 sub _inline_check_constraint {
655     my $self = shift;
656     my ($value, $tc, $tc_obj) = @_;
657
658     return unless $self->has_type_constraint;
659
660     my $attr_name = quotemeta($self->name);
661
662     if ( $self->type_constraint->can_be_inlined ) {
663         return (
664             'if (! (' . $self->type_constraint->_inline_check($value) . ')) {',
665                 $self->_inline_throw_error(
666                     '"Attribute (' . $attr_name . ') does not pass the type '
667                   . 'constraint because: " . '
668                   . $tc_obj . '->get_message(' . $value . ')',
669                     'data => ' . $value
670                 ) . ';',
671             '}',
672         );
673     }
674     else {
675         return (
676             'if (!' . $tc . '->(' . $value . ')) {',
677                 $self->_inline_throw_error(
678                     '"Attribute (' . $attr_name . ') does not pass the type '
679                   . 'constraint because: " . '
680                   . $tc_obj . '->get_message(' . $value . ')',
681                     'data => ' . $value
682                 ) . ';',
683             '}',
684         );
685     }
686 }
687
688 sub _inline_get_old_value_for_trigger {
689     my $self = shift;
690     my ($instance, $old) = @_;
691
692     return unless $self->has_trigger;
693
694     return (
695         'my ' . $old . ' = ' . $self->_inline_instance_has($instance),
696             '? ' . $self->_inline_instance_get($instance),
697             ': ();',
698     );
699 }
700
701 sub _inline_weaken_value {
702     my $self = shift;
703     my ($instance, $value) = @_;
704
705     return unless $self->is_weak_ref;
706
707     my $mi = $self->associated_class->get_meta_instance;
708     return (
709         $mi->inline_weaken_slot_value($instance, $self->name, $value),
710             'if ref ' . $value . ';',
711     );
712 }
713
714 sub _inline_trigger {
715     my $self = shift;
716     my ($instance, $value, $old) = @_;
717
718     return unless $self->has_trigger;
719
720     return '$trigger->(' . $instance . ', ' . $value . ', ' . $old . ');';
721 }
722
723 sub _weaken_value {
724     my ( $self, $instance ) = @_;
725
726     my $meta_instance = Class::MOP::Class->initialize( blessed($instance) )
727         ->get_meta_instance;
728
729     $meta_instance->weaken_slot_value( $instance, $self->name );
730 }
731
732 sub get_value {
733     my ($self, $instance, $for_trigger) = @_;
734
735     if ($self->is_lazy) {
736         unless ($self->has_value($instance)) {
737             my $value;
738             if ($self->has_default) {
739                 $value = $self->default($instance);
740             } elsif ( $self->has_builder ) {
741                 $value = $self->_call_builder($instance);
742             }
743
744             $value = $self->_coerce_and_verify( $value, $instance );
745
746             $self->set_initial_value($instance, $value);
747         }
748     }
749
750     if ( $self->should_auto_deref && ! $for_trigger ) {
751
752         my $type_constraint = $self->type_constraint;
753
754         if ($type_constraint->is_a_type_of('ArrayRef')) {
755             my $rv = $self->SUPER::get_value($instance);
756             return unless defined $rv;
757             return wantarray ? @{ $rv } : $rv;
758         }
759         elsif ($type_constraint->is_a_type_of('HashRef')) {
760             my $rv = $self->SUPER::get_value($instance);
761             return unless defined $rv;
762             return wantarray ? %{ $rv } : $rv;
763         }
764         else {
765             $self->throw_error("Can not auto de-reference the type constraint '" . $type_constraint->name . "'", object => $instance, type_constraint => $type_constraint);
766         }
767
768     }
769     else {
770
771         return $self->SUPER::get_value($instance);
772     }
773 }
774
775 sub _inline_get_value {
776     my $self = shift;
777     my ($instance, $tc, $coercion, $tc_obj) = @_;
778
779     my $slot_access = $self->_inline_instance_get($instance);
780     $tc           ||= '$type_constraint';
781     $coercion     ||= '$type_coercion';
782     $tc_obj       ||= '$type_constraint_obj';
783
784     return (
785         $self->_inline_check_lazy($instance, $tc, $coercion, $tc_obj),
786         $self->_inline_return_auto_deref($slot_access),
787     );
788 }
789
790 sub _inline_check_lazy {
791     my $self = shift;
792     my ($instance, $tc, $coercion, $tc_obj) = @_;
793
794     return unless $self->is_lazy;
795
796     my $slot_exists = $self->_inline_instance_has($instance);
797
798     return (
799         'if (!' . $slot_exists . ') {',
800             $self->_inline_init_from_default($instance, '$default', $tc, $coercion, $tc_obj, 'lazy'),
801         '}',
802     );
803 }
804
805 sub _inline_init_from_default {
806     my $self = shift;
807     my ($instance, $default, $tc, $coercion, $tc_obj, $for_lazy) = @_;
808
809     if (!($self->has_default || $self->has_builder)) {
810         $self->throw_error(
811             'You cannot have a lazy attribute '
812           . '(' . $self->name . ') '
813           . 'without specifying a default value for it',
814             attr => $self,
815         );
816     }
817
818     return (
819         $self->_inline_generate_default($instance, $default),
820         # intentionally not using _inline_tc_code, since that can be overridden
821         # to do things like possibly only do member tc checks, which isn't
822         # appropriate for checking the result of a default
823         $self->has_type_constraint
824             ? ($self->_inline_check_coercion($default, $tc, $coercion, $for_lazy),
825                $self->_inline_check_constraint($default, $tc, $tc_obj, $for_lazy))
826             : (),
827         $self->_inline_init_slot($instance, $default),
828     );
829 }
830
831 sub _inline_generate_default {
832     my $self = shift;
833     my ($instance, $default) = @_;
834
835     if ($self->has_default) {
836         my $source = 'my ' . $default . ' = $default';
837         $source .= '->(' . $instance . ')'
838             if $self->is_default_a_coderef;
839         return $source . ';';
840     }
841     elsif ($self->has_builder) {
842         my $builder = B::perlstring($self->builder);
843         my $builder_str = quotemeta($self->builder);
844         my $attr_name_str = quotemeta($self->name);
845         return (
846             'my ' . $default . ';',
847             'if (my $builder = ' . $instance . '->can(' . $builder . ')) {',
848                 $default . ' = ' . $instance . '->$builder;',
849             '}',
850             'else {',
851                 'my $class = ref(' . $instance . ') || ' . $instance . ';',
852                 $self->_inline_throw_error(
853                     '"$class does not support builder method '
854                   . '\'' . $builder_str . '\' for attribute '
855                   . '\'' . $attr_name_str . '\'"'
856                 ) . ';',
857             '}',
858         );
859     }
860     else {
861         $self->throw_error(
862             "Can't generate a default for " . $self->name
863           . " since no default or builder was specified"
864         );
865     }
866 }
867
868 sub _inline_init_slot {
869     my $self = shift;
870     my ($inv, $value) = @_;
871
872     if ($self->has_initializer) {
873         return '$attr->set_initial_value(' . $inv . ', ' . $value . ');';
874     }
875     else {
876         return $self->_inline_instance_set($inv, $value) . ';';
877     }
878 }
879
880 sub _inline_return_auto_deref {
881     my $self = shift;
882
883     return 'return ' . $self->_auto_deref(@_) . ';';
884 }
885
886 sub _auto_deref {
887     my $self = shift;
888     my ($ref_value) = @_;
889
890     return $ref_value unless $self->should_auto_deref;
891
892     my $type_constraint = $self->type_constraint;
893
894     my $sigil;
895     if ($type_constraint->is_a_type_of('ArrayRef')) {
896         $sigil = '@';
897     }
898     elsif ($type_constraint->is_a_type_of('HashRef')) {
899         $sigil = '%';
900     }
901     else {
902         $self->throw_error(
903             'Can not auto de-reference the type constraint \''
904           . $type_constraint->name
905           . '\'',
906             type_constraint => $type_constraint,
907         );
908     }
909
910     return 'wantarray '
911              . '? ' . $sigil . '{ (' . $ref_value . ') || return } '
912              . ': (' . $ref_value . ')';
913 }
914
915 ## installing accessors
916
917 sub accessor_metaclass { 'Moose::Meta::Method::Accessor' }
918
919 sub install_accessors {
920     my $self = shift;
921     $self->SUPER::install_accessors(@_);
922     $self->install_delegation if $self->has_handles;
923     return;
924 }
925
926 sub _check_associated_methods {
927     my $self = shift;
928     unless (
929         @{ $self->associated_methods }
930         || ($self->_is_metadata || '') eq 'bare'
931     ) {
932         Carp::cluck(
933             'Attribute (' . $self->name . ') of class '
934             . $self->associated_class->name
935             . ' has no associated methods'
936             . ' (did you mean to provide an "is" argument?)'
937             . "\n"
938         )
939     }
940 }
941
942 sub _process_accessors {
943     my $self = shift;
944     my ($type, $accessor, $generate_as_inline_methods) = @_;
945
946     $accessor = ( keys %$accessor )[0] if ( ref($accessor) || '' ) eq 'HASH';
947     my $method = $self->associated_class->get_method($accessor);
948
949     if (   $method
950         && $method->isa('Class::MOP::Method::Accessor')
951         && $method->associated_attribute->name ne $self->name ) {
952
953         my $other_attr_name = $method->associated_attribute->name;
954         my $name            = $self->name;
955
956         Carp::cluck(
957             "You are overwriting an accessor ($accessor) for the $other_attr_name attribute"
958                 . " with a new accessor method for the $name attribute" );
959     }
960
961     if (
962            $method
963         && !$method->isa('Class::MOP::Method::Accessor')
964         && (  !$self->definition_context
965             || $method->package_name eq $self->definition_context->{package} )
966         ) {
967
968         Carp::cluck(
969             "You are overwriting a locally defined method ($accessor) with "
970                 . "an accessor" );
971     }
972
973     if (  !$self->associated_class->has_method($accessor)
974         && $self->associated_class->has_package_symbol( '&' . $accessor ) ) {
975
976         Carp::cluck(
977             "You are overwriting a locally defined function ($accessor) with "
978                 . "an accessor" );
979     }
980
981     $self->SUPER::_process_accessors(@_);
982 }
983
984 sub remove_accessors {
985     my $self = shift;
986     $self->SUPER::remove_accessors(@_);
987     $self->remove_delegation if $self->has_handles;
988     return;
989 }
990
991 sub install_delegation {
992     my $self = shift;
993
994     # NOTE:
995     # Here we canonicalize the 'handles' option
996     # this will sort out any details and always
997     # return an hash of methods which we want
998     # to delagate to, see that method for details
999     my %handles = $self->_canonicalize_handles;
1000
1001
1002     # install the delegation ...
1003     my $associated_class = $self->associated_class;
1004     foreach my $handle (keys %handles) {
1005         my $method_to_call = $handles{$handle};
1006         my $class_name = $associated_class->name;
1007         my $name = "${class_name}::${handle}";
1008
1009             (!$associated_class->has_method($handle))
1010                 || $self->throw_error("You cannot overwrite a locally defined method ($handle) with a delegation", method_name => $handle);
1011
1012         # NOTE:
1013         # handles is not allowed to delegate
1014         # any of these methods, as they will
1015         # override the ones in your class, which
1016         # is almost certainly not what you want.
1017
1018         # FIXME warn when $handle was explicitly specified, but not if the source is a regex or something
1019         #cluck("Not delegating method '$handle' because it is a core method") and
1020         next if $class_name->isa("Moose::Object") and $handle =~ /^BUILD|DEMOLISH$/ || Moose::Object->can($handle);
1021
1022         my $method = $self->_make_delegation_method($handle, $method_to_call);
1023
1024         $self->associated_class->add_method($method->name, $method);
1025         $self->associate_method($method);
1026     }
1027 }
1028
1029 sub remove_delegation {
1030     my $self = shift;
1031     my %handles = $self->_canonicalize_handles;
1032     my $associated_class = $self->associated_class;
1033     foreach my $handle (keys %handles) {
1034         next unless any { $handle eq $_ }
1035                     map { $_->name }
1036                     @{ $self->associated_methods };
1037         $self->associated_class->remove_method($handle);
1038     }
1039 }
1040
1041 # private methods to help delegation ...
1042
1043 sub _canonicalize_handles {
1044     my $self    = shift;
1045     my $handles = $self->handles;
1046     if (my $handle_type = ref($handles)) {
1047         if ($handle_type eq 'HASH') {
1048             return %{$handles};
1049         }
1050         elsif ($handle_type eq 'ARRAY') {
1051             return map { $_ => $_ } @{$handles};
1052         }
1053         elsif ($handle_type eq 'Regexp') {
1054             ($self->has_type_constraint)
1055                 || $self->throw_error("Cannot delegate methods based on a Regexp without a type constraint (isa)", data => $handles);
1056             return map  { ($_ => $_) }
1057                    grep { /$handles/ } $self->_get_delegate_method_list;
1058         }
1059         elsif ($handle_type eq 'CODE') {
1060             return $handles->($self, $self->_find_delegate_metaclass);
1061         }
1062         elsif (blessed($handles) && $handles->isa('Moose::Meta::TypeConstraint::DuckType')) {
1063             return map { $_ => $_ } @{ $handles->methods };
1064         }
1065         elsif (blessed($handles) && $handles->isa('Moose::Meta::TypeConstraint::Role')) {
1066             $handles = $handles->role;
1067         }
1068         else {
1069             $self->throw_error("Unable to canonicalize the 'handles' option with $handles", data => $handles);
1070         }
1071     }
1072
1073     Class::MOP::load_class($handles);
1074     my $role_meta = Class::MOP::class_of($handles);
1075
1076     (blessed $role_meta && $role_meta->isa('Moose::Meta::Role'))
1077         || $self->throw_error("Unable to canonicalize the 'handles' option with $handles because its metaclass is not a Moose::Meta::Role", data => $handles);
1078
1079     return map { $_ => $_ }
1080         map { $_->name }
1081         grep { !$_->isa('Class::MOP::Method::Meta') } (
1082         $role_meta->_get_local_methods,
1083         $role_meta->get_required_method_list,
1084         );
1085 }
1086
1087 sub _get_delegate_method_list {
1088     my $self = shift;
1089     my $meta = $self->_find_delegate_metaclass;
1090     if ($meta->isa('Class::MOP::Class')) {
1091         return map  { $_->name }  # NOTE: !never! delegate &meta
1092                grep { $_->package_name ne 'Moose::Object' && !$_->isa('Class::MOP::Method::Meta') }
1093                     $meta->get_all_methods;
1094     }
1095     elsif ($meta->isa('Moose::Meta::Role')) {
1096         return $meta->get_method_list;
1097     }
1098     else {
1099         $self->throw_error("Unable to recognize the delegate metaclass '$meta'", data => $meta);
1100     }
1101 }
1102
1103 sub _find_delegate_metaclass {
1104     my $self = shift;
1105     if (my $class = $self->_isa_metadata) {
1106         unless ( Class::MOP::is_class_loaded($class) ) {
1107             $self->throw_error(
1108                 sprintf(
1109                     'The %s attribute is trying to delegate to a class which has not been loaded - %s',
1110                     $self->name, $class
1111                 )
1112             );
1113         }
1114         # we might be dealing with a non-Moose class,
1115         # and need to make our own metaclass. if there's
1116         # already a metaclass, it will be returned
1117         return Class::MOP::Class->initialize($class);
1118     }
1119     elsif (my $role = $self->_does_metadata) {
1120         unless ( Class::MOP::is_class_loaded($class) ) {
1121             $self->throw_error(
1122                 sprintf(
1123                     'The %s attribute is trying to delegate to a role which has not been loaded - %s',
1124                     $self->name, $role
1125                 )
1126             );
1127         }
1128
1129         return Class::MOP::class_of($role);
1130     }
1131     else {
1132         $self->throw_error("Cannot find delegate metaclass for attribute " . $self->name);
1133     }
1134 }
1135
1136 sub delegation_metaclass { 'Moose::Meta::Method::Delegation' }
1137
1138 sub _make_delegation_method {
1139     my ( $self, $handle_name, $method_to_call ) = @_;
1140
1141     my @curried_arguments;
1142
1143     ($method_to_call, @curried_arguments) = @$method_to_call
1144         if 'ARRAY' eq ref($method_to_call);
1145
1146     return $self->delegation_metaclass->new(
1147         name               => $handle_name,
1148         package_name       => $self->associated_class->name,
1149         attribute          => $self,
1150         delegate_to_method => $method_to_call,
1151         curried_arguments  => \@curried_arguments,
1152     );
1153 }
1154
1155 sub _coerce_and_verify {
1156     my $self     = shift;
1157     my $val      = shift;
1158     my $instance = shift;
1159
1160     return $val unless $self->has_type_constraint;
1161
1162     $val = $self->type_constraint->coerce($val)
1163         if $self->should_coerce && $self->type_constraint->has_coercion;
1164
1165     $self->verify_against_type_constraint($val, instance => $instance);
1166
1167     return $val;
1168 }
1169
1170 sub verify_against_type_constraint {
1171     my $self = shift;
1172     my $val  = shift;
1173
1174     return 1 if !$self->has_type_constraint;
1175
1176     my $type_constraint = $self->type_constraint;
1177
1178     $type_constraint->check($val)
1179         || $self->throw_error("Attribute ("
1180                  . $self->name
1181                  . ") does not pass the type constraint because: "
1182                  . $type_constraint->get_message($val), data => $val, @_);
1183 }
1184
1185 package Moose::Meta::Attribute::Custom::Moose;
1186 sub register_implementation { 'Moose::Meta::Attribute' }
1187
1188 1;
1189
1190 # ABSTRACT: The Moose attribute metaclass
1191
1192 __END__
1193
1194 =pod
1195
1196 =head1 DESCRIPTION
1197
1198 This class is a subclass of L<Class::MOP::Attribute> that provides
1199 additional Moose-specific functionality.
1200
1201 To really understand this class, you will need to start with the
1202 L<Class::MOP::Attribute> documentation. This class can be understood
1203 as a set of additional features on top of the basic feature provided
1204 by that parent class.
1205
1206 =head1 INHERITANCE
1207
1208 C<Moose::Meta::Attribute> is a subclass of L<Class::MOP::Attribute>.
1209
1210 =head1 METHODS
1211
1212 Many of the documented below override methods in
1213 L<Class::MOP::Attribute> and add Moose specific features.
1214
1215 =head2 Creation
1216
1217 =over 4
1218
1219 =item B<< Moose::Meta::Attribute->new(%options) >>
1220
1221 This method overrides the L<Class::MOP::Attribute> constructor.
1222
1223 Many of the options below are described in more detail in the
1224 L<Moose::Manual::Attributes> document.
1225
1226 It adds the following options to the constructor:
1227
1228 =over 8
1229
1230 =item * is => 'ro', 'rw', 'bare'
1231
1232 This provides a shorthand for specifying the C<reader>, C<writer>, or
1233 C<accessor> names. If the attribute is read-only ('ro') then it will
1234 have a C<reader> method with the same attribute as the name.
1235
1236 If it is read-write ('rw') then it will have an C<accessor> method
1237 with the same name. If you provide an explicit C<writer> for a
1238 read-write attribute, then you will have a C<reader> with the same
1239 name as the attribute, and a C<writer> with the name you provided.
1240
1241 Use 'bare' when you are deliberately not installing any methods
1242 (accessor, reader, etc.) associated with this attribute; otherwise,
1243 Moose will issue a deprecation warning when this attribute is added to a
1244 metaclass.
1245
1246 =item * isa => $type
1247
1248 This option accepts a type. The type can be a string, which should be
1249 a type name. If the type name is unknown, it is assumed to be a class
1250 name.
1251
1252 This option can also accept a L<Moose::Meta::TypeConstraint> object.
1253
1254 If you I<also> provide a C<does> option, then your C<isa> option must
1255 be a class name, and that class must do the role specified with
1256 C<does>.
1257
1258 =item * does => $role
1259
1260 This is short-hand for saying that the attribute's type must be an
1261 object which does the named role.
1262
1263 =item * coerce => $bool
1264
1265 This option is only valid for objects with a type constraint
1266 (C<isa>) that defined a coercion. If this is true, then coercions will be applied whenever
1267 this attribute is set.
1268
1269 You can make both this and the C<weak_ref> option true.
1270
1271 =item * trigger => $sub
1272
1273 This option accepts a subroutine reference, which will be called after
1274 the attribute is set.
1275
1276 =item * required => $bool
1277
1278 An attribute which is required must be provided to the constructor. An
1279 attribute which is required can also have a C<default> or C<builder>,
1280 which will satisfy its required-ness.
1281
1282 A required attribute must have a C<default>, C<builder> or a
1283 non-C<undef> C<init_arg>
1284
1285 =item * lazy => $bool
1286
1287 A lazy attribute must have a C<default> or C<builder>. When an
1288 attribute is lazy, the default value will not be calculated until the
1289 attribute is read.
1290
1291 =item * weak_ref => $bool
1292
1293 If this is true, the attribute's value will be stored as a weak
1294 reference.
1295
1296 =item * auto_deref => $bool
1297
1298 If this is true, then the reader will dereference the value when it is
1299 called. The attribute must have a type constraint which defines the
1300 attribute as an array or hash reference.
1301
1302 =item * lazy_build => $bool
1303
1304 Setting this to true makes the attribute lazy and provides a number of
1305 default methods.
1306
1307   has 'size' => (
1308       is         => 'ro',
1309       lazy_build => 1,
1310   );
1311
1312 is equivalent to this:
1313
1314   has 'size' => (
1315       is        => 'ro',
1316       lazy      => 1,
1317       builder   => '_build_size',
1318       clearer   => 'clear_size',
1319       predicate => 'has_size',
1320   );
1321
1322
1323 If your attribute name starts with an underscore (C<_>), then the clearer
1324 and predicate will as well:
1325
1326   has '_size' => (
1327       is         => 'ro',
1328       lazy_build => 1,
1329   );
1330
1331 becomes:
1332
1333   has '_size' => (
1334       is        => 'ro',
1335       lazy      => 1,
1336       builder   => '_build__size',
1337       clearer   => '_clear_size',
1338       predicate => '_has_size',
1339   );
1340
1341 Note the doubled underscore in the builder name. Internally, Moose
1342 simply prepends the attribute name with "_build_" to come up with the
1343 builder name.
1344
1345 =item * documentation
1346
1347 An arbitrary string that can be retrieved later by calling C<<
1348 $attr->documentation >>.
1349
1350 =back
1351
1352 =item B<< $attr->clone(%options) >>
1353
1354 This creates a new attribute based on attribute being cloned. You must
1355 supply a C<name> option to provide a new name for the attribute.
1356
1357 The C<%options> can only specify options handled by
1358 L<Class::MOP::Attribute>.
1359
1360 =back
1361
1362 =head2 Value management
1363
1364 =over 4
1365
1366 =item B<< $attr->initialize_instance_slot($meta_instance, $instance, $params) >>
1367
1368 This method is used internally to initialize the attribute's slot in
1369 the object C<$instance>.
1370
1371 This overrides the L<Class::MOP::Attribute> method to handle lazy
1372 attributes, weak references, and type constraints.
1373
1374 =item B<get_value>
1375
1376 =item B<set_value>
1377
1378   eval { $point->meta->get_attribute('x')->set_value($point, 'forty-two') };
1379   if($@) {
1380     print "Oops: $@\n";
1381   }
1382
1383 I<Attribute (x) does not pass the type constraint (Int) with 'forty-two'>
1384
1385 Before setting the value, a check is made on the type constraint of
1386 the attribute, if it has one, to see if the value passes it. If the
1387 value fails to pass, the set operation dies with a L</throw_error>.
1388
1389 Any coercion to convert values is done before checking the type constraint.
1390
1391 To check a value against a type constraint before setting it, fetch the
1392 attribute instance using L<Class::MOP::Class/find_attribute_by_name>,
1393 fetch the type_constraint from the attribute using L<Moose::Meta::Attribute/type_constraint>
1394 and call L<Moose::Meta::TypeConstraint/check>. See L<Moose::Cookbook::Basics::Recipe4>
1395 for an example.
1396
1397 =back
1398
1399 =head2 Attribute Accessor generation
1400
1401 =over 4
1402
1403 =item B<< $attr->install_accessors >>
1404
1405 This method overrides the parent to also install delegation methods.
1406
1407 If, after installing all methods, the attribute object has no associated
1408 methods, it throws an error unless C<< is => 'bare' >> was passed to the
1409 attribute constructor.  (Trying to add an attribute that has no associated
1410 methods is almost always an error.)
1411
1412 =item B<< $attr->remove_accessors >>
1413
1414 This method overrides the parent to also remove delegation methods.
1415
1416 =item B<< $attr->inline_set($instance_var, $value_var) >>
1417
1418 This method return a code snippet suitable for inlining the relevant
1419 operation. It expect strings containing variable names to be used in the
1420 inlining, like C<'$self'> or C<'$_[1]'>.
1421
1422 =item B<< $attr->install_delegation >>
1423
1424 This method adds its delegation methods to the attribute's associated
1425 class, if it has any to add.
1426
1427 =item B<< $attr->remove_delegation >>
1428
1429 This method remove its delegation methods from the attribute's
1430 associated class.
1431
1432 =item B<< $attr->accessor_metaclass >>
1433
1434 Returns the accessor metaclass name, which defaults to
1435 L<Moose::Meta::Method::Accessor>.
1436
1437 =item B<< $attr->delegation_metaclass >>
1438
1439 Returns the delegation metaclass name, which defaults to
1440 L<Moose::Meta::Method::Delegation>.
1441
1442 =back
1443
1444 =head2 Additional Moose features
1445
1446 These methods are not found in the superclass. They support features
1447 provided by Moose.
1448
1449 =over 4
1450
1451 =item B<< $attr->does($role) >>
1452
1453 This indicates whether the I<attribute itself> does the given
1454 role. The role can be given as a full class name, or as a resolvable
1455 trait name.
1456
1457 Note that this checks the attribute itself, not its type constraint,
1458 so it is checking the attribute's metaclass and any traits applied to
1459 the attribute.
1460
1461 =item B<< Moose::Meta::Class->interpolate_class_and_new($name, %options) >>
1462
1463 This is an alternate constructor that handles the C<metaclass> and
1464 C<traits> options.
1465
1466 Effectively, this method is a factory that finds or creates the
1467 appropriate class for the given C<metaclass> and/or C<traits>.
1468
1469 Once it has the appropriate class, it will call C<< $class->new($name,
1470 %options) >> on that class.
1471
1472 =item B<< $attr->clone_and_inherit_options(%options) >>
1473
1474 This method supports the C<has '+foo'> feature. It does various bits
1475 of processing on the supplied C<%options> before ultimately calling
1476 the C<clone> method.
1477
1478 One of its main tasks is to make sure that the C<%options> provided
1479 does not include the options returned by the
1480 C<illegal_options_for_inheritance> method.
1481
1482 =item B<< $attr->illegal_options_for_inheritance >>
1483
1484 This returns a blacklist of options that can not be overridden in a
1485 subclass's attribute definition.
1486
1487 This exists to allow a custom metaclass to change or add to the list
1488 of options which can not be changed.
1489
1490 =item B<< $attr->type_constraint >>
1491
1492 Returns the L<Moose::Meta::TypeConstraint> object for this attribute,
1493 if it has one.
1494
1495 =item B<< $attr->has_type_constraint >>
1496
1497 Returns true if this attribute has a type constraint.
1498
1499 =item B<< $attr->verify_against_type_constraint($value) >>
1500
1501 Given a value, this method returns true if the value is valid for the
1502 attribute's type constraint. If the value is not valid, it throws an
1503 error.
1504
1505 =item B<< $attr->handles >>
1506
1507 This returns the value of the C<handles> option passed to the
1508 constructor.
1509
1510 =item B<< $attr->has_handles >>
1511
1512 Returns true if this attribute performs delegation.
1513
1514 =item B<< $attr->is_weak_ref >>
1515
1516 Returns true if this attribute stores its value as a weak reference.
1517
1518 =item B<< $attr->is_required >>
1519
1520 Returns true if this attribute is required to have a value.
1521
1522 =item B<< $attr->is_lazy >>
1523
1524 Returns true if this attribute is lazy.
1525
1526 =item B<< $attr->is_lazy_build >>
1527
1528 Returns true if the C<lazy_build> option was true when passed to the
1529 constructor.
1530
1531 =item B<< $attr->should_coerce >>
1532
1533 Returns true if the C<coerce> option passed to the constructor was
1534 true.
1535
1536 =item B<< $attr->should_auto_deref >>
1537
1538 Returns true if the C<auto_deref> option passed to the constructor was
1539 true.
1540
1541 =item B<< $attr->trigger >>
1542
1543 This is the subroutine reference that was in the C<trigger> option
1544 passed to the constructor, if any.
1545
1546 =item B<< $attr->has_trigger >>
1547
1548 Returns true if this attribute has a trigger set.
1549
1550 =item B<< $attr->documentation >>
1551
1552 Returns the value that was in the C<documentation> option passed to
1553 the constructor, if any.
1554
1555 =item B<< $attr->has_documentation >>
1556
1557 Returns true if this attribute has any documentation.
1558
1559 =item B<< $attr->applied_traits >>
1560
1561 This returns an array reference of all the traits which were applied
1562 to this attribute. If none were applied, this returns C<undef>.
1563
1564 =item B<< $attr->has_applied_traits >>
1565
1566 Returns true if this attribute has any traits applied.
1567
1568 =back
1569
1570 =head1 BUGS
1571
1572 See L<Moose/BUGS> for details on reporting bugs.
1573
1574 =cut