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