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