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