basic-type-coercion
[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(
17 Class::MOP::Attribute->new('weak_ref' => (
18 reader => 'weak_ref',
19 predicate => {
20 'has_weak_ref' => sub { $_[0]->weak_ref() ? 1 : 0 }
21 }
22 ))
23);
24
25Moose::Meta::Attribute->meta->add_attribute(
26 Class::MOP::Attribute->new('type_constraint' => (
27 reader => 'type_constraint',
28 predicate => 'has_type_constraint',
29 ))
30);
31
32Moose::Meta::Attribute->meta->add_before_method_modifier('new' => sub {
33 my (undef, undef, %options) = @_;
34 (reftype($options{type_constraint}) && reftype($options{type_constraint}) eq 'CODE')
29db16a9 35 || confess "Type cosntraint parameter must be a code-ref, not " . $options{type_constraint}
36 if exists $options{type_constraint};
c0e30cf5 37});
38
a15dff8d 39sub generate_accessor_method {
40 my ($self, $attr_name) = @_;
41 if ($self->has_type_constraint) {
42 if ($self->has_weak_ref) {
43 return sub {
44 if (scalar(@_) == 2) {
45 (defined $self->type_constraint->($_[1]))
5569c072 46 || confess "Attribute ($attr_name) does not pass the type contraint with '$_[1]'"
a15dff8d 47 if defined $_[1];
48 $_[0]->{$attr_name} = $_[1];
49 weaken($_[0]->{$attr_name});
50 }
51 $_[0]->{$attr_name};
52 };
53 }
54 else {
55 return sub {
56 if (scalar(@_) == 2) {
57 (defined $self->type_constraint->($_[1]))
5569c072 58 || confess "Attribute ($attr_name) does not pass the type contraint with '$_[1]'"
a15dff8d 59 if defined $_[1];
60 $_[0]->{$attr_name} = $_[1];
61 }
62 $_[0]->{$attr_name};
63 };
64 }
65 }
66 else {
67 if ($self->has_weak_ref) {
68 return sub {
69 if (scalar(@_) == 2) {
70 $_[0]->{$attr_name} = $_[1];
71 weaken($_[0]->{$attr_name});
72 }
73 $_[0]->{$attr_name};
74 };
75 }
76 else {
77 sub {
78 $_[0]->{$attr_name} = $_[1] if scalar(@_) == 2;
79 $_[0]->{$attr_name};
80 };
81 }
82 }
83}
84
85sub generate_writer_method {
86 my ($self, $attr_name) = @_;
87 if ($self->has_type_constraint) {
88 if ($self->has_weak_ref) {
89 return sub {
90 (defined $self->type_constraint->($_[1]))
5569c072 91 || confess "Attribute ($attr_name) does not pass the type contraint with '$_[1]'"
a15dff8d 92 if defined $_[1];
93 $_[0]->{$attr_name} = $_[1];
94 weaken($_[0]->{$attr_name});
95 };
96 }
97 else {
98 return sub {
99 (defined $self->type_constraint->($_[1]))
5569c072 100 || confess "Attribute ($attr_name) does not pass the type contraint with '$_[1]'"
a15dff8d 101 if defined $_[1];
102 $_[0]->{$attr_name} = $_[1];
103 };
104 }
105 }
106 else {
107 if ($self->has_weak_ref) {
108 return sub {
109 $_[0]->{$attr_name} = $_[1];
110 weaken($_[0]->{$attr_name});
111 };
112 }
113 else {
114 return sub { $_[0]->{$attr_name} = $_[1] };
115 }
116 }
117}
c0e30cf5 118
1191;
120
121__END__
122
123=pod
124
125=head1 NAME
126
e522431d 127Moose::Meta::Attribute - The Moose attribute metaobject
c0e30cf5 128
129=head1 SYNOPSIS
130
131=head1 DESCRIPTION
132
e522431d 133This is a subclass of L<Class::MOP::Attribute> with Moose specific
134extensions.
135
c0e30cf5 136=head1 METHODS
137
138=over 4
139
140=item B<new>
141
a15dff8d 142=item B<generate_accessor_method>
143
144=item B<generate_writer_method>
145
146=back
147
148=over 4
149
150=item B<has_type_constraint>
151
152=item B<type_constraint>
153
154=item B<has_weak_ref>
155
156=item B<weak_ref>
157
c0e30cf5 158=back
159
160=head1 BUGS
161
162All complex software has bugs lurking in it, and this module is no
163exception. If you find a bug please either email me, or add the bug
164to cpan-RT.
165
c0e30cf5 166=head1 AUTHOR
167
168Stevan Little E<lt>stevan@iinteractive.comE<gt>
169
170=head1 COPYRIGHT AND LICENSE
171
172Copyright 2006 by Infinity Interactive, Inc.
173
174L<http://www.iinteractive.com>
175
176This library is free software; you can redistribute it and/or modify
177it under the same terms as Perl itself.
178
179=cut