lazy_build should be able to be added in inherited attributes
[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.72';
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     return $class->SUPER::new($name, %options);
81 }
82
83 sub interpolate_class_and_new {
84     my ($class, $name, @args) = @_;
85
86     my ( $new_class, @traits ) = $class->interpolate_class(@args);
87     
88     $new_class->new($name, @args, ( scalar(@traits) ? ( traits => \@traits ) : () ) );
89 }
90
91 sub interpolate_class {
92     my ($class, %options) = @_;
93
94     $class = ref($class) || $class;
95
96     if ( my $metaclass_name = delete $options{metaclass} ) {
97         my $new_class = Moose::Util::resolve_metaclass_alias( Attribute => $metaclass_name );
98         
99         if ( $class ne $new_class ) {
100             if ( $new_class->can("interpolate_class") ) {
101                 return $new_class->interpolate_class(%options);
102             } else {
103                 $class = $new_class;
104             }
105         }
106     }
107
108     my @traits;
109
110     if (my $traits = $options{traits}) {
111         my $i = 0;
112         while ($i < @$traits) {
113             my $trait = $traits->[$i++];
114             next if ref($trait); # options to a trait we discarded
115
116             $trait = Moose::Util::resolve_metatrait_alias(Attribute => $trait)
117                   || $trait;
118
119             next if $class->does($trait);
120
121             push @traits, $trait;
122
123             # are there options?
124             push @traits, $traits->[$i++]
125                 if $traits->[$i] && ref($traits->[$i]);
126         }
127
128         if (@traits) {
129             my $anon_class = Moose::Meta::Class->create_anon_class(
130                 superclasses => [ $class ],
131                 roles        => [ @traits ],
132                 cache        => 1,
133             );
134
135             $class = $anon_class->name;
136         }
137     }
138
139     return ( wantarray ? ( $class, @traits ) : $class );
140 }
141
142 # ...
143
144 my @legal_options_for_inheritance = qw(
145     default coerce required 
146     documentation lazy handles 
147     builder type_constraint
148     definition_context
149     lazy_build
150 );
151
152 sub legal_options_for_inheritance { @legal_options_for_inheritance }
153
154 # NOTE/TODO
155 # This method *must* be able to handle 
156 # Class::MOP::Attribute instances as 
157 # well. Yes, I know that is wrong, but 
158 # apparently we didn't realize it was 
159 # doing that and now we have some code 
160 # which is dependent on it. The real 
161 # solution of course is to push this 
162 # feature back up into Class::MOP::Attribute
163 # but I not right now, I am too lazy.
164 # However if you are reading this and 
165 # looking for something to do,.. please 
166 # be my guest.
167 # - stevan
168 sub clone_and_inherit_options {
169     my ($self, %options) = @_;
170     
171     my %copy = %options;
172     
173     my %actual_options;
174     
175     # NOTE:
176     # we may want to extends a Class::MOP::Attribute
177     # in which case we need to be able to use the 
178     # core set of legal options that have always 
179     # been here. But we allows Moose::Meta::Attribute
180     # instances to changes them.
181     # - SL
182     my @legal_options = $self->can('legal_options_for_inheritance')
183         ? $self->legal_options_for_inheritance
184         : @legal_options_for_inheritance;
185     
186     foreach my $legal_option (@legal_options) {
187         if (exists $options{$legal_option}) {
188             $actual_options{$legal_option} = $options{$legal_option};
189             delete $options{$legal_option};
190         }
191     }    
192
193     if ($options{isa}) {
194         my $type_constraint;
195         if (blessed($options{isa}) && $options{isa}->isa('Moose::Meta::TypeConstraint')) {
196             $type_constraint = $options{isa};
197         }
198         else {
199             $type_constraint = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options{isa});
200             (defined $type_constraint)
201                 || $self->throw_error("Could not find the type constraint '" . $options{isa} . "'", data => $options{isa});
202         }
203
204         $actual_options{type_constraint} = $type_constraint;
205         delete $options{isa};
206     }
207     
208     if ($options{does}) {
209         my $type_constraint;
210         if (blessed($options{does}) && $options{does}->isa('Moose::Meta::TypeConstraint')) {
211             $type_constraint = $options{does};
212         }
213         else {
214             $type_constraint = Moose::Util::TypeConstraints::find_or_create_does_type_constraint($options{does});
215             (defined $type_constraint)
216                 || $self->throw_error("Could not find the type constraint '" . $options{does} . "'", data => $options{does});
217         }
218
219         $actual_options{type_constraint} = $type_constraint;
220         delete $options{does};
221     }    
222
223     # NOTE:
224     # this doesn't apply to Class::MOP::Attributes, 
225     # so we can ignore it for them.
226     # - SL
227     if ($self->can('interpolate_class')) {
228         ( $actual_options{metaclass}, my @traits ) = $self->interpolate_class(%options);
229
230         my %seen;
231         my @all_traits = grep { $seen{$_}++ } @{ $self->applied_traits || [] }, @traits;
232         $actual_options{traits} = \@all_traits if @all_traits;
233
234         delete @options{qw(metaclass traits)};
235     }
236
237     (scalar keys %options == 0)
238         || $self->throw_error("Illegal inherited options => (" . (join ', ' => keys %options) . ")", data => \%options);
239
240
241     $self->clone(%actual_options);
242 }
243
244 sub clone {
245     my ( $self, %params ) = @_;
246
247     my $class = $params{metaclass} || ref $self;
248
249     if ( 0 and $class eq ref $self ) {
250         return $self->SUPER::clone(%params);
251     } else {
252         my ( @init, @non_init );
253
254         foreach my $attr ( grep { $_->has_value($self) } $self->meta->compute_all_applicable_attributes ) {
255             push @{ $attr->has_init_arg ? \@init : \@non_init }, $attr;
256         }
257
258         my %new_params = ( ( map { $_->init_arg => $_->get_value($self) } @init ), %params );
259
260         my $name = delete $new_params{name};
261
262         my $clone = $class->new($name, %new_params, __hack_no_process_options => 1 );
263
264         foreach my $attr ( @non_init ) {
265             $attr->set_value($clone, $attr->get_value($self));
266         }
267
268
269         return $clone;
270     }
271 }
272
273 sub _process_options {
274     my ($class, $name, $options) = @_;
275
276     if (exists $options->{is}) {
277
278         ### -------------------------
279         ## is => ro, writer => _foo    # turns into (reader => foo, writer => _foo) as before
280         ## is => rw, writer => _foo    # turns into (reader => foo, writer => _foo)
281         ## is => rw, accessor => _foo  # turns into (accessor => _foo)
282         ## is => ro, accessor => _foo  # error, accesor is rw
283         ### -------------------------
284         
285         if ($options->{is} eq 'ro') {
286             $class->throw_error("Cannot define an accessor name on a read-only attribute, accessors are read/write", data => $options)
287                 if exists $options->{accessor};
288             $options->{reader} ||= $name;
289         }
290         elsif ($options->{is} eq 'rw') {
291             if ($options->{writer}) {
292                 $options->{reader} ||= $name;
293             }
294             else {
295                 $options->{accessor} ||= $name;
296             }
297         }
298         else {
299             $class->throw_error("I do not understand this option (is => " . $options->{is} . ") on attribute ($name)", data => $options->{is});
300         }
301     }
302
303     if (exists $options->{isa}) {
304         if (exists $options->{does}) {
305             if (eval { $options->{isa}->can('does') }) {
306                 ($options->{isa}->does($options->{does}))
307                     || $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);
308             }
309             else {
310                 $class->throw_error("Cannot have an isa option which cannot ->does() on attribute ($name)", data => $options);
311             }
312         }
313
314         # allow for anon-subtypes here ...
315         if (blessed($options->{isa}) && $options->{isa}->isa('Moose::Meta::TypeConstraint')) {
316             $options->{type_constraint} = $options->{isa};
317         }
318         else {
319             $options->{type_constraint} = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options->{isa});
320         }
321     }
322     elsif (exists $options->{does}) {
323         # allow for anon-subtypes here ...
324         if (blessed($options->{does}) && $options->{does}->isa('Moose::Meta::TypeConstraint')) {
325                 $options->{type_constraint} = $options->{does};
326         }
327         else {
328             $options->{type_constraint} = Moose::Util::TypeConstraints::find_or_create_does_type_constraint($options->{does});
329         }
330     }
331
332     if (exists $options->{coerce} && $options->{coerce}) {
333         (exists $options->{type_constraint})
334             || $class->throw_error("You cannot have coercion without specifying a type constraint on attribute ($name)", data => $options);
335         $class->throw_error("You cannot have a weak reference to a coerced value on attribute ($name)", data => $options)
336             if $options->{weak_ref};
337     }
338
339     if (exists $options->{trigger}) {
340         ('CODE' eq ref $options->{trigger})
341             || $class->throw_error("Trigger must be a CODE ref on attribute ($name)", data => $options->{trigger});
342     }
343
344     if (exists $options->{auto_deref} && $options->{auto_deref}) {
345         (exists $options->{type_constraint})
346             || $class->throw_error("You cannot auto-dereference without specifying a type constraint on attribute ($name)", data => $options);
347         ($options->{type_constraint}->is_a_type_of('ArrayRef') ||
348          $options->{type_constraint}->is_a_type_of('HashRef'))
349             || $class->throw_error("You cannot auto-dereference anything other than a ArrayRef or HashRef on attribute ($name)", data => $options);
350     }
351
352     if (exists $options->{lazy_build} && $options->{lazy_build} == 1) {
353         $class->throw_error("You can not use lazy_build and default for the same attribute ($name)", data => $options)
354             if exists $options->{default};
355         $options->{lazy}      = 1;
356         $options->{required}  = 1;
357         $options->{builder} ||= "_build_${name}";
358         if ($name =~ /^_/) {
359             $options->{clearer}   ||= "_clear${name}";
360             $options->{predicate} ||= "_has${name}";
361         } 
362         else {
363             $options->{clearer}   ||= "clear_${name}";
364             $options->{predicate} ||= "has_${name}";
365         }
366     }
367
368     if (exists $options->{lazy} && $options->{lazy}) {
369         (exists $options->{default} || defined $options->{builder} )
370             || $class->throw_error("You cannot have lazy attribute ($name) without specifying a default value for it", data => $options);
371     }
372
373     if ( $options->{required} && !( ( !exists $options->{init_arg} || defined $options->{init_arg} ) || exists $options->{default} || defined $options->{builder} ) ) {
374         $class->throw_error("You cannot have a required attribute ($name) without a default, builder, or an init_arg", data => $options);
375     }
376
377 }
378
379 sub initialize_instance_slot {
380     my ($self, $meta_instance, $instance, $params) = @_;
381     my $init_arg = $self->init_arg();
382     # try to fetch the init arg from the %params ...
383
384     my $val;
385     my $value_is_set;
386     if ( defined($init_arg) and exists $params->{$init_arg}) {
387         $val = $params->{$init_arg};
388         $value_is_set = 1;    
389     }
390     else {
391         # skip it if it's lazy
392         return if $self->is_lazy;
393         # and die if it's required and doesn't have a default value
394         $self->throw_error("Attribute (" . $self->name . ") is required", object => $instance, data => $params)
395             if $self->is_required && !$self->has_default && !$self->has_builder;
396
397         # if nothing was in the %params, we can use the
398         # attribute's default value (if it has one)
399         if ($self->has_default) {
400             $val = $self->default($instance);
401             $value_is_set = 1;
402         } 
403         elsif ($self->has_builder) {
404             $val = $self->_call_builder($instance);
405             $value_is_set = 1;
406         }
407     }
408
409     return unless $value_is_set;
410
411     if ($self->has_type_constraint) {
412         my $type_constraint = $self->type_constraint;
413         if ($self->should_coerce && $type_constraint->has_coercion) {
414             $val = $type_constraint->coerce($val);
415         }
416         $self->verify_against_type_constraint($val, instance => $instance);
417     }
418
419     $self->set_initial_value($instance, $val);
420     $meta_instance->weaken_slot_value($instance, $self->name)
421         if ref $val && $self->is_weak_ref;
422 }
423
424 sub _call_builder {
425     my ( $self, $instance ) = @_;
426
427     my $builder = $self->builder();
428
429     return $instance->$builder()
430         if $instance->can( $self->builder );
431
432     $self->throw_error(  blessed($instance)
433             . " does not support builder method '"
434             . $self->builder
435             . "' for attribute '"
436             . $self->name
437             . "'",
438             object => $instance,
439      );
440 }
441
442 ## Slot management
443
444 # FIXME:
445 # this duplicates too much code from 
446 # Class::MOP::Attribute, we need to 
447 # refactor these bits eventually.
448 # - SL
449 sub _set_initial_slot_value {
450     my ($self, $meta_instance, $instance, $value) = @_;
451
452     my $slot_name = $self->name;
453
454     return $meta_instance->set_slot_value($instance, $slot_name, $value)
455         unless $self->has_initializer;
456
457     my ($type_constraint, $can_coerce);
458     if ($self->has_type_constraint) {
459         $type_constraint = $self->type_constraint;
460         $can_coerce      = ($self->should_coerce && $type_constraint->has_coercion);
461     }
462
463     my $callback = sub {
464         my $val = shift;
465         if ($type_constraint) {
466             $val = $type_constraint->coerce($val)
467                 if $can_coerce;
468             $self->verify_against_type_constraint($val, object => $instance);
469         }
470         $meta_instance->set_slot_value($instance, $slot_name, $val);
471     };
472     
473     my $initializer = $self->initializer;
474
475     # most things will just want to set a value, so make it first arg
476     $instance->$initializer($value, $callback, $self);
477 }
478
479 sub set_value {
480     my ($self, $instance, @args) = @_;
481     my $value = $args[0];
482
483     my $attr_name = $self->name;
484
485     if ($self->is_required and not @args) {
486         $self->throw_error("Attribute ($attr_name) is required", object => $instance);
487     }
488
489     if ($self->has_type_constraint) {
490
491         my $type_constraint = $self->type_constraint;
492
493         if ($self->should_coerce) {
494             $value = $type_constraint->coerce($value);
495         }        
496         $type_constraint->_compiled_type_constraint->($value)
497             || $self->throw_error("Attribute (" 
498                      . $self->name 
499                      . ") does not pass the type constraint because " 
500                      . $type_constraint->get_message($value), object => $instance, data => $value);
501     }
502
503     my $meta_instance = Class::MOP::Class->initialize(blessed($instance))
504                                          ->get_meta_instance;
505
506     $meta_instance->set_slot_value($instance, $attr_name, $value);
507
508     if (ref $value && $self->is_weak_ref) {
509         $meta_instance->weaken_slot_value($instance, $attr_name);
510     }
511
512     if ($self->has_trigger) {
513         $self->trigger->($instance, $value);
514     }
515 }
516
517 sub get_value {
518     my ($self, $instance) = @_;
519
520     if ($self->is_lazy) {
521         unless ($self->has_value($instance)) {
522             my $value;
523             if ($self->has_default) {
524                 $value = $self->default($instance);
525             } elsif ( $self->has_builder ) {
526                 $value = $self->_call_builder($instance);
527             }
528             if ($self->has_type_constraint) {
529                 my $type_constraint = $self->type_constraint;
530                 $value = $type_constraint->coerce($value)
531                     if ($self->should_coerce);
532                 $self->verify_against_type_constraint($value);
533             }
534             $self->set_initial_value($instance, $value);
535         }
536     }
537
538     if ($self->should_auto_deref) {
539
540         my $type_constraint = $self->type_constraint;
541
542         if ($type_constraint->is_a_type_of('ArrayRef')) {
543             my $rv = $self->SUPER::get_value($instance);
544             return unless defined $rv;
545             return wantarray ? @{ $rv } : $rv;
546         }
547         elsif ($type_constraint->is_a_type_of('HashRef')) {
548             my $rv = $self->SUPER::get_value($instance);
549             return unless defined $rv;
550             return wantarray ? %{ $rv } : $rv;
551         }
552         else {
553             $self->throw_error("Can not auto de-reference the type constraint '" . $type_constraint->name . "'", object => $instance, type_constraint => $type_constraint);
554         }
555
556     }
557     else {
558
559         return $self->SUPER::get_value($instance);
560     }
561 }
562
563 ## installing accessors
564
565 sub accessor_metaclass { 'Moose::Meta::Method::Accessor' }
566
567 sub install_accessors {
568     my $self = shift;
569     $self->SUPER::install_accessors(@_);
570     $self->install_delegation if $self->has_handles;
571     return;
572 }
573
574 sub remove_accessors {
575     my $self = shift;
576     $self->SUPER::remove_accessors(@_);
577     $self->remove_delegation if $self->has_handles;
578     return;
579 }
580
581 sub install_delegation {
582     my $self = shift;
583
584     # NOTE:
585     # Here we canonicalize the 'handles' option
586     # this will sort out any details and always
587     # return an hash of methods which we want
588     # to delagate to, see that method for details
589     my %handles = $self->_canonicalize_handles;
590
591
592     # install the delegation ...
593     my $associated_class = $self->associated_class;
594     foreach my $handle (keys %handles) {
595         my $method_to_call = $handles{$handle};
596         my $class_name = $associated_class->name;
597         my $name = "${class_name}::${handle}";
598
599             (!$associated_class->has_method($handle))
600                 || $self->throw_error("You cannot overwrite a locally defined method ($handle) with a delegation", method_name => $handle);
601
602         # NOTE:
603         # handles is not allowed to delegate
604         # any of these methods, as they will
605         # override the ones in your class, which
606         # is almost certainly not what you want.
607
608         # FIXME warn when $handle was explicitly specified, but not if the source is a regex or something
609         #cluck("Not delegating method '$handle' because it is a core method") and
610         next if $class_name->isa("Moose::Object") and $handle =~ /^BUILD|DEMOLISH$/ || Moose::Object->can($handle);
611
612         my $method = $self->_make_delegation_method($handle, $method_to_call);
613
614         $self->associated_class->add_method($method->name, $method);
615     }    
616 }
617
618 sub remove_delegation {
619     my $self = shift;
620     my %handles = $self->_canonicalize_handles;
621     my $associated_class = $self->associated_class;
622     foreach my $handle (keys %handles) {
623         $self->associated_class->remove_method($handle);
624     }
625 }
626
627 # private methods to help delegation ...
628
629 sub _canonicalize_handles {
630     my $self    = shift;
631     my $handles = $self->handles;
632     if (my $handle_type = ref($handles)) {
633         if ($handle_type eq 'HASH') {
634             return %{$handles};
635         }
636         elsif ($handle_type eq 'ARRAY') {
637             return map { $_ => $_ } @{$handles};
638         }
639         elsif ($handle_type eq 'Regexp') {
640             ($self->has_type_constraint)
641                 || $self->throw_error("Cannot delegate methods based on a Regexp without a type constraint (isa)", data => $handles);
642             return map  { ($_ => $_) }
643                    grep { /$handles/ } $self->_get_delegate_method_list;
644         }
645         elsif ($handle_type eq 'CODE') {
646             return $handles->($self, $self->_find_delegate_metaclass);
647         }
648         else {
649             $self->throw_error("Unable to canonicalize the 'handles' option with $handles", data => $handles);
650         }
651     }
652     else {
653         Class::MOP::load_class($handles) 
654             unless Class::MOP::is_class_loaded($handles);
655             
656         my $role_meta = eval { $handles->meta };
657         if ($@) {
658             $self->throw_error("Unable to canonicalize the 'handles' option with $handles because : $@", data => $handles, error => $@);
659         }
660
661         (blessed $role_meta && $role_meta->isa('Moose::Meta::Role'))
662             || $self->throw_error("Unable to canonicalize the 'handles' option with $handles because ->meta is not a Moose::Meta::Role", data => $handles);
663             
664         return map { $_ => $_ } (
665             $role_meta->get_method_list,
666             $role_meta->get_required_method_list
667         );
668     }
669 }
670
671 sub _find_delegate_metaclass {
672     my $self = shift;
673     if (my $class = $self->_isa_metadata) {
674         # if the class does have
675         # a meta method, use it
676         return $class->meta if $class->can('meta');
677         # otherwise we might be
678         # dealing with a non-Moose
679         # class, and need to make
680         # our own metaclass
681         return Moose::Meta::Class->initialize($class);
682     }
683     elsif (my $role = $self->_does_metadata) {
684         # our role will always have
685         # a meta method
686         return $role->meta;
687     }
688     else {
689         $self->throw_error("Cannot find delegate metaclass for attribute " . $self->name);
690     }
691 }
692
693 sub _get_delegate_method_list {
694     my $self = shift;
695     my $meta = $self->_find_delegate_metaclass;
696     if ($meta->isa('Class::MOP::Class')) {
697         return map  { $_->name }  # NOTE: !never! delegate &meta
698                grep { $_->package_name ne 'Moose::Object' && $_->name ne 'meta' }
699                     $meta->get_all_methods;
700     }
701     elsif ($meta->isa('Moose::Meta::Role')) {
702         return $meta->get_method_list;
703     }
704     else {
705         $self->throw_error("Unable to recognize the delegate metaclass '$meta'", data => $meta);
706     }
707 }
708
709 sub delegation_metaclass { 'Moose::Meta::Method::Delegation' }
710
711 sub _make_delegation_method {
712     my ( $self, $handle_name, $method_to_call ) = @_;
713
714     my $method_body;
715
716     $method_body = $method_to_call
717         if 'CODE' eq ref($method_to_call);
718
719     return $self->delegation_metaclass->new(
720         name               => $handle_name,
721         package_name       => $self->associated_class->name,
722         attribute          => $self,
723         delegate_to_method => $method_to_call,
724     );
725 }
726
727 sub verify_against_type_constraint {
728     my $self = shift;
729     my $val  = shift;
730
731     return 1 if !$self->has_type_constraint;
732
733     my $type_constraint = $self->type_constraint;
734
735     $type_constraint->check($val)
736         || $self->throw_error("Attribute ("
737                  . $self->name
738                  . ") does not pass the type constraint because: "
739                  . $type_constraint->get_message($val), data => $val, @_);
740 }
741
742 package Moose::Meta::Attribute::Custom::Moose;
743 sub register_implementation { 'Moose::Meta::Attribute' }
744
745 1;
746
747 __END__
748
749 =pod
750
751 =head1 NAME
752
753 Moose::Meta::Attribute - The Moose attribute metaclass
754
755 =head1 DESCRIPTION
756
757 This is a subclass of L<Class::MOP::Attribute> with Moose specific
758 extensions.
759
760 For the most part, the only time you will ever encounter an
761 instance of this class is if you are doing some serious deep
762 introspection. To really understand this class, you need to refer
763 to the L<Class::MOP::Attribute> documentation.
764
765 =head1 METHODS
766
767 =head2 Overridden methods
768
769 These methods override methods in L<Class::MOP::Attribute> and add
770 Moose specific features. You can safely assume though that they
771 will behave just as L<Class::MOP::Attribute> does.
772
773 =over 4
774
775 =item B<new>
776
777 =item B<clone>
778
779 =item B<does>
780
781 =item B<initialize_instance_slot>
782
783 =item B<install_accessors>
784
785 =item B<remove_accessors>
786
787 =item B<install_delegation>
788
789 =item B<remove_delegation>
790
791 =item B<accessor_metaclass>
792
793 =item B<delegation_metaclass>
794
795 =item B<get_value>
796
797 =item B<set_value>
798
799   eval { $point->meta->get_attribute('x')->set_value($point, 'forty-two') };
800   if($@) {
801     print "Oops: $@\n";
802   }
803
804 I<Attribute (x) does not pass the type constraint (Int) with 'forty-two'>
805
806 Before setting the value, a check is made on the type constraint of
807 the attribute, if it has one, to see if the value passes it. If the
808 value fails to pass, the set operation dies with a L<throw_error>.
809
810 Any coercion to convert values is done before checking the type constraint.
811
812 To check a value against a type constraint before setting it, fetch the
813 attribute instance using L<Class::MOP::Class/find_attribute_by_name>,
814 fetch the type_constraint from the attribute using L<Moose::Meta::Attribute/type_constraint>
815 and call L<Moose::Meta::TypeConstraint/check>. See L<Moose::Cookbook::Basics::Recipe4>
816 for an example.
817
818 =back
819
820 =head2 Additional Moose features
821
822 Moose attributes support type-constraint checking, weak reference
823 creation and type coercion.
824
825 =over 4
826
827 =item B<throw_error>
828
829 Delegates to C<associated_class> or C<Moose::Meta::Class> if there is none.
830
831 =item B<interpolate_class_and_new>
832
833 =item B<interpolate_class>
834
835 When called as a class method causes interpretation of the C<metaclass> and
836 C<traits> options.
837
838 =item B<clone_and_inherit_options>
839
840 This is to support the C<has '+foo'> feature, it clones an attribute
841 from a superclass and allows a very specific set of changes to be made
842 to the attribute.
843
844 =item B<legal_options_for_inheritance>
845
846 Whitelist with options you can change. You can overload it in your custom
847 metaclass to allow your options be inheritable.
848
849 =item B<has_type_constraint>
850
851 Returns true if this meta-attribute has a type constraint.
852
853 =item B<type_constraint>
854
855 A read-only accessor for this meta-attribute's type constraint. For
856 more information on what you can do with this, see the documentation
857 for L<Moose::Meta::TypeConstraint>.
858
859 =item B<verify_against_type_constraint>
860
861 Verifies that the given value is valid under this attribute's type
862 constraint, otherwise throws an error.
863
864 =item B<has_handles>
865
866 Returns true if this meta-attribute performs delegation.
867
868 =item B<handles>
869
870 This returns the value which was passed into the handles option.
871
872 =item B<is_weak_ref>
873
874 Returns true if this meta-attribute produces a weak reference.
875
876 =item B<is_required>
877
878 Returns true if this meta-attribute is required to have a value.
879
880 =item B<is_lazy>
881
882 Returns true if this meta-attribute should be initialized lazily.
883
884 NOTE: lazy attributes, B<must> have a C<default> or C<builder> field set.
885
886 =item B<is_lazy_build>
887
888 Returns true if this meta-attribute should be initialized lazily through
889 the builder generated by lazy_build. Using C<lazy_build =E<gt> 1> will
890 make your attribute required and lazy. In addition it will set the builder, clearer
891 and predicate options for you using the following convention.
892
893    #If your attribute name starts with an underscore:
894    has '_foo' => (lazy_build => 1);
895    #is the same as
896    has '_foo' => (lazy => 1, required => 1, predicate => '_has_foo', clearer => '_clear_foo', builder => '_build__foo');
897    # or
898    has '_foo' => (lazy => 1, required => 1, predicate => '_has_foo', clearer => '_clear_foo', default => sub{shift->_build__foo});
899
900    #If your attribute name does not start with an underscore:
901    has 'foo' => (lazy_build => 1);
902    #is the same as
903    has 'foo' => (lazy => 1, required => 1, predicate => 'has_foo', clearer => 'clear_foo', builder => '_build_foo');
904    # or
905    has 'foo' => (lazy => 1, required => 1, predicate => 'has_foo', clearer => 'clear_foo', default => sub{shift->_build_foo});
906
907 The reason for the different naming of the C<builder> is that the C<builder>
908 method is a private method while the C<clearer> and C<predicate> methods
909 are public methods.
910
911 NOTE: This means your class should provide a method whose name matches the value
912 of the builder part, in this case _build__foo or _build_foo.
913
914 =item B<should_coerce>
915
916 Returns true if this meta-attribute should perform type coercion.
917
918 =item B<should_auto_deref>
919
920 Returns true if this meta-attribute should perform automatic
921 auto-dereferencing.
922
923 NOTE: This can only be done for attributes whose type constraint is
924 either I<ArrayRef> or I<HashRef>.
925
926 =item B<has_trigger>
927
928 Returns true if this meta-attribute has a trigger set.
929
930 =item B<trigger>
931
932 This is a CODE reference which will be executed every time the
933 value of an attribute is assigned. The CODE ref will get two values,
934 the invocant and the new value. This can be used to handle I<basic>
935 bi-directional relations.
936
937 =item B<documentation>
938
939 This is a string which contains the documentation for this attribute.
940 It serves no direct purpose right now, but it might in the future
941 in some kind of automated documentation system perhaps.
942
943 =item B<has_documentation>
944
945 Returns true if this meta-attribute has any documentation.
946
947 =item B<applied_traits>
948
949 This will return the ARRAY ref of all the traits applied to this 
950 attribute, or if no traits have been applied, it returns C<undef>.
951
952 =item B<has_applied_traits>
953
954 Returns true if this meta-attribute has any traits applied.
955
956 =back
957
958 =head1 BUGS
959
960 All complex software has bugs lurking in it, and this module is no
961 exception. If you find a bug please either email me, or add the bug
962 to cpan-RT.
963
964 =head1 AUTHOR
965
966 Stevan Little E<lt>stevan@iinteractive.comE<gt>
967
968 Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
969
970 =head1 COPYRIGHT AND LICENSE
971
972 Copyright 2006-2009 by Infinity Interactive, Inc.
973
974 L<http://www.iinteractive.com>
975
976 This library is free software; you can redistribute it and/or modify
977 it under the same terms as Perl itself.
978
979 =cut