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