e97a5df0b51175d723c12b6bf877f025cb3e8530
[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->is_stub
1041         && !$method->isa('Class::MOP::Method::Accessor')
1042         && (  !$self->definition_context
1043             || $method->package_name eq $self->definition_context->{package} )
1044         ) {
1045
1046         Carp::cluck(
1047             "You are overwriting a locally defined method ($accessor) with "
1048                 . "an accessor" );
1049     }
1050
1051     if (  !$self->associated_class->has_method($accessor)
1052         && $self->associated_class->has_package_symbol( '&' . $accessor ) ) {
1053
1054         Carp::cluck(
1055             "You are overwriting a locally defined function ($accessor) with "
1056                 . "an accessor" );
1057     }
1058
1059     $self->SUPER::_process_accessors(@_);
1060 }
1061
1062 sub remove_accessors {
1063     my $self = shift;
1064     $self->SUPER::remove_accessors(@_);
1065     $self->remove_delegation if $self->has_handles;
1066     return;
1067 }
1068
1069 sub install_delegation {
1070     my $self = shift;
1071
1072     # NOTE:
1073     # Here we canonicalize the 'handles' option
1074     # this will sort out any details and always
1075     # return an hash of methods which we want
1076     # to delagate to, see that method for details
1077     my %handles = $self->_canonicalize_handles;
1078
1079
1080     # install the delegation ...
1081     my $associated_class = $self->associated_class;
1082     foreach my $handle (sort keys %handles) {
1083         my $method_to_call = $handles{$handle};
1084         my $class_name = $associated_class->name;
1085         my $name = "${class_name}::${handle}";
1086
1087         ( !$associated_class->has_method($handle) )
1088             || $self->throw_error(
1089             "You cannot overwrite a locally defined method ($handle) with a delegation",
1090             method_name => $handle );
1091
1092         # NOTE:
1093         # handles is not allowed to delegate
1094         # any of these methods, as they will
1095         # override the ones in your class, which
1096         # is almost certainly not what you want.
1097
1098         # FIXME warn when $handle was explicitly specified, but not if the source is a regex or something
1099         #cluck("Not delegating method '$handle' because it is a core method") and
1100         next if $class_name->isa("Moose::Object") and $handle =~ /^BUILD|DEMOLISH$/ || Moose::Object->can($handle);
1101
1102         my $method = $self->_make_delegation_method($handle, $method_to_call);
1103
1104         $self->associated_class->add_method($method->name, $method);
1105         $self->associate_method($method);
1106     }
1107 }
1108
1109 sub remove_delegation {
1110     my $self = shift;
1111     my %handles = $self->_canonicalize_handles;
1112     my $associated_class = $self->associated_class;
1113     foreach my $handle (keys %handles) {
1114         next unless any { $handle eq $_ }
1115                     map { $_->name }
1116                     @{ $self->associated_methods };
1117         $self->associated_class->remove_method($handle);
1118     }
1119 }
1120
1121 # private methods to help delegation ...
1122
1123 sub _canonicalize_handles {
1124     my $self    = shift;
1125     my $handles = $self->handles;
1126     if (my $handle_type = ref($handles)) {
1127         if ($handle_type eq 'HASH') {
1128             return %{$handles};
1129         }
1130         elsif ($handle_type eq 'ARRAY') {
1131             return map { $_ => $_ } @{$handles};
1132         }
1133         elsif ($handle_type eq 'Regexp') {
1134             ($self->has_type_constraint)
1135                 || $self->throw_error("Cannot delegate methods based on a Regexp without a type constraint (isa)", data => $handles);
1136             return map  { ($_ => $_) }
1137                    grep { /$handles/ } $self->_get_delegate_method_list;
1138         }
1139         elsif ($handle_type eq 'CODE') {
1140             return $handles->($self, $self->_find_delegate_metaclass);
1141         }
1142         elsif (blessed($handles) && $handles->isa('Moose::Meta::TypeConstraint::DuckType')) {
1143             return map { $_ => $_ } @{ $handles->methods };
1144         }
1145         elsif (blessed($handles) && $handles->isa('Moose::Meta::TypeConstraint::Role')) {
1146             $handles = $handles->role;
1147         }
1148         else {
1149             $self->throw_error("Unable to canonicalize the 'handles' option with $handles", data => $handles);
1150         }
1151     }
1152
1153     load_class($handles);
1154     my $role_meta = Class::MOP::class_of($handles);
1155
1156     (blessed $role_meta && $role_meta->isa('Moose::Meta::Role'))
1157         || $self->throw_error("Unable to canonicalize the 'handles' option with $handles because its metaclass is not a Moose::Meta::Role", data => $handles);
1158
1159     return map { $_ => $_ }
1160         map { $_->name }
1161         grep { !$_->isa('Class::MOP::Method::Meta') } (
1162         $role_meta->_get_local_methods,
1163         $role_meta->get_required_method_list,
1164         );
1165 }
1166
1167 sub _get_delegate_method_list {
1168     my $self = shift;
1169     my $meta = $self->_find_delegate_metaclass;
1170     if ($meta->isa('Class::MOP::Class')) {
1171         return map  { $_->name }  # NOTE: !never! delegate &meta
1172                grep { $_->package_name ne 'Moose::Object' && !$_->isa('Class::MOP::Method::Meta') }
1173                     $meta->get_all_methods;
1174     }
1175     elsif ($meta->isa('Moose::Meta::Role')) {
1176         return $meta->get_method_list;
1177     }
1178     else {
1179         $self->throw_error("Unable to recognize the delegate metaclass '$meta'", data => $meta);
1180     }
1181 }
1182
1183 sub _find_delegate_metaclass {
1184     my $self = shift;
1185     if (my $class = $self->_isa_metadata) {
1186         unless ( is_class_loaded($class) ) {
1187             $self->throw_error(
1188                 sprintf(
1189                     'The %s attribute is trying to delegate to a class which has not been loaded - %s',
1190                     $self->name, $class
1191                 )
1192             );
1193         }
1194         # we might be dealing with a non-Moose class,
1195         # and need to make our own metaclass. if there's
1196         # already a metaclass, it will be returned
1197         return Class::MOP::Class->initialize($class);
1198     }
1199     elsif (my $role = $self->_does_metadata) {
1200         unless ( is_class_loaded($class) ) {
1201             $self->throw_error(
1202                 sprintf(
1203                     'The %s attribute is trying to delegate to a role which has not been loaded - %s',
1204                     $self->name, $role
1205                 )
1206             );
1207         }
1208
1209         return Class::MOP::class_of($role);
1210     }
1211     else {
1212         $self->throw_error("Cannot find delegate metaclass for attribute " . $self->name);
1213     }
1214 }
1215
1216 sub delegation_metaclass { 'Moose::Meta::Method::Delegation' }
1217
1218 sub _make_delegation_method {
1219     my ( $self, $handle_name, $method_to_call ) = @_;
1220
1221     my @curried_arguments;
1222
1223     ($method_to_call, @curried_arguments) = @$method_to_call
1224         if 'ARRAY' eq ref($method_to_call);
1225
1226     return $self->delegation_metaclass->new(
1227         name               => $handle_name,
1228         package_name       => $self->associated_class->name,
1229         attribute          => $self,
1230         delegate_to_method => $method_to_call,
1231         curried_arguments  => \@curried_arguments,
1232     );
1233 }
1234
1235 sub _coerce_and_verify {
1236     my $self     = shift;
1237     my $val      = shift;
1238     my $instance = shift;
1239
1240     return $val unless $self->has_type_constraint;
1241
1242     $val = $self->type_constraint->coerce($val)
1243         if $self->should_coerce && $self->type_constraint->has_coercion;
1244
1245     $self->verify_against_type_constraint($val, instance => $instance);
1246
1247     return $val;
1248 }
1249
1250 sub verify_against_type_constraint {
1251     my $self = shift;
1252     my $val  = shift;
1253
1254     return 1 if !$self->has_type_constraint;
1255
1256     my $type_constraint = $self->type_constraint;
1257
1258     $type_constraint->check($val)
1259         || $self->throw_error("Attribute ("
1260                  . $self->name
1261                  . ") does not pass the type constraint because: "
1262                  . $type_constraint->get_message($val), data => $val, @_);
1263 }
1264
1265 package Moose::Meta::Attribute::Custom::Moose;
1266 sub register_implementation { 'Moose::Meta::Attribute' }
1267
1268 1;
1269
1270 # ABSTRACT: The Moose attribute metaclass
1271
1272 __END__
1273
1274 =pod
1275
1276 =head1 DESCRIPTION
1277
1278 This class is a subclass of L<Class::MOP::Attribute> that provides
1279 additional Moose-specific functionality.
1280
1281 To really understand this class, you will need to start with the
1282 L<Class::MOP::Attribute> documentation. This class can be understood
1283 as a set of additional features on top of the basic feature provided
1284 by that parent class.
1285
1286 =head1 INHERITANCE
1287
1288 C<Moose::Meta::Attribute> is a subclass of L<Class::MOP::Attribute>.
1289
1290 =head1 METHODS
1291
1292 Many of the documented below override methods in
1293 L<Class::MOP::Attribute> and add Moose specific features.
1294
1295 =head2 Creation
1296
1297 =over 4
1298
1299 =item B<< Moose::Meta::Attribute->new(%options) >>
1300
1301 This method overrides the L<Class::MOP::Attribute> constructor.
1302
1303 Many of the options below are described in more detail in the
1304 L<Moose::Manual::Attributes> document.
1305
1306 It adds the following options to the constructor:
1307
1308 =over 8
1309
1310 =item * is => 'ro', 'rw', 'bare'
1311
1312 This provides a shorthand for specifying the C<reader>, C<writer>, or
1313 C<accessor> names. If the attribute is read-only ('ro') then it will
1314 have a C<reader> method with the same attribute as the name.
1315
1316 If it is read-write ('rw') then it will have an C<accessor> method
1317 with the same name. If you provide an explicit C<writer> for a
1318 read-write attribute, then you will have a C<reader> with the same
1319 name as the attribute, and a C<writer> with the name you provided.
1320
1321 Use 'bare' when you are deliberately not installing any methods
1322 (accessor, reader, etc.) associated with this attribute; otherwise,
1323 Moose will issue a deprecation warning when this attribute is added to a
1324 metaclass.
1325
1326 =item * isa => $type
1327
1328 This option accepts a type. The type can be a string, which should be
1329 a type name. If the type name is unknown, it is assumed to be a class
1330 name.
1331
1332 This option can also accept a L<Moose::Meta::TypeConstraint> object.
1333
1334 If you I<also> provide a C<does> option, then your C<isa> option must
1335 be a class name, and that class must do the role specified with
1336 C<does>.
1337
1338 =item * does => $role
1339
1340 This is short-hand for saying that the attribute's type must be an
1341 object which does the named role.
1342
1343 =item * coerce => $bool
1344
1345 This option is only valid for objects with a type constraint
1346 (C<isa>) that defined a coercion. If this is true, then coercions will be applied whenever
1347 this attribute is set.
1348
1349 You can make both this and the C<weak_ref> option true.
1350
1351 =item * trigger => $sub
1352
1353 This option accepts a subroutine reference, which will be called after
1354 the attribute is set.
1355
1356 =item * required => $bool
1357
1358 An attribute which is required must be provided to the constructor. An
1359 attribute which is required can also have a C<default> or C<builder>,
1360 which will satisfy its required-ness.
1361
1362 A required attribute must have a C<default>, C<builder> or a
1363 non-C<undef> C<init_arg>
1364
1365 =item * lazy => $bool
1366
1367 A lazy attribute must have a C<default> or C<builder>. When an
1368 attribute is lazy, the default value will not be calculated until the
1369 attribute is read.
1370
1371 =item * weak_ref => $bool
1372
1373 If this is true, the attribute's value will be stored as a weak
1374 reference.
1375
1376 =item * auto_deref => $bool
1377
1378 If this is true, then the reader will dereference the value when it is
1379 called. The attribute must have a type constraint which defines the
1380 attribute as an array or hash reference.
1381
1382 =item * lazy_build => $bool
1383
1384 Setting this to true makes the attribute lazy and provides a number of
1385 default methods.
1386
1387   has 'size' => (
1388       is         => 'ro',
1389       lazy_build => 1,
1390   );
1391
1392 is equivalent to this:
1393
1394   has 'size' => (
1395       is        => 'ro',
1396       lazy      => 1,
1397       builder   => '_build_size',
1398       clearer   => 'clear_size',
1399       predicate => 'has_size',
1400   );
1401
1402
1403 If your attribute name starts with an underscore (C<_>), then the clearer
1404 and predicate will as well:
1405
1406   has '_size' => (
1407       is         => 'ro',
1408       lazy_build => 1,
1409   );
1410
1411 becomes:
1412
1413   has '_size' => (
1414       is        => 'ro',
1415       lazy      => 1,
1416       builder   => '_build__size',
1417       clearer   => '_clear_size',
1418       predicate => '_has_size',
1419   );
1420
1421 Note the doubled underscore in the builder name. Internally, Moose
1422 simply prepends the attribute name with "_build_" to come up with the
1423 builder name.
1424
1425 =item * documentation
1426
1427 An arbitrary string that can be retrieved later by calling C<<
1428 $attr->documentation >>.
1429
1430 =back
1431
1432 =item B<< $attr->clone(%options) >>
1433
1434 This creates a new attribute based on attribute being cloned. You must
1435 supply a C<name> option to provide a new name for the attribute.
1436
1437 The C<%options> can only specify options handled by
1438 L<Class::MOP::Attribute>.
1439
1440 =back
1441
1442 =head2 Value management
1443
1444 =over 4
1445
1446 =item B<< $attr->initialize_instance_slot($meta_instance, $instance, $params) >>
1447
1448 This method is used internally to initialize the attribute's slot in
1449 the object C<$instance>.
1450
1451 This overrides the L<Class::MOP::Attribute> method to handle lazy
1452 attributes, weak references, and type constraints.
1453
1454 =item B<get_value>
1455
1456 =item B<set_value>
1457
1458   eval { $point->meta->get_attribute('x')->set_value($point, 'forty-two') };
1459   if($@) {
1460     print "Oops: $@\n";
1461   }
1462
1463 I<Attribute (x) does not pass the type constraint (Int) with 'forty-two'>
1464
1465 Before setting the value, a check is made on the type constraint of
1466 the attribute, if it has one, to see if the value passes it. If the
1467 value fails to pass, the set operation dies with a L</throw_error>.
1468
1469 Any coercion to convert values is done before checking the type constraint.
1470
1471 To check a value against a type constraint before setting it, fetch the
1472 attribute instance using L<Class::MOP::Class/find_attribute_by_name>,
1473 fetch the type_constraint from the attribute using L<Moose::Meta::Attribute/type_constraint>
1474 and call L<Moose::Meta::TypeConstraint/check>. See L<Moose::Cookbook::Basics::Recipe4>
1475 for an example.
1476
1477 =back
1478
1479 =head2 Attribute Accessor generation
1480
1481 =over 4
1482
1483 =item B<< $attr->install_accessors >>
1484
1485 This method overrides the parent to also install delegation methods.
1486
1487 If, after installing all methods, the attribute object has no associated
1488 methods, it throws an error unless C<< is => 'bare' >> was passed to the
1489 attribute constructor.  (Trying to add an attribute that has no associated
1490 methods is almost always an error.)
1491
1492 =item B<< $attr->remove_accessors >>
1493
1494 This method overrides the parent to also remove delegation methods.
1495
1496 =item B<< $attr->inline_set($instance_var, $value_var) >>
1497
1498 This method return a code snippet suitable for inlining the relevant
1499 operation. It expect strings containing variable names to be used in the
1500 inlining, like C<'$self'> or C<'$_[1]'>.
1501
1502 =item B<< $attr->install_delegation >>
1503
1504 This method adds its delegation methods to the attribute's associated
1505 class, if it has any to add.
1506
1507 =item B<< $attr->remove_delegation >>
1508
1509 This method remove its delegation methods from the attribute's
1510 associated class.
1511
1512 =item B<< $attr->accessor_metaclass >>
1513
1514 Returns the accessor metaclass name, which defaults to
1515 L<Moose::Meta::Method::Accessor>.
1516
1517 =item B<< $attr->delegation_metaclass >>
1518
1519 Returns the delegation metaclass name, which defaults to
1520 L<Moose::Meta::Method::Delegation>.
1521
1522 =back
1523
1524 =head2 Additional Moose features
1525
1526 These methods are not found in the superclass. They support features
1527 provided by Moose.
1528
1529 =over 4
1530
1531 =item B<< $attr->does($role) >>
1532
1533 This indicates whether the I<attribute itself> does the given
1534 role. The role can be given as a full class name, or as a resolvable
1535 trait name.
1536
1537 Note that this checks the attribute itself, not its type constraint,
1538 so it is checking the attribute's metaclass and any traits applied to
1539 the attribute.
1540
1541 =item B<< Moose::Meta::Class->interpolate_class_and_new($name, %options) >>
1542
1543 This is an alternate constructor that handles the C<metaclass> and
1544 C<traits> options.
1545
1546 Effectively, this method is a factory that finds or creates the
1547 appropriate class for the given C<metaclass> and/or C<traits>.
1548
1549 Once it has the appropriate class, it will call C<< $class->new($name,
1550 %options) >> on that class.
1551
1552 =item B<< $attr->clone_and_inherit_options(%options) >>
1553
1554 This method supports the C<has '+foo'> feature. It does various bits
1555 of processing on the supplied C<%options> before ultimately calling
1556 the C<clone> method.
1557
1558 One of its main tasks is to make sure that the C<%options> provided
1559 does not include the options returned by the
1560 C<illegal_options_for_inheritance> method.
1561
1562 =item B<< $attr->illegal_options_for_inheritance >>
1563
1564 This returns a blacklist of options that can not be overridden in a
1565 subclass's attribute definition.
1566
1567 This exists to allow a custom metaclass to change or add to the list
1568 of options which can not be changed.
1569
1570 =item B<< $attr->type_constraint >>
1571
1572 Returns the L<Moose::Meta::TypeConstraint> object for this attribute,
1573 if it has one.
1574
1575 =item B<< $attr->has_type_constraint >>
1576
1577 Returns true if this attribute has a type constraint.
1578
1579 =item B<< $attr->verify_against_type_constraint($value) >>
1580
1581 Given a value, this method returns true if the value is valid for the
1582 attribute's type constraint. If the value is not valid, it throws an
1583 error.
1584
1585 =item B<< $attr->handles >>
1586
1587 This returns the value of the C<handles> option passed to the
1588 constructor.
1589
1590 =item B<< $attr->has_handles >>
1591
1592 Returns true if this attribute performs delegation.
1593
1594 =item B<< $attr->is_weak_ref >>
1595
1596 Returns true if this attribute stores its value as a weak reference.
1597
1598 =item B<< $attr->is_required >>
1599
1600 Returns true if this attribute is required to have a value.
1601
1602 =item B<< $attr->is_lazy >>
1603
1604 Returns true if this attribute is lazy.
1605
1606 =item B<< $attr->is_lazy_build >>
1607
1608 Returns true if the C<lazy_build> option was true when passed to the
1609 constructor.
1610
1611 =item B<< $attr->should_coerce >>
1612
1613 Returns true if the C<coerce> option passed to the constructor was
1614 true.
1615
1616 =item B<< $attr->should_auto_deref >>
1617
1618 Returns true if the C<auto_deref> option passed to the constructor was
1619 true.
1620
1621 =item B<< $attr->trigger >>
1622
1623 This is the subroutine reference that was in the C<trigger> option
1624 passed to the constructor, if any.
1625
1626 =item B<< $attr->has_trigger >>
1627
1628 Returns true if this attribute has a trigger set.
1629
1630 =item B<< $attr->documentation >>
1631
1632 Returns the value that was in the C<documentation> option passed to
1633 the constructor, if any.
1634
1635 =item B<< $attr->has_documentation >>
1636
1637 Returns true if this attribute has any documentation.
1638
1639 =item B<< $attr->applied_traits >>
1640
1641 This returns an array reference of all the traits which were applied
1642 to this attribute. If none were applied, this returns C<undef>.
1643
1644 =item B<< $attr->has_applied_traits >>
1645
1646 Returns true if this attribute has any traits applied.
1647
1648 =back
1649
1650 =head1 BUGS
1651
1652 See L<Moose/BUGS> for details on reporting bugs.
1653
1654 =cut