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('coerce' => (
16 predicate => { 'has_coercion' => sub { $_[0]->coerce() ? 1 : 0 } }
19 __PACKAGE__->meta->add_attribute('weak_ref' => (
21 predicate => { 'has_weak_ref' => sub { $_[0]->weak_ref() ? 1 : 0 } }
24 __PACKAGE__->meta->add_attribute('type_constraint' => (
25 reader => 'type_constraint',
26 predicate => 'has_type_constraint',
29 __PACKAGE__->meta->add_before_method_modifier('new' => sub {
30 my (undef, undef, %options) = @_;
31 if (exists $options{coerce} && $options{coerce}) {
32 (exists $options{type_constraint})
33 || confess "You cannot have coercion without specifying a type constraint";
34 confess "You cannot have a weak reference to a coerced value"
35 if $options{weak_ref};
39 sub generate_accessor_method {
40 my ($self, $attr_name) = @_;
41 if ($self->has_type_constraint) {
42 if ($self->has_weak_ref) {
44 if (scalar(@_) == 2) {
45 (defined $self->type_constraint->constraint_code->($_[1]))
46 || confess "Attribute ($attr_name) does not pass the type contraint with '$_[1]'"
48 $_[0]->{$attr_name} = $_[1];
49 weaken($_[0]->{$attr_name});
55 if ($self->has_coercion) {
57 if (scalar(@_) == 2) {
58 my $val = $self->type_constraint->coercion_code->($_[1]);
59 (defined $self->type_constraint->constraint_code->($val))
60 || confess "Attribute ($attr_name) does not pass the type contraint with '$val'"
62 $_[0]->{$attr_name} = $val;
69 if (scalar(@_) == 2) {
70 (defined $self->type_constraint->constraint_code->($_[1]))
71 || confess "Attribute ($attr_name) does not pass the type contraint with '$_[1]'"
73 $_[0]->{$attr_name} = $_[1];
81 if ($self->has_weak_ref) {
83 if (scalar(@_) == 2) {
84 $_[0]->{$attr_name} = $_[1];
85 weaken($_[0]->{$attr_name});
92 $_[0]->{$attr_name} = $_[1] if scalar(@_) == 2;
99 sub generate_writer_method {
100 my ($self, $attr_name) = @_;
101 if ($self->has_type_constraint) {
102 if ($self->has_weak_ref) {
104 (defined $self->type_constraint->constraint_code->($_[1]))
105 || confess "Attribute ($attr_name) does not pass the type contraint with '$_[1]'"
107 $_[0]->{$attr_name} = $_[1];
108 weaken($_[0]->{$attr_name});
112 if ($self->has_coercion) {
114 my $val = $self->type_constraint->coercion_code->($_[1]);
115 (defined $self->type_constraint->constraint_code->($val))
116 || confess "Attribute ($attr_name) does not pass the type contraint with '$val'"
118 $_[0]->{$attr_name} = $val;
123 (defined $self->type_constraint->constraint_code->($_[1]))
124 || confess "Attribute ($attr_name) does not pass the type contraint with '$_[1]'"
126 $_[0]->{$attr_name} = $_[1];
132 if ($self->has_weak_ref) {
134 $_[0]->{$attr_name} = $_[1];
135 weaken($_[0]->{$attr_name});
139 return sub { $_[0]->{$attr_name} = $_[1] };
152 Moose::Meta::Attribute - The Moose attribute metaobject
158 This is a subclass of L<Class::MOP::Attribute> with Moose specific
167 =item B<generate_accessor_method>
169 =item B<generate_writer_method>
175 =item B<has_type_constraint>
177 =item B<type_constraint>
179 =item B<has_weak_ref>
185 =item B<has_coercion>
191 All complex software has bugs lurking in it, and this module is no
192 exception. If you find a bug please either email me, or add the bug
197 Stevan Little E<lt>stevan@iinteractive.comE<gt>
199 =head1 COPYRIGHT AND LICENSE
201 Copyright 2006 by Infinity Interactive, Inc.
203 L<http://www.iinteractive.com>
205 This library is free software; you can redistribute it and/or modify
206 it under the same terms as Perl itself.