coercion happens during obj construction too
[gitmo/Moose.git] / lib / Moose / Meta / Attribute.pm
CommitLineData
c0e30cf5 1
2package Moose::Meta::Attribute;
3
4use strict;
5use warnings;
6
a15dff8d 7use Scalar::Util 'weaken', 'reftype';
8use Carp 'confess';
9
10use Moose::Util::TypeConstraints ':no_export';
11
5569c072 12our $VERSION = '0.02';
bc1e29b5 13
c0e30cf5 14use base 'Class::MOP::Attribute';
15
a15dff8d 16Moose::Meta::Attribute->meta->add_attribute(
4b598ea3 17 Class::MOP::Attribute->new('coerce' => (
18 reader => 'coerce',
19 predicate => 'has_coercion'
20 ))
21);
22
23Moose::Meta::Attribute->meta->add_attribute(
a15dff8d 24 Class::MOP::Attribute->new('weak_ref' => (
25 reader => 'weak_ref',
26 predicate => {
27 'has_weak_ref' => sub { $_[0]->weak_ref() ? 1 : 0 }
28 }
29 ))
30);
31
32Moose::Meta::Attribute->meta->add_attribute(
33 Class::MOP::Attribute->new('type_constraint' => (
34 reader => 'type_constraint',
35 predicate => 'has_type_constraint',
36 ))
37);
38
39Moose::Meta::Attribute->meta->add_before_method_modifier('new' => sub {
40 my (undef, undef, %options) = @_;
4b598ea3 41 if (exists $options{coerce} && $options{coerce}) {
42 (exists $options{type_constraint})
43 || confess "You cannot have coercion without specifying a type constraint";
44 confess "You cannot have a weak reference to a coerced value"
45 if $options{weak_ref};
46 }
a15dff8d 47 (reftype($options{type_constraint}) && reftype($options{type_constraint}) eq 'CODE')
29db16a9 48 || confess "Type cosntraint parameter must be a code-ref, not " . $options{type_constraint}
49 if exists $options{type_constraint};
c0e30cf5 50});
51
a15dff8d 52sub generate_accessor_method {
53 my ($self, $attr_name) = @_;
54 if ($self->has_type_constraint) {
55 if ($self->has_weak_ref) {
56 return sub {
57 if (scalar(@_) == 2) {
58 (defined $self->type_constraint->($_[1]))
5569c072 59 || confess "Attribute ($attr_name) does not pass the type contraint with '$_[1]'"
a15dff8d 60 if defined $_[1];
61 $_[0]->{$attr_name} = $_[1];
62 weaken($_[0]->{$attr_name});
63 }
64 $_[0]->{$attr_name};
65 };
66 }
67 else {
4b598ea3 68 if ($self->has_coercion) {
69 return sub {
70 if (scalar(@_) == 2) {
71 my $val = $self->coerce->($_[1]);
72 (defined $self->type_constraint->($val))
73 || confess "Attribute ($attr_name) does not pass the type contraint with '$val'"
74 if defined $val;
75 $_[0]->{$attr_name} = $val;
76 }
77 $_[0]->{$attr_name};
78 };
79 }
80 else {
81 return sub {
82 if (scalar(@_) == 2) {
83 (defined $self->type_constraint->($_[1]))
84 || confess "Attribute ($attr_name) does not pass the type contraint with '$_[1]'"
85 if defined $_[1];
86 $_[0]->{$attr_name} = $_[1];
87 }
88 $_[0]->{$attr_name};
89 };
90 }
a15dff8d 91 }
92 }
93 else {
94 if ($self->has_weak_ref) {
95 return sub {
96 if (scalar(@_) == 2) {
97 $_[0]->{$attr_name} = $_[1];
98 weaken($_[0]->{$attr_name});
99 }
100 $_[0]->{$attr_name};
101 };
102 }
103 else {
104 sub {
105 $_[0]->{$attr_name} = $_[1] if scalar(@_) == 2;
106 $_[0]->{$attr_name};
107 };
108 }
109 }
110}
111
112sub generate_writer_method {
113 my ($self, $attr_name) = @_;
114 if ($self->has_type_constraint) {
115 if ($self->has_weak_ref) {
116 return sub {
117 (defined $self->type_constraint->($_[1]))
5569c072 118 || confess "Attribute ($attr_name) does not pass the type contraint with '$_[1]'"
a15dff8d 119 if defined $_[1];
120 $_[0]->{$attr_name} = $_[1];
121 weaken($_[0]->{$attr_name});
122 };
123 }
124 else {
125 return sub {
126 (defined $self->type_constraint->($_[1]))
5569c072 127 || confess "Attribute ($attr_name) does not pass the type contraint with '$_[1]'"
a15dff8d 128 if defined $_[1];
129 $_[0]->{$attr_name} = $_[1];
130 };
131 }
132 }
133 else {
134 if ($self->has_weak_ref) {
135 return sub {
136 $_[0]->{$attr_name} = $_[1];
137 weaken($_[0]->{$attr_name});
138 };
139 }
140 else {
141 return sub { $_[0]->{$attr_name} = $_[1] };
142 }
143 }
144}
c0e30cf5 145
1461;
147
148__END__
149
150=pod
151
152=head1 NAME
153
e522431d 154Moose::Meta::Attribute - The Moose attribute metaobject
c0e30cf5 155
156=head1 SYNOPSIS
157
158=head1 DESCRIPTION
159
e522431d 160This is a subclass of L<Class::MOP::Attribute> with Moose specific
161extensions.
162
c0e30cf5 163=head1 METHODS
164
165=over 4
166
167=item B<new>
168
a15dff8d 169=item B<generate_accessor_method>
170
171=item B<generate_writer_method>
172
173=back
174
175=over 4
176
177=item B<has_type_constraint>
178
179=item B<type_constraint>
180
181=item B<has_weak_ref>
182
183=item B<weak_ref>
184
4b598ea3 185=item B<coerce>
186
187=item B<has_coercion>
188
c0e30cf5 189=back
190
191=head1 BUGS
192
193All complex software has bugs lurking in it, and this module is no
194exception. If you find a bug please either email me, or add the bug
195to cpan-RT.
196
c0e30cf5 197=head1 AUTHOR
198
199Stevan Little E<lt>stevan@iinteractive.comE<gt>
200
201=head1 COPYRIGHT AND LICENSE
202
203Copyright 2006 by Infinity Interactive, Inc.
204
205L<http://www.iinteractive.com>
206
207This library is free software; you can redistribute it and/or modify
208it under the same terms as Perl itself.
209
210=cut