stop duplicating code here
[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.19';
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 sub _make_initializer_writer_callback {
513     my $self = shift;
514     my ($meta_instance, $instance, $slot_name) = @_;
515     my $old_callback = $self->SUPER::_make_initializer_writer_callback(@_);
516     return sub {
517         $old_callback->($self->_coerce_and_verify($_[0], $instance));
518     };
519 }
520
521 sub set_value {
522     my ($self, $instance, @args) = @_;
523     my $value = $args[0];
524
525     my $attr_name = $self->name;
526
527     if ($self->is_required and not @args) {
528         $self->throw_error("Attribute ($attr_name) is required", object => $instance);
529     }
530
531     $value = $self->_coerce_and_verify( $value, $instance );
532
533     my @old;
534     if ( $self->has_trigger && $self->has_value($instance) ) {
535         @old = $self->get_value($instance, 'for trigger');
536     }
537
538     $self->SUPER::set_value($instance, $value);
539
540     if ( ref $value && $self->is_weak_ref ) {
541         $self->_weaken_value($instance);
542     }
543
544     if ($self->has_trigger) {
545         $self->trigger->($instance, $value, @old);
546     }
547 }
548
549 sub _weaken_value {
550     my ( $self, $instance ) = @_;
551
552     my $meta_instance = Class::MOP::Class->initialize( blessed($instance) )
553         ->get_meta_instance;
554
555     $meta_instance->weaken_slot_value( $instance, $self->name );
556 }
557
558 sub get_value {
559     my ($self, $instance, $for_trigger) = @_;
560
561     if ($self->is_lazy) {
562         unless ($self->has_value($instance)) {
563             my $value;
564             if ($self->has_default) {
565                 $value = $self->default($instance);
566             } elsif ( $self->has_builder ) {
567                 $value = $self->_call_builder($instance);
568             }
569
570             $value = $self->_coerce_and_verify( $value, $instance );
571
572             $self->set_initial_value($instance, $value);
573         }
574     }
575
576     if ( $self->should_auto_deref && ! $for_trigger ) {
577
578         my $type_constraint = $self->type_constraint;
579
580         if ($type_constraint->is_a_type_of('ArrayRef')) {
581             my $rv = $self->SUPER::get_value($instance);
582             return unless defined $rv;
583             return wantarray ? @{ $rv } : $rv;
584         }
585         elsif ($type_constraint->is_a_type_of('HashRef')) {
586             my $rv = $self->SUPER::get_value($instance);
587             return unless defined $rv;
588             return wantarray ? %{ $rv } : $rv;
589         }
590         else {
591             $self->throw_error("Can not auto de-reference the type constraint '" . $type_constraint->name . "'", object => $instance, type_constraint => $type_constraint);
592         }
593
594     }
595     else {
596
597         return $self->SUPER::get_value($instance);
598     }
599 }
600
601 ## installing accessors
602
603 sub accessor_metaclass { 'Moose::Meta::Method::Accessor' }
604
605 sub install_accessors {
606     my $self = shift;
607     $self->SUPER::install_accessors(@_);
608     $self->install_delegation if $self->has_handles;
609     return;
610 }
611
612 sub _check_associated_methods {
613     my $self = shift;
614     unless (
615         @{ $self->associated_methods }
616         || ($self->_is_metadata || '') eq 'bare'
617     ) {
618         Carp::cluck(
619             'Attribute (' . $self->name . ') of class '
620             . $self->associated_class->name
621             . ' has no associated methods'
622             . ' (did you mean to provide an "is" argument?)'
623             . "\n"
624         )
625     }
626 }
627
628 sub _process_accessors {
629     my $self = shift;
630     my ($type, $accessor, $generate_as_inline_methods) = @_;
631
632     $accessor = ( keys %$accessor )[0] if ( ref($accessor) || '' ) eq 'HASH';
633     my $method = $self->associated_class->get_method($accessor);
634
635     if (   $method
636         && $method->isa('Class::MOP::Method::Accessor')
637         && $method->associated_attribute->name ne $self->name ) {
638
639         my $other_attr_name = $method->associated_attribute->name;
640         my $name            = $self->name;
641
642         Carp::cluck(
643             "You are overwriting an accessor ($accessor) for the $other_attr_name attribute"
644                 . " with a new accessor method for the $name attribute" );
645     }
646
647     if (
648            $method
649         && !$method->isa('Class::MOP::Method::Accessor')
650         && (  !$self->definition_context
651             || $method->package_name eq $self->definition_context->{package} )
652         ) {
653
654         Carp::cluck(
655             "You are overwriting a locally defined method ($accessor) with "
656                 . "an accessor" );
657     }
658
659     if (  !$self->associated_class->has_method($accessor)
660         && $self->associated_class->has_package_symbol( '&' . $accessor ) ) {
661
662         Carp::cluck(
663             "You are overwriting a locally defined function ($accessor) with "
664                 . "an accessor" );
665     }
666
667     $self->SUPER::_process_accessors(@_);
668 }
669
670 sub remove_accessors {
671     my $self = shift;
672     $self->SUPER::remove_accessors(@_);
673     $self->remove_delegation if $self->has_handles;
674     return;
675 }
676
677 sub _inline_set_value {
678     my $self = shift;
679     my ($instance, $value) = @_;
680
681     my $mi = $self->associated_class->get_meta_instance;
682
683     my @code = ($self->SUPER::_inline_set_value(@_));
684
685     push @code, (
686         $mi->inline_weaken_slot_value($instance, $self->name, $value),
687             'if ref ' . $value . ';',
688     ) if $self->is_weak_ref;
689
690     return @code;
691 }
692
693 sub install_delegation {
694     my $self = shift;
695
696     # NOTE:
697     # Here we canonicalize the 'handles' option
698     # this will sort out any details and always
699     # return an hash of methods which we want
700     # to delagate to, see that method for details
701     my %handles = $self->_canonicalize_handles;
702
703
704     # install the delegation ...
705     my $associated_class = $self->associated_class;
706     foreach my $handle (keys %handles) {
707         my $method_to_call = $handles{$handle};
708         my $class_name = $associated_class->name;
709         my $name = "${class_name}::${handle}";
710
711             (!$associated_class->has_method($handle))
712                 || $self->throw_error("You cannot overwrite a locally defined method ($handle) with a delegation", method_name => $handle);
713
714         # NOTE:
715         # handles is not allowed to delegate
716         # any of these methods, as they will
717         # override the ones in your class, which
718         # is almost certainly not what you want.
719
720         # FIXME warn when $handle was explicitly specified, but not if the source is a regex or something
721         #cluck("Not delegating method '$handle' because it is a core method") and
722         next if $class_name->isa("Moose::Object") and $handle =~ /^BUILD|DEMOLISH$/ || Moose::Object->can($handle);
723
724         my $method = $self->_make_delegation_method($handle, $method_to_call);
725
726         $self->associated_class->add_method($method->name, $method);
727         $self->associate_method($method);
728     }
729 }
730
731 sub remove_delegation {
732     my $self = shift;
733     my %handles = $self->_canonicalize_handles;
734     my $associated_class = $self->associated_class;
735     foreach my $handle (keys %handles) {
736         next unless any { $handle eq $_ }
737                     map { $_->name }
738                     @{ $self->associated_methods };
739         $self->associated_class->remove_method($handle);
740     }
741 }
742
743 # private methods to help delegation ...
744
745 sub _canonicalize_handles {
746     my $self    = shift;
747     my $handles = $self->handles;
748     if (my $handle_type = ref($handles)) {
749         if ($handle_type eq 'HASH') {
750             return %{$handles};
751         }
752         elsif ($handle_type eq 'ARRAY') {
753             return map { $_ => $_ } @{$handles};
754         }
755         elsif ($handle_type eq 'Regexp') {
756             ($self->has_type_constraint)
757                 || $self->throw_error("Cannot delegate methods based on a Regexp without a type constraint (isa)", data => $handles);
758             return map  { ($_ => $_) }
759                    grep { /$handles/ } $self->_get_delegate_method_list;
760         }
761         elsif ($handle_type eq 'CODE') {
762             return $handles->($self, $self->_find_delegate_metaclass);
763         }
764         elsif (blessed($handles) && $handles->isa('Moose::Meta::TypeConstraint::DuckType')) {
765             return map { $_ => $_ } @{ $handles->methods };
766         }
767         elsif (blessed($handles) && $handles->isa('Moose::Meta::TypeConstraint::Role')) {
768             $handles = $handles->role;
769         }
770         else {
771             $self->throw_error("Unable to canonicalize the 'handles' option with $handles", data => $handles);
772         }
773     }
774
775     Class::MOP::load_class($handles);
776     my $role_meta = Class::MOP::class_of($handles);
777
778     (blessed $role_meta && $role_meta->isa('Moose::Meta::Role'))
779         || $self->throw_error("Unable to canonicalize the 'handles' option with $handles because its metaclass is not a Moose::Meta::Role", data => $handles);
780
781     return map { $_ => $_ }
782         map { $_->name }
783         grep { !$_->isa('Class::MOP::Method::Meta') } (
784         $role_meta->_get_local_methods,
785         $role_meta->get_required_method_list,
786         );
787 }
788
789 sub _get_delegate_method_list {
790     my $self = shift;
791     my $meta = $self->_find_delegate_metaclass;
792     if ($meta->isa('Class::MOP::Class')) {
793         return map  { $_->name }  # NOTE: !never! delegate &meta
794                grep { $_->package_name ne 'Moose::Object' && !$_->isa('Class::MOP::Method::Meta') }
795                     $meta->get_all_methods;
796     }
797     elsif ($meta->isa('Moose::Meta::Role')) {
798         return $meta->get_method_list;
799     }
800     else {
801         $self->throw_error("Unable to recognize the delegate metaclass '$meta'", data => $meta);
802     }
803 }
804
805 sub _find_delegate_metaclass {
806     my $self = shift;
807     if (my $class = $self->_isa_metadata) {
808         unless ( Class::MOP::is_class_loaded($class) ) {
809             $self->throw_error(
810                 sprintf(
811                     'The %s attribute is trying to delegate to a class which has not been loaded - %s',
812                     $self->name, $class
813                 )
814             );
815         }
816         # we might be dealing with a non-Moose class,
817         # and need to make our own metaclass. if there's
818         # already a metaclass, it will be returned
819         return Class::MOP::Class->initialize($class);
820     }
821     elsif (my $role = $self->_does_metadata) {
822         unless ( Class::MOP::is_class_loaded($class) ) {
823             $self->throw_error(
824                 sprintf(
825                     'The %s attribute is trying to delegate to a role which has not been loaded - %s',
826                     $self->name, $role
827                 )
828             );
829         }
830
831         return Class::MOP::class_of($role);
832     }
833     else {
834         $self->throw_error("Cannot find delegate metaclass for attribute " . $self->name);
835     }
836 }
837
838 sub delegation_metaclass { 'Moose::Meta::Method::Delegation' }
839
840 sub _make_delegation_method {
841     my ( $self, $handle_name, $method_to_call ) = @_;
842
843     my @curried_arguments;
844
845     ($method_to_call, @curried_arguments) = @$method_to_call
846         if 'ARRAY' eq ref($method_to_call);
847
848     return $self->delegation_metaclass->new(
849         name               => $handle_name,
850         package_name       => $self->associated_class->name,
851         attribute          => $self,
852         delegate_to_method => $method_to_call,
853         curried_arguments  => \@curried_arguments,
854     );
855 }
856
857 sub _coerce_and_verify {
858     my $self     = shift;
859     my $val      = shift;
860     my $instance = shift;
861
862     return $val unless $self->has_type_constraint;
863
864     $val = $self->type_constraint->coerce($val)
865         if $self->should_coerce && $self->type_constraint->has_coercion;
866
867     $self->verify_against_type_constraint($val, instance => $instance);
868
869     return $val;
870 }
871
872 sub verify_against_type_constraint {
873     my $self = shift;
874     my $val  = shift;
875
876     return 1 if !$self->has_type_constraint;
877
878     my $type_constraint = $self->type_constraint;
879
880     $type_constraint->check($val)
881         || $self->throw_error("Attribute ("
882                  . $self->name
883                  . ") does not pass the type constraint because: "
884                  . $type_constraint->get_message($val), data => $val, @_);
885 }
886
887 package Moose::Meta::Attribute::Custom::Moose;
888 sub register_implementation { 'Moose::Meta::Attribute' }
889
890 1;
891
892 __END__
893
894 =pod
895
896 =head1 NAME
897
898 Moose::Meta::Attribute - The Moose attribute metaclass
899
900 =head1 DESCRIPTION
901
902 This class is a subclass of L<Class::MOP::Attribute> that provides
903 additional Moose-specific functionality.
904
905 To really understand this class, you will need to start with the
906 L<Class::MOP::Attribute> documentation. This class can be understood
907 as a set of additional features on top of the basic feature provided
908 by that parent class.
909
910 =head1 INHERITANCE
911
912 C<Moose::Meta::Attribute> is a subclass of L<Class::MOP::Attribute>.
913
914 =head1 METHODS
915
916 Many of the documented below override methods in
917 L<Class::MOP::Attribute> and add Moose specific features.
918
919 =head2 Creation
920
921 =over 4
922
923 =item B<< Moose::Meta::Attribute->new(%options) >>
924
925 This method overrides the L<Class::MOP::Attribute> constructor.
926
927 Many of the options below are described in more detail in the
928 L<Moose::Manual::Attributes> document.
929
930 It adds the following options to the constructor:
931
932 =over 8
933
934 =item * is => 'ro', 'rw', 'bare'
935
936 This provides a shorthand for specifying the C<reader>, C<writer>, or
937 C<accessor> names. If the attribute is read-only ('ro') then it will
938 have a C<reader> method with the same attribute as the name.
939
940 If it is read-write ('rw') then it will have an C<accessor> method
941 with the same name. If you provide an explicit C<writer> for a
942 read-write attribute, then you will have a C<reader> with the same
943 name as the attribute, and a C<writer> with the name you provided.
944
945 Use 'bare' when you are deliberately not installing any methods
946 (accessor, reader, etc.) associated with this attribute; otherwise,
947 Moose will issue a deprecation warning when this attribute is added to a
948 metaclass.
949
950 =item * isa => $type
951
952 This option accepts a type. The type can be a string, which should be
953 a type name. If the type name is unknown, it is assumed to be a class
954 name.
955
956 This option can also accept a L<Moose::Meta::TypeConstraint> object.
957
958 If you I<also> provide a C<does> option, then your C<isa> option must
959 be a class name, and that class must do the role specified with
960 C<does>.
961
962 =item * does => $role
963
964 This is short-hand for saying that the attribute's type must be an
965 object which does the named role.
966
967 =item * coerce => $bool
968
969 This option is only valid for objects with a type constraint
970 (C<isa>) that defined a coercion. If this is true, then coercions will be applied whenever
971 this attribute is set.
972
973 You can make both this and the C<weak_ref> option true.
974
975 =item * trigger => $sub
976
977 This option accepts a subroutine reference, which will be called after
978 the attribute is set.
979
980 =item * required => $bool
981
982 An attribute which is required must be provided to the constructor. An
983 attribute which is required can also have a C<default> or C<builder>,
984 which will satisfy its required-ness.
985
986 A required attribute must have a C<default>, C<builder> or a
987 non-C<undef> C<init_arg>
988
989 =item * lazy => $bool
990
991 A lazy attribute must have a C<default> or C<builder>. When an
992 attribute is lazy, the default value will not be calculated until the
993 attribute is read.
994
995 =item * weak_ref => $bool
996
997 If this is true, the attribute's value will be stored as a weak
998 reference.
999
1000 =item * auto_deref => $bool
1001
1002 If this is true, then the reader will dereference the value when it is
1003 called. The attribute must have a type constraint which defines the
1004 attribute as an array or hash reference.
1005
1006 =item * lazy_build => $bool
1007
1008 Setting this to true makes the attribute lazy and provides a number of
1009 default methods.
1010
1011   has 'size' => (
1012       is         => 'ro',
1013       lazy_build => 1,
1014   );
1015
1016 is equivalent to this:
1017
1018   has 'size' => (
1019       is        => 'ro',
1020       lazy      => 1,
1021       builder   => '_build_size',
1022       clearer   => 'clear_size',
1023       predicate => 'has_size',
1024   );
1025
1026
1027 If your attribute name starts with an underscore (C<_>), then the clearer
1028 and predicate will as well:
1029
1030   has '_size' => (
1031       is         => 'ro',
1032       lazy_build => 1,
1033   );
1034
1035 becomes:
1036
1037   has '_size' => (
1038       is        => 'ro',
1039       lazy      => 1,
1040       builder   => '_build__size',
1041       clearer   => '_clear_size',
1042       predicate => '_has_size',
1043   );
1044
1045 Note the doubled underscore in the builder name. Internally, Moose
1046 simply prepends the attribute name with "_build_" to come up with the
1047 builder name.
1048
1049 =item * documentation
1050
1051 An arbitrary string that can be retrieved later by calling C<<
1052 $attr->documentation >>.
1053
1054 =back
1055
1056 =item B<< $attr->clone(%options) >>
1057
1058 This creates a new attribute based on attribute being cloned. You must
1059 supply a C<name> option to provide a new name for the attribute.
1060
1061 The C<%options> can only specify options handled by
1062 L<Class::MOP::Attribute>.
1063
1064 =back
1065
1066 =head2 Value management
1067
1068 =over 4
1069
1070 =item B<< $attr->initialize_instance_slot($meta_instance, $instance, $params) >>
1071
1072 This method is used internally to initialize the attribute's slot in
1073 the object C<$instance>.
1074
1075 This overrides the L<Class::MOP::Attribute> method to handle lazy
1076 attributes, weak references, and type constraints.
1077
1078 =item B<get_value>
1079
1080 =item B<set_value>
1081
1082   eval { $point->meta->get_attribute('x')->set_value($point, 'forty-two') };
1083   if($@) {
1084     print "Oops: $@\n";
1085   }
1086
1087 I<Attribute (x) does not pass the type constraint (Int) with 'forty-two'>
1088
1089 Before setting the value, a check is made on the type constraint of
1090 the attribute, if it has one, to see if the value passes it. If the
1091 value fails to pass, the set operation dies with a L</throw_error>.
1092
1093 Any coercion to convert values is done before checking the type constraint.
1094
1095 To check a value against a type constraint before setting it, fetch the
1096 attribute instance using L<Class::MOP::Class/find_attribute_by_name>,
1097 fetch the type_constraint from the attribute using L<Moose::Meta::Attribute/type_constraint>
1098 and call L<Moose::Meta::TypeConstraint/check>. See L<Moose::Cookbook::Basics::Recipe4>
1099 for an example.
1100
1101 =back
1102
1103 =head2 Attribute Accessor generation
1104
1105 =over 4
1106
1107 =item B<< $attr->install_accessors >>
1108
1109 This method overrides the parent to also install delegation methods.
1110
1111 If, after installing all methods, the attribute object has no associated
1112 methods, it throws an error unless C<< is => 'bare' >> was passed to the
1113 attribute constructor.  (Trying to add an attribute that has no associated
1114 methods is almost always an error.)
1115
1116 =item B<< $attr->remove_accessors >>
1117
1118 This method overrides the parent to also remove delegation methods.
1119
1120 =item B<< $attr->inline_set($instance_var, $value_var) >>
1121
1122 This method return a code snippet suitable for inlining the relevant
1123 operation. It expect strings containing variable names to be used in the
1124 inlining, like C<'$self'> or C<'$_[1]'>.
1125
1126 =item B<< $attr->install_delegation >>
1127
1128 This method adds its delegation methods to the attribute's associated
1129 class, if it has any to add.
1130
1131 =item B<< $attr->remove_delegation >>
1132
1133 This method remove its delegation methods from the attribute's
1134 associated class.
1135
1136 =item B<< $attr->accessor_metaclass >>
1137
1138 Returns the accessor metaclass name, which defaults to
1139 L<Moose::Meta::Method::Accessor>.
1140
1141 =item B<< $attr->delegation_metaclass >>
1142
1143 Returns the delegation metaclass name, which defaults to
1144 L<Moose::Meta::Method::Delegation>.
1145
1146 =back
1147
1148 =head2 Additional Moose features
1149
1150 These methods are not found in the superclass. They support features
1151 provided by Moose.
1152
1153 =over 4
1154
1155 =item B<< $attr->does($role) >>
1156
1157 This indicates whether the I<attribute itself> does the given
1158 role. The role can be given as a full class name, or as a resolvable
1159 trait name.
1160
1161 Note that this checks the attribute itself, not its type constraint,
1162 so it is checking the attribute's metaclass and any traits applied to
1163 the attribute.
1164
1165 =item B<< Moose::Meta::Class->interpolate_class_and_new($name, %options) >>
1166
1167 This is an alternate constructor that handles the C<metaclass> and
1168 C<traits> options.
1169
1170 Effectively, this method is a factory that finds or creates the
1171 appropriate class for the given C<metaclass> and/or C<traits>.
1172
1173 Once it has the appropriate class, it will call C<< $class->new($name,
1174 %options) >> on that class.
1175
1176 =item B<< $attr->clone_and_inherit_options(%options) >>
1177
1178 This method supports the C<has '+foo'> feature. It does various bits
1179 of processing on the supplied C<%options> before ultimately calling
1180 the C<clone> method.
1181
1182 One of its main tasks is to make sure that the C<%options> provided
1183 does not include the options returned by the
1184 C<illegal_options_for_inheritance> method.
1185
1186 =item B<< $attr->illegal_options_for_inheritance >>
1187
1188 This returns a blacklist of options that can not be overridden in a
1189 subclass's attribute definition.
1190
1191 This exists to allow a custom metaclass to change or add to the list
1192 of options which can not be changed.
1193
1194 =item B<< $attr->type_constraint >>
1195
1196 Returns the L<Moose::Meta::TypeConstraint> object for this attribute,
1197 if it has one.
1198
1199 =item B<< $attr->has_type_constraint >>
1200
1201 Returns true if this attribute has a type constraint.
1202
1203 =item B<< $attr->verify_against_type_constraint($value) >>
1204
1205 Given a value, this method returns true if the value is valid for the
1206 attribute's type constraint. If the value is not valid, it throws an
1207 error.
1208
1209 =item B<< $attr->handles >>
1210
1211 This returns the value of the C<handles> option passed to the
1212 constructor.
1213
1214 =item B<< $attr->has_handles >>
1215
1216 Returns true if this attribute performs delegation.
1217
1218 =item B<< $attr->is_weak_ref >>
1219
1220 Returns true if this attribute stores its value as a weak reference.
1221
1222 =item B<< $attr->is_required >>
1223
1224 Returns true if this attribute is required to have a value.
1225
1226 =item B<< $attr->is_lazy >>
1227
1228 Returns true if this attribute is lazy.
1229
1230 =item B<< $attr->is_lazy_build >>
1231
1232 Returns true if the C<lazy_build> option was true when passed to the
1233 constructor.
1234
1235 =item B<< $attr->should_coerce >>
1236
1237 Returns true if the C<coerce> option passed to the constructor was
1238 true.
1239
1240 =item B<< $attr->should_auto_deref >>
1241
1242 Returns true if the C<auto_deref> option passed to the constructor was
1243 true.
1244
1245 =item B<< $attr->trigger >>
1246
1247 This is the subroutine reference that was in the C<trigger> option
1248 passed to the constructor, if any.
1249
1250 =item B<< $attr->has_trigger >>
1251
1252 Returns true if this attribute has a trigger set.
1253
1254 =item B<< $attr->documentation >>
1255
1256 Returns the value that was in the C<documentation> option passed to
1257 the constructor, if any.
1258
1259 =item B<< $attr->has_documentation >>
1260
1261 Returns true if this attribute has any documentation.
1262
1263 =item B<< $attr->applied_traits >>
1264
1265 This returns an array reference of all the traits which were applied
1266 to this attribute. If none were applied, this returns C<undef>.
1267
1268 =item B<< $attr->has_applied_traits >>
1269
1270 Returns true if this attribute has any traits applied.
1271
1272 =back
1273
1274 =head1 BUGS
1275
1276 See L<Moose/BUGS> for details on reporting bugs.
1277
1278 =head1 AUTHOR
1279
1280 Stevan Little E<lt>stevan@iinteractive.comE<gt>
1281
1282 Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
1283
1284 =head1 COPYRIGHT AND LICENSE
1285
1286 Copyright 2006-2010 by Infinity Interactive, Inc.
1287
1288 L<http://www.iinteractive.com>
1289
1290 This library is free software; you can redistribute it and/or modify
1291 it under the same terms as Perl itself.
1292
1293 =cut