support traits/metaclasses in clone_and_inherit_whatever_id_dont_remember_the_name_of...
[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', 'reftype';
8 use Carp         'confess';
9 use Sub::Name    'subname';
10 use overload     ();
11
12 our $VERSION   = '0.22';
13 our $AUTHORITY = 'cpan:STEVAN';
14
15 use Moose::Meta::Method::Accessor;
16 use Moose::Util ();
17 use Moose::Util::TypeConstraints ();
18
19 use base 'Class::MOP::Attribute';
20
21 # options which are not directly used
22 # but we store them for metadata purposes
23 __PACKAGE__->meta->add_attribute('isa'  => (reader    => '_isa_metadata'));
24 __PACKAGE__->meta->add_attribute('does' => (reader    => '_does_metadata'));
25 __PACKAGE__->meta->add_attribute('is'   => (reader    => '_is_metadata'));
26
27 # these are actual options for the attrs
28 __PACKAGE__->meta->add_attribute('required'   => (reader => 'is_required'      ));
29 __PACKAGE__->meta->add_attribute('lazy'       => (reader => 'is_lazy'          ));
30 __PACKAGE__->meta->add_attribute('lazy_build' => (reader => 'is_lazy_build'    ));
31 __PACKAGE__->meta->add_attribute('coerce'     => (reader => 'should_coerce'    ));
32 __PACKAGE__->meta->add_attribute('weak_ref'   => (reader => 'is_weak_ref'      ));
33 __PACKAGE__->meta->add_attribute('auto_deref' => (reader => 'should_auto_deref'));
34 __PACKAGE__->meta->add_attribute('type_constraint' => (
35     reader    => 'type_constraint',
36     predicate => 'has_type_constraint',
37 ));
38 __PACKAGE__->meta->add_attribute('trigger' => (
39     reader    => 'trigger',
40     predicate => 'has_trigger',
41 ));
42 __PACKAGE__->meta->add_attribute('handles' => (
43     reader    => 'handles',
44     predicate => 'has_handles',
45 ));
46 __PACKAGE__->meta->add_attribute('documentation' => (
47     reader    => 'documentation',
48     predicate => 'has_documentation',
49 ));
50 __PACKAGE__->meta->add_attribute('traits' => (
51     reader    => 'applied_traits',
52     predicate => 'has_applied_traits',
53 ));
54
55 # NOTE:
56 # we need to have a ->does method in here to 
57 # more easily support traits, and the introspection 
58 # of those traits. So in order to do this we 
59 # just alias Moose::Object's version of it.
60 # - SL
61 *does = \&Moose::Object::does;
62
63 sub new {
64     my ($class, $name, %options) = @_;
65     $class->_process_options($name, \%options) unless $options{__hack_no_process_options}; # used from clone()... YECHKKK FIXME ICKY YUCK GROSS
66     return $class->SUPER::new($name, %options);
67 }
68
69 sub interpolate_class_and_new {
70     my ($class, $name, @args) = @_;
71
72     my ( $new_class, @traits ) = $class->interpolate_class(@args);
73     
74     $new_class->new($name, @args, ( scalar(@traits) ? ( traits => \@traits ) : () ) );
75 }
76
77 sub interpolate_class {
78     my ($class, %options) = @_;
79
80     $class = ref($class) || $class;
81
82     if ( my $metaclass_name = delete $options{metaclass} ) {
83         my $new_class = Moose::Util::resolve_metaclass_alias( Attribute => $metaclass_name );
84         
85         if ( $class ne $new_class ) {
86             if ( $new_class->can("interpolate_class") ) {
87                 return $new_class->interpolate_class(%options);
88             } else {
89                 $class = $new_class;
90             }
91         }
92     }
93
94     my @traits;
95
96     if (my $traits = $options{traits}) {
97         if ( @traits = grep { not $class->does($_) } map {
98             Moose::Util::resolve_metatrait_alias( Attribute => $_ )
99                 or
100             $_
101         } @$traits ) {
102             my $anon_class = Moose::Meta::Class->create_anon_class(
103                 superclasses => [ $class ],
104                 roles        => [ @traits ],
105                 cache        => 1,
106             );
107
108             $class = $anon_class->name;
109         }
110     }
111
112     return ( wantarray ? ( $class, @traits ) : $class );
113 }
114
115 sub clone_and_inherit_options {
116     my ($self, %options) = @_;
117     my %copy = %options;
118     # you can change default, required, coerce, documentation, lazy, handles, builder, type_constraint (explicitly or using isa/does), metaclass and traits
119     my %actual_options;
120     foreach my $legal_option (qw(default coerce required documentation lazy handles builder type_constraint)) {
121         if (exists $options{$legal_option}) {
122             $actual_options{$legal_option} = $options{$legal_option};
123             delete $options{$legal_option};
124         }
125     }
126
127     if ($options{isa}) {
128         my $type_constraint;
129         if (blessed($options{isa}) && $options{isa}->isa('Moose::Meta::TypeConstraint')) {
130             $type_constraint = $options{isa};
131         }
132         else {
133             $type_constraint = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options{isa});
134             (defined $type_constraint)
135                 || confess "Could not find the type constraint '" . $options{isa} . "'";
136         }
137
138         $actual_options{type_constraint} = $type_constraint;
139         delete $options{isa};
140     }
141     
142     if ($options{does}) {
143         my $type_constraint;
144         if (blessed($options{does}) && $options{does}->isa('Moose::Meta::TypeConstraint')) {
145             $type_constraint = $options{does};
146         }
147         else {
148             $type_constraint = Moose::Util::TypeConstraints::find_or_create_does_type_constraint($options{does});
149             (defined $type_constraint)
150                 || confess "Could not find the type constraint '" . $options{does} . "'";
151         }
152
153         $actual_options{type_constraint} = $type_constraint;
154         delete $options{does};
155     }    
156
157     ( $actual_options{metaclass}, my @traits ) = $self->interpolate_class(%options);
158
159     my %seen;
160     my @all_traits = grep { $seen{$_}++ } @{ $self->applied_traits || [] }, @traits;
161     $actual_options{traits} = \@all_traits if @all_traits;
162
163     delete @options{qw(metaclass traits)};
164
165     (scalar keys %options == 0)
166         || confess "Illegal inherited options => (" . (join ', ' => keys %options) . ")";
167
168
169     $self->clone(%actual_options);
170 }
171
172 sub clone {
173     my ( $self, %params ) = @_;
174
175     my $class = $params{metaclass} || ref $self;
176
177     if ( 0 and $class eq ref $self ) {
178         return $self->SUPER::clone(%params);
179     } else {
180         my ( @init, @non_init );
181
182         foreach my $attr ( grep { $_->has_value($self) } $self->meta->compute_all_applicable_attributes ) {
183             push @{ $attr->has_init_arg ? \@init : \@non_init }, $attr;
184         }
185
186         my %new_params = ( ( map { $_->init_arg => $_->get_value($self) } @init ), %params );
187
188         my $name = delete $new_params{name};
189
190         my $clone = $class->new($name, %new_params, __hack_no_process_options => 1 );
191
192         foreach my $attr ( @non_init ) {
193             $attr->set_value($clone, $attr->get_value($self));
194         }
195
196
197         return $clone;
198     }
199 }
200
201 sub _process_options {
202     my ($class, $name, $options) = @_;
203
204     if (exists $options->{is}) {
205         if ($options->{is} eq 'ro') {
206             $options->{reader} ||= $name;
207             (!exists $options->{trigger})
208                 || confess "Cannot have a trigger on a read-only attribute $name";
209         }
210         elsif ($options->{is} eq 'rw') {
211             $options->{accessor} = $name;
212             ((reftype($options->{trigger}) || '') eq 'CODE')
213                 || confess "Trigger must be a CODE ref"
214                     if exists $options->{trigger};
215         }
216         else {
217             confess "I do not understand this option (is => " . $options->{is} . ") on attribute $name"
218         }
219     }
220
221     if (exists $options->{isa}) {
222         if (exists $options->{does}) {
223             if (eval { $options->{isa}->can('does') }) {
224                 ($options->{isa}->does($options->{does}))
225                     || confess "Cannot have an isa option and a does option if the isa does not do the does on attribute $name";
226             }
227             else {
228                 confess "Cannot have an isa option which cannot ->does() on attribute $name";
229             }
230         }
231
232         # allow for anon-subtypes here ...
233         if (blessed($options->{isa}) && $options->{isa}->isa('Moose::Meta::TypeConstraint')) {
234             $options->{type_constraint} = $options->{isa};
235         }
236         else {
237             $options->{type_constraint} = Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($options->{isa});
238         }
239     }
240     elsif (exists $options->{does}) {
241         # allow for anon-subtypes here ...
242         if (blessed($options->{does}) && $options->{does}->isa('Moose::Meta::TypeConstraint')) {
243                 $options->{type_constraint} = $options->{does};
244         }
245         else {
246             $options->{type_constraint} = Moose::Util::TypeConstraints::find_or_create_does_type_constraint($options->{does});
247         }
248     }
249
250     if (exists $options->{coerce} && $options->{coerce}) {
251         (exists $options->{type_constraint})
252             || confess "You cannot have coercion without specifying a type constraint on attribute $name";
253         confess "You cannot have a weak reference to a coerced value on attribute $name"
254             if $options->{weak_ref};
255     }
256
257     if (exists $options->{auto_deref} && $options->{auto_deref}) {
258         (exists $options->{type_constraint})
259             || confess "You cannot auto-dereference without specifying a type constraint on attribute $name";
260         ($options->{type_constraint}->is_a_type_of('ArrayRef') ||
261          $options->{type_constraint}->is_a_type_of('HashRef'))
262             || confess "You cannot auto-dereference anything other than a ArrayRef or HashRef on attribute $name";
263     }
264
265     if (exists $options->{lazy_build} && $options->{lazy_build} == 1) {
266         confess("You can not use lazy_build and default for the same attribute $name")
267             if exists $options->{default};
268         $options->{lazy}      = 1;
269         $options->{required}  = 1;
270         $options->{builder} ||= "_build_${name}";
271         if ($name =~ /^_/) {
272             $options->{clearer}   ||= "_clear${name}";
273             $options->{predicate} ||= "_has${name}";
274         } 
275         else {
276             $options->{clearer}   ||= "clear_${name}";
277             $options->{predicate} ||= "has_${name}";
278         }
279     }
280
281     if (exists $options->{lazy} && $options->{lazy}) {
282         (exists $options->{default} || defined $options->{builder} )
283             || confess "You cannot have lazy attribute ($name) without specifying a default value for it";
284     }
285
286     if ( $options->{required} && !( ( !exists $options->{init_arg} || defined $options->{init_arg} ) || exists $options->{default} || defined $options->{builder} ) ) {
287         confess "You cannot have a required attribute ($name) without a default, builder, or an init_arg";
288     }
289
290 }
291
292 sub initialize_instance_slot {
293     my ($self, $meta_instance, $instance, $params) = @_;
294     my $init_arg = $self->init_arg();
295     # try to fetch the init arg from the %params ...
296
297     my $val;
298     my $value_is_set;
299     if ( defined($init_arg) and exists $params->{$init_arg}) {
300         $val = $params->{$init_arg};
301         $value_is_set = 1;    
302     }
303     else {
304         # skip it if it's lazy
305         return if $self->is_lazy;
306         # and die if it's required and doesn't have a default value
307         confess "Attribute (" . $self->name . ") is required"
308             if $self->is_required && !$self->has_default && !$self->has_builder;
309
310         # if nothing was in the %params, we can use the
311         # attribute's default value (if it has one)
312         if ($self->has_default) {
313             $val = $self->default($instance);
314             $value_is_set = 1;
315         } 
316         elsif ($self->has_builder) {
317             if (my $builder = $instance->can($self->builder)){
318                 $val = $instance->$builder;
319                 $value_is_set = 1;
320             } 
321             else {
322                 confess(blessed($instance)." does not support builder method '".$self->builder."' for attribute '" . $self->name . "'");
323             }
324         }
325     }
326
327     return unless $value_is_set;
328
329     if ($self->has_type_constraint) {
330         my $type_constraint = $self->type_constraint;
331         if ($self->should_coerce && $type_constraint->has_coercion) {
332             $val = $type_constraint->coerce($val);
333         }
334         $type_constraint->check($val)
335             || confess "Attribute (" 
336                      . $self->name 
337                      . ") does not pass the type constraint because: " 
338                      . $type_constraint->get_message($val);
339     }
340
341     $self->set_initial_value($instance, $val);
342     $meta_instance->weaken_slot_value($instance, $self->name)
343         if ref $val && $self->is_weak_ref;
344 }
345
346 ## Slot management
347
348 # FIXME:
349 # this duplicates too much code from 
350 # Class::MOP::Attribute, we need to 
351 # refactor these bits eventually.
352 # - SL
353 sub _set_initial_slot_value {
354     my ($self, $meta_instance, $instance, $value) = @_;
355
356     my $slot_name = $self->name;
357
358     return $meta_instance->set_slot_value($instance, $slot_name, $value)
359         unless $self->has_initializer;
360
361     my ($type_constraint, $can_coerce);
362     if ($self->has_type_constraint) {
363         $type_constraint = $self->type_constraint;
364         $can_coerce      = ($self->should_coerce && $type_constraint->has_coercion);
365     }
366
367     my $callback = sub {
368         my $val = shift;
369         if ($type_constraint) {
370             $val = $type_constraint->coerce($val)
371                 if $can_coerce;
372             $type_constraint->check($val)
373                 || confess "Attribute (" 
374                          . $slot_name 
375                          . ") does not pass the type constraint because: " 
376                          . $type_constraint->get_message($val);            
377         }
378         $meta_instance->set_slot_value($instance, $slot_name, $val);
379     };
380     
381     my $initializer = $self->initializer;
382
383     # most things will just want to set a value, so make it first arg
384     $instance->$initializer($value, $callback, $self);
385 }
386
387 sub set_value {
388     my ($self, $instance, $value) = @_;
389
390     my $attr_name = $self->name;
391
392     if ($self->is_required) {
393         defined($value)
394             || confess "Attribute ($attr_name) is required, so cannot be set to undef";
395     }
396
397     if ($self->has_type_constraint) {
398
399         my $type_constraint = $self->type_constraint;
400
401         if ($self->should_coerce) {
402             $value = $type_constraint->coerce($value);
403         }        
404         $type_constraint->_compiled_type_constraint->($value)
405             || confess "Attribute (" 
406                      . $self->name 
407                      . ") does not pass the type constraint because " 
408                      . $type_constraint->get_message($value);
409     }
410
411     my $meta_instance = Class::MOP::Class->initialize(blessed($instance))
412                                          ->get_meta_instance;
413
414     $meta_instance->set_slot_value($instance, $attr_name, $value);
415
416     if (ref $value && $self->is_weak_ref) {
417         $meta_instance->weaken_slot_value($instance, $attr_name);
418     }
419
420     if ($self->has_trigger) {
421         $self->trigger->($instance, $value, $self);
422     }
423 }
424
425 sub get_value {
426     my ($self, $instance) = @_;
427
428     if ($self->is_lazy) {
429         unless ($self->has_value($instance)) {
430             if ($self->has_default) {
431                 my $default = $self->default($instance);
432                 $self->set_initial_value($instance, $default);
433             }
434             if ( $self->has_builder ){
435                 if (my $builder = $instance->can($self->builder)){
436                     $self->set_initial_value($instance, $instance->$builder);
437                 } 
438                 else {
439                     confess(blessed($instance) 
440                           . " does not support builder method '"
441                           . $self->builder 
442                           . "' for attribute '" 
443                           . $self->name 
444                           . "'");
445                 }
446             } 
447             else {
448                 $self->set_initial_value($instance, undef);
449             }
450         }
451     }
452
453     if ($self->should_auto_deref) {
454
455         my $type_constraint = $self->type_constraint;
456
457         if ($type_constraint->is_a_type_of('ArrayRef')) {
458             my $rv = $self->SUPER::get_value($instance);
459             return unless defined $rv;
460             return wantarray ? @{ $rv } : $rv;
461         }
462         elsif ($type_constraint->is_a_type_of('HashRef')) {
463             my $rv = $self->SUPER::get_value($instance);
464             return unless defined $rv;
465             return wantarray ? %{ $rv } : $rv;
466         }
467         else {
468             confess "Can not auto de-reference the type constraint '" . $type_constraint->name . "'";
469         }
470
471     }
472     else {
473
474         return $self->SUPER::get_value($instance);
475     }
476 }
477
478 ## installing accessors
479
480 sub accessor_metaclass { 'Moose::Meta::Method::Accessor' }
481
482 sub install_accessors {
483     my $self = shift;
484     $self->SUPER::install_accessors(@_);
485
486     if ($self->has_handles) {
487
488         # NOTE:
489         # Here we canonicalize the 'handles' option
490         # this will sort out any details and always
491         # return an hash of methods which we want
492         # to delagate to, see that method for details
493         my %handles = $self->_canonicalize_handles();
494
495         # find the accessor method for this attribute
496         my $accessor = $self->get_read_method_ref;
497         # then unpack it if we need too ...
498         $accessor = $accessor->body if blessed $accessor;
499
500         # install the delegation ...
501         my $associated_class = $self->associated_class;
502         foreach my $handle (keys %handles) {
503             my $method_to_call = $handles{$handle};
504             my $class_name = $associated_class->name;
505             my $name = "${class_name}::${handle}";
506
507             (!$associated_class->has_method($handle))
508                 || confess "You cannot overwrite a locally defined method ($handle) with a delegation";
509
510             # NOTE:
511             # handles is not allowed to delegate
512             # any of these methods, as they will
513             # override the ones in your class, which
514             # is almost certainly not what you want.
515
516             # FIXME warn when $handle was explicitly specified, but not if the source is a regex or something
517             #cluck("Not delegating method '$handle' because it is a core method") and
518             next if $class_name->isa("Moose::Object") and $handle =~ /^BUILD|DEMOLISH$/ || Moose::Object->can($handle);
519
520             if ((reftype($method_to_call) || '') eq 'CODE') {
521                 $associated_class->add_method($handle => subname $name, $method_to_call);
522             }
523             else {
524                 # NOTE:
525                 # we used to do a goto here, but the
526                 # goto didn't handle failure correctly
527                 # (it just returned nothing), so I took 
528                 # that out. However, the more I thought
529                 # about it, the less I liked it doing 
530                 # the goto, and I prefered the act of 
531                 # delegation being actually represented
532                 # in the stack trace. 
533                 # - SL
534                 $associated_class->add_method($handle => subname $name, sub {
535                     my $proxy = (shift)->$accessor();
536                     (defined $proxy) 
537                         || confess "Cannot delegate $handle to $method_to_call because " . 
538                                    "the value of " . $self->name . " is not defined";
539                     $proxy->$method_to_call(@_);
540                 });
541             }
542         }
543     }
544
545     return;
546 }
547
548 # private methods to help delegation ...
549
550 sub _canonicalize_handles {
551     my $self    = shift;
552     my $handles = $self->handles;
553     if (my $handle_type = ref($handles)) {
554         if ($handle_type eq 'HASH') {
555             return %{$handles};
556         }
557         elsif ($handle_type eq 'ARRAY') {
558             return map { $_ => $_ } @{$handles};
559         }
560         elsif ($handle_type eq 'Regexp') {
561             ($self->has_type_constraint)
562                 || confess "Cannot delegate methods based on a RegExpr without a type constraint (isa)";
563             return map  { ($_ => $_) }
564                    grep { /$handles/ } $self->_get_delegate_method_list;
565         }
566         elsif ($handle_type eq 'CODE') {
567             return $handles->($self, $self->_find_delegate_metaclass);
568         }
569         else {
570             confess "Unable to canonicalize the 'handles' option with $handles";
571         }
572     }
573     else {
574         my $role_meta = eval { $handles->meta };
575         if ($@) {
576             confess "Unable to canonicalize the 'handles' option with $handles because : $@";
577         }
578
579         (blessed $role_meta && $role_meta->isa('Moose::Meta::Role'))
580             || confess "Unable to canonicalize the 'handles' option with $handles because ->meta is not a Moose::Meta::Role";
581
582         return map { $_ => $_ } (
583             $role_meta->get_method_list,
584             $role_meta->get_required_method_list
585         );
586     }
587 }
588
589 sub _find_delegate_metaclass {
590     my $self = shift;
591     if (my $class = $self->_isa_metadata) {
592         # if the class does have
593         # a meta method, use it
594         return $class->meta if $class->can('meta');
595         # otherwise we might be
596         # dealing with a non-Moose
597         # class, and need to make
598         # our own metaclass
599         return Moose::Meta::Class->initialize($class);
600     }
601     elsif (my $role = $self->_does_metadata) {
602         # our role will always have
603         # a meta method
604         return $role->meta;
605     }
606     else {
607         confess "Cannot find delegate metaclass for attribute " . $self->name;
608     }
609 }
610
611 sub _get_delegate_method_list {
612     my $self = shift;
613     my $meta = $self->_find_delegate_metaclass;
614     if ($meta->isa('Class::MOP::Class')) {
615         return map  { $_->{name}                     }  # NOTE: !never! delegate &meta
616                grep { $_->{class} ne 'Moose::Object' && $_->{name} ne 'meta' }
617                     $meta->compute_all_applicable_methods;
618     }
619     elsif ($meta->isa('Moose::Meta::Role')) {
620         return $meta->get_method_list;
621     }
622     else {
623         confess "Unable to recognize the delegate metaclass '$meta'";
624     }
625 }
626
627 1;
628
629 __END__
630
631 =pod
632
633 =head1 NAME
634
635 Moose::Meta::Attribute - The Moose attribute metaclass
636
637 =head1 DESCRIPTION
638
639 This is a subclass of L<Class::MOP::Attribute> with Moose specific
640 extensions.
641
642 For the most part, the only time you will ever encounter an
643 instance of this class is if you are doing some serious deep
644 introspection. To really understand this class, you need to refer
645 to the L<Class::MOP::Attribute> documentation.
646
647 =head1 METHODS
648
649 =head2 Overridden methods
650
651 These methods override methods in L<Class::MOP::Attribute> and add
652 Moose specific features. You can safely assume though that they
653 will behave just as L<Class::MOP::Attribute> does.
654
655 =over 4
656
657 =item B<new>
658
659 =item B<clone>
660
661 =item B<does>
662
663 =item B<initialize_instance_slot>
664
665 =item B<install_accessors>
666
667 =item B<accessor_metaclass>
668
669 =item B<get_value>
670
671 =item B<set_value>
672
673   eval { $point->meta->get_attribute('x')->set_value($point, 'fourty-two') };
674   if($@) {
675     print "Oops: $@\n";
676   }
677
678 I<Attribute (x) does not pass the type constraint (Int) with 'fourty-two'>
679
680 Before setting the value, a check is made on the type constraint of
681 the attribute, if it has one, to see if the value passes it. If the
682 value fails to pass, the set operation dies with a L<Carp/confess>.
683
684 Any coercion to convert values is done before checking the type constraint.
685
686 To check a value against a type constraint before setting it, fetch the
687 attribute instance using L<Class::MOP::Class/find_attribute_by_name>,
688 fetch the type_constraint from the attribute using L<Moose::Meta::Attribute/type_constraint>
689 and call L<Moose::Meta::TypeConstraint/check>. See L<Moose::Cookbook::RecipeX>
690 for an example.
691
692 =back
693
694 =head2 Additional Moose features
695
696 Moose attributes support type-constraint checking, weak reference
697 creation and type coercion.
698
699 =over 4
700
701 =item B<interpolate_class_and_new>
702
703 =item B<interpolate_class>
704
705 When called as a class method causes interpretation of the C<metaclass> and
706 C<traits> options.
707
708 =item B<clone_and_inherit_options>
709
710 This is to support the C<has '+foo'> feature, it clones an attribute
711 from a superclass and allows a very specific set of changes to be made
712 to the attribute.
713
714 =item B<has_type_constraint>
715
716 Returns true if this meta-attribute has a type constraint.
717
718 =item B<type_constraint>
719
720 A read-only accessor for this meta-attribute's type constraint. For
721 more information on what you can do with this, see the documentation
722 for L<Moose::Meta::TypeConstraint>.
723
724 =item B<has_handles>
725
726 Returns true if this meta-attribute performs delegation.
727
728 =item B<handles>
729
730 This returns the value which was passed into the handles option.
731
732 =item B<is_weak_ref>
733
734 Returns true if this meta-attribute produces a weak reference.
735
736 =item B<is_required>
737
738 Returns true if this meta-attribute is required to have a value.
739
740 =item B<is_lazy>
741
742 Returns true if this meta-attribute should be initialized lazily.
743
744 NOTE: lazy attributes, B<must> have a C<default> or C<builder> field set.
745
746 =item B<is_lazy_build>
747
748 Returns true if this meta-attribute should be initialized lazily through
749 the builder generated by lazy_build. Using C<lazy_build =E<gt> 1> will
750 make your attribute required and lazy. In addition it will set the builder, clearer
751 and predicate options for you using the following convention.
752
753    #If your attribute name starts with an underscore:
754    has '_foo' => (lazy_build => 1);
755    #is the same as
756    has '_foo' => (lazy => 1, required => 1, predicate => '_has_foo', clearer => '_clear_foo', builder => '_build__foo);
757    # or
758    has '_foo' => (lazy => 1, required => 1, predicate => '_has_foo', clearer => '_clear_foo', default => sub{shift->_build__foo});
759
760    #If your attribute name does not start with an underscore:
761    has 'foo' => (lazy_build => 1);
762    #is the same as
763    has 'foo' => (lazy => 1, required => 1, predicate => 'has_foo', clearer => 'clear_foo', builder => '_build_foo);
764    # or
765    has 'foo' => (lazy => 1, required => 1, predicate => 'has_foo', clearer => 'clear_foo', default => sub{shift->_build_foo});
766
767 The reason for the different naming of the C<builder> is that the C<builder>
768 method is a private method while the C<clearer> and C<predicate> methods
769 are public methods.
770
771 NOTE: This means your class should provide a method whose name matches the value
772 of the builder part, in this case _build__foo or _build_foo.
773
774 =item B<should_coerce>
775
776 Returns true if this meta-attribute should perform type coercion.
777
778 =item B<should_auto_deref>
779
780 Returns true if this meta-attribute should perform automatic
781 auto-dereferencing.
782
783 NOTE: This can only be done for attributes whose type constraint is
784 either I<ArrayRef> or I<HashRef>.
785
786 =item B<has_trigger>
787
788 Returns true if this meta-attribute has a trigger set.
789
790 =item B<trigger>
791
792 This is a CODE reference which will be executed every time the
793 value of an attribute is assigned. The CODE ref will get two values,
794 the invocant and the new value. This can be used to handle I<basic>
795 bi-directional relations.
796
797 =item B<documentation>
798
799 This is a string which contains the documentation for this attribute.
800 It serves no direct purpose right now, but it might in the future
801 in some kind of automated documentation system perhaps.
802
803 =item B<has_documentation>
804
805 Returns true if this meta-attribute has any documentation.
806
807 =item B<applied_traits>
808
809 This will return the ARRAY ref of all the traits applied to this 
810 attribute, or if no traits have been applied, it returns C<undef>.
811
812 =item B<has_applied_traits>
813
814 Returns true if this meta-attribute has any traits applied.
815
816 =back
817
818 =head1 BUGS
819
820 All complex software has bugs lurking in it, and this module is no
821 exception. If you find a bug please either email me, or add the bug
822 to cpan-RT.
823
824 =head1 AUTHOR
825
826 Stevan Little E<lt>stevan@iinteractive.comE<gt>
827
828 Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
829
830 =head1 COPYRIGHT AND LICENSE
831
832 Copyright 2006-2008 by Infinity Interactive, Inc.
833
834 L<http://www.iinteractive.com>
835
836 This library is free software; you can redistribute it and/or modify
837 it under the same terms as Perl itself.
838
839 =cut