2 package Moose::Meta::Attribute;
7 use Scalar::Util 'weaken', 'reftype';
10 our $VERSION = '0.02';
12 use base 'Class::MOP::Attribute';
14 __PACKAGE__->meta->add_attribute('required' => (reader => 'is_required' ));
15 __PACKAGE__->meta->add_attribute('lazy' => (reader => 'is_lazy' ));
16 __PACKAGE__->meta->add_attribute('coerce' => (reader => 'should_coerce'));
17 __PACKAGE__->meta->add_attribute('weak_ref' => (reader => 'is_weak_ref' ));
18 __PACKAGE__->meta->add_attribute('type_constraint' => (
19 reader => 'type_constraint',
20 predicate => 'has_type_constraint',
23 __PACKAGE__->meta->add_before_method_modifier('new' => sub {
24 my (undef, undef, %options) = @_;
25 if (exists $options{coerce} && $options{coerce}) {
26 (exists $options{type_constraint})
27 || confess "You cannot have coercion without specifying a type constraint";
28 confess "You cannot have a weak reference to a coerced value"
29 if $options{weak_ref};
31 if (exists $options{lazy} && $options{lazy}) {
32 (exists $options{default})
33 || confess "You cannot have lazy attribute without specifying a default value for it";
37 sub generate_accessor_method {
38 my ($self, $attr_name) = @_;
39 my $value_name = $self->should_coerce ? '$val' : '$_[1]';
41 . 'if (scalar(@_) == 2) {'
42 . ($self->is_required ?
43 'defined($_[1]) || confess "Attribute ($attr_name) is required, so cannot be set to undef";'
45 . ($self->should_coerce ?
46 'my $val = $self->type_constraint->coercion->coerce($_[1]);'
48 . ($self->has_type_constraint ?
49 ('(defined $self->type_constraint->check(' . $value_name . '))'
50 . '|| confess "Attribute ($attr_name) does not pass the type contraint with \'' . $value_name . '\'"'
51 . 'if defined ' . $value_name . ';')
53 . '$_[0]->{$attr_name} = ' . $value_name . ';'
54 . ($self->is_weak_ref ?
55 'weaken($_[0]->{$attr_name});'
59 '$_[0]->{$attr_name} = ($self->has_default ? $self->default($_[0]) : undef)'
60 . 'unless exists $_[0]->{$attr_name};'
62 . ' $_[0]->{$attr_name};'
65 confess "Could not create writer for '$attr_name' because $@ \n code: $code" if $@;
69 sub generate_writer_method {
70 my ($self, $attr_name) = @_;
71 my $value_name = $self->should_coerce ? '$val' : '$_[1]';
73 . ($self->is_required ?
74 'defined($_[1]) || confess "Attribute ($attr_name) is required, so cannot be set to undef";'
76 . ($self->should_coerce ?
77 'my $val = $self->type_constraint->coercion->coerce($_[1]);'
79 . ($self->has_type_constraint ?
80 ('(defined $self->type_constraint->check(' . $value_name . '))'
81 . '|| confess "Attribute ($attr_name) does not pass the type contraint with \'' . $value_name . '\'"'
82 . 'if defined ' . $value_name . ';')
84 . '$_[0]->{$attr_name} = ' . $value_name . ';'
85 . ($self->is_weak_ref ?
86 'weaken($_[0]->{$attr_name});'
90 confess "Could not create writer for '$attr_name' because $@ \n code: $code" if $@;
94 sub generate_reader_method {
95 my ($self, $attr_name) = @_;
97 . 'confess "Cannot assign a value to a read-only accessor" if @_ > 1;'
99 '$_[0]->{$attr_name} = ($self->has_default ? $self->default($_[0]) : undef)'
100 . 'unless exists $_[0]->{$attr_name};'
102 . '$_[0]->{$attr_name};'
104 my $sub = eval $code;
105 confess "Could not create reader for '$attr_name' because $@ \n code: $code" if $@;
117 Moose::Meta::Attribute - The Moose attribute metaclass
121 This is a subclass of L<Class::MOP::Attribute> with Moose specific
124 For the most part, the only time you will ever encounter an
125 instance of this class is if you are doing some serious deep
126 introspection. To really understand this class, you need to refer
127 to the L<Class::MOP::Attribute> documentation.
131 =head2 Overridden methods
133 These methods override methods in L<Class::MOP::Attribute> and add
134 Moose specific features. You can safely assume though that they
135 will behave just as L<Class::MOP::Attribute> does.
141 =item B<generate_accessor_method>
143 =item B<generate_writer_method>
145 =item B<generate_reader_method>
149 =head2 Additional Moose features
151 Moose attributes support type-contstraint checking, weak reference
152 creation and type coercion.
156 =item B<has_type_constraint>
158 Returns true if this meta-attribute has a type constraint.
160 =item B<type_constraint>
162 A read-only accessor for this meta-attribute's type constraint. For
163 more information on what you can do with this, see the documentation
164 for L<Moose::Meta::TypeConstraint>.
168 Returns true of this meta-attribute produces a weak reference.
172 Returns true of this meta-attribute is required to have a value.
176 Returns true of this meta-attribute should be initialized lazily.
178 NOTE: lazy attributes, B<must> have a C<default> field set.
180 =item B<should_coerce>
182 Returns true of this meta-attribute should perform type coercion.
188 All complex software has bugs lurking in it, and this module is no
189 exception. If you find a bug please either email me, or add the bug
194 Stevan Little E<lt>stevan@iinteractive.comE<gt>
196 =head1 COPYRIGHT AND LICENSE
198 Copyright 2006 by Infinity Interactive, Inc.
200 L<http://www.iinteractive.com>
202 This library is free software; you can redistribute it and/or modify
203 it under the same terms as Perl itself.