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