Fix grammar in warning
[gitmo/Moose.git] / lib / Moose / Meta / Attribute / Native / Trait.pm
CommitLineData
e3c07b19 1
c466e58f 2package Moose::Meta::Attribute::Native::Trait;
e3c07b19 3use Moose::Role;
3cf2f9ec 4
efa806d8 5use List::MoreUtils qw( any uniq );
e3c07b19 6use Moose::Util::TypeConstraints;
34d6d196 7use Moose::Deprecated;
e3c07b19 8
bb09ad91 9our $VERSION = '1.17';
e3c07b19 10$VERSION = eval $VERSION;
11our $AUTHORITY = 'cpan:STEVAN';
12
2e069f5a 13requires '_helper_type';
e3c07b19 14
efa806d8 15has _used_default_is => (
16 is => 'rw',
17 isa => 'Bool',
18 default => 0,
19);
20
2edb73d9 21before '_process_options' => sub {
22 my ( $self, $name, $options ) = @_;
e3c07b19 23
2edb73d9 24 $self->_check_helper_type( $options, $name );
e3c07b19 25
3cf2f9ec 26 if ( !( any { exists $options->{$_} } qw( is reader writer accessor ) )
27 && $self->can('_default_is') ) {
28
34d6d196 29 $options->{is} = $self->_default_is;
30
efa806d8 31 $options->{_used_default_is} = 1;
34d6d196 32 }
33
3cf2f9ec 34 if (
35 !(
36 $options->{required}
b558f8a6 37 || any { exists $options->{$_} } qw( default builder lazy_build )
3cf2f9ec 38 )
39 && $self->can('_default_default')
40 ) {
41
34d6d196 42 $options->{default} = $self->_default_default;
43
44 Moose::Deprecated::deprecated(
45 feature => 'default default for Native Trait',
46 message =>
cab2e1d0 47 'Allowing a native trait to automatically supply a default is deprecated.'
557ae2ff 48 . ' You can avoid this warning by supplying a default, builder, or making the attribute required'
34d6d196 49 );
50 }
2edb73d9 51};
e3c07b19 52
efa806d8 53after 'install_accessors' => sub {
54 my $self = shift;
55
56 return unless $self->_used_default_is;
57
58 my @methods
59 = $self->_default_is eq 'rw'
60 ? qw( reader writer accessor )
61 : 'reader';
62
63 my $name = $self->name;
64 my $class = $self->associated_class->name;
65
66 for my $meth ( uniq grep {defined} map { $self->$_ } @methods ) {
67
68 my $message
69 = "The $meth method in the $class class was automatically created"
70 . " by the native delegation trait for the $name attribute."
71 . q{ This "default is" feature is deprecated.}
72 . q{ Explicitly set "is" or define accessor names to avoid this};
73
74 $self->associated_class->add_before_method_modifier(
75 $meth => sub {
76 Moose::Deprecated::deprecated(
77 feature => 'default is for Native Trait',
78 message =>$message,
79 );
80 }
81 );
82 }
83 };
84
2edb73d9 85sub _check_helper_type {
86 my ( $self, $options, $name ) = @_;
e3c07b19 87
2e069f5a 88 my $type = $self->_helper_type;
2edb73d9 89
2e069f5a 90 $options->{isa} = $type
2edb73d9 91 unless exists $options->{isa};
92
93 my $isa = Moose::Util::TypeConstraints::find_or_create_type_constraint(
94 $options->{isa} );
95
96 ( $isa->is_a_type_of($type) )
97 || confess
98 "The type constraint for $name must be a subtype of $type but it's a $isa";
99}
e3c07b19 100
2edb73d9 101before 'install_accessors' => sub { (shift)->_check_handles_values };
5404f169 102
2edb73d9 103sub _check_handles_values {
e3c07b19 104 my $self = shift;
105
5404f169 106 my %handles = $self->_canonicalize_handles;
e3c07b19 107
046c8b5e 108 for my $original_method ( values %handles ) {
5404f169 109 my $name = $original_method->[0];
f7fd22b6 110
ffc2e25f 111 my $accessor_class = $self->_native_accessor_class_for($name);
f7fd22b6 112
78aee58f 113 ( $accessor_class && $accessor_class->can('new') )
114 || confess
115 "$name is an unsupported method type - $accessor_class";
e3c07b19 116 }
5404f169 117}
e3c07b19 118
d4dc38ed 119around '_canonicalize_handles' => sub {
120 shift;
121 my $self = shift;
122 my $handles = $self->handles;
123
124 return unless $handles;
125
126 unless ( 'HASH' eq ref $handles ) {
127 $self->throw_error(
128 "The 'handles' option must be a HASH reference, not $handles");
129 }
130
131 return map {
132 my $to = $handles->{$_};
133 $to = [$to] unless ref $to;
134 $_ => $to
135 } keys %$handles;
136};
137
18281451 138around '_make_delegation_method' => sub {
139 my $next = shift;
046c8b5e 140 my ( $self, $handle_name, $method_to_call ) = @_;
18281451 141
3c573ca4 142 my ( $name, @curried_args ) = @$method_to_call;
18281451 143
ffc2e25f 144 my $accessor_class = $self->_native_accessor_class_for($name);
18281451 145
78aee58f 146 die "Cannot find an accessor class for $name"
147 unless $accessor_class && $accessor_class->can('new');
148
149 return $accessor_class->new(
8b9641b8 150 name => $handle_name,
151 package_name => $self->associated_class->name,
152 delegate_to_method => $name,
153 attribute => $self,
154 is_inline => 1,
155 curried_arguments => \@curried_args,
156 root_types => [ $self->_root_types ],
78aee58f 157 );
18281451 158};
159
a6ae7438 160sub _root_types {
161 return $_[0]->_helper_type;
162}
163
ffc2e25f 164sub _native_accessor_class_for {
165 my ( $self, $suffix ) = @_;
166
8b9641b8 167 my $role
168 = 'Moose::Meta::Method::Accessor::Native::'
169 . $self->_native_type . '::'
170 . $suffix;
171
172 return Moose::Meta::Class->create_anon_class(
173 superclasses =>
174 [ $self->accessor_metaclass, $self->delegation_metaclass ],
175 roles => [$role],
176 cache => 1,
177 )->name;
f7fd22b6 178}
179
15715245 180sub _build_native_type {
181 my $self = shift;
182
183 for my $role_name ( map { $_->name } $self->meta->calculate_all_roles ) {
184 return $1 if $role_name =~ /::Native::Trait::(\w+)$/;
185 }
186
187 die "Cannot calculate native type for " . ref $self;
188}
189
190has '_native_type' => (
191 is => 'ro',
192 isa => 'Str',
193 lazy => 1,
194 builder => '_build_native_type',
195);
196
e3c07b19 197no Moose::Role;
198no Moose::Util::TypeConstraints;
199
2001;
201
202__END__
203
204=head1 NAME
205
e132fd56 206Moose::Meta::Attribute::Native::Trait - Shared role for native delegation traits
e3c07b19 207
e3c07b19 208=head1 BUGS
209
d4048ef3 210See L<Moose/BUGS> for details on reporting bugs.
e3c07b19 211
1af5d116 212=head1 SEE ALSO
213
e132fd56 214Documentation for Moose native traits can be found in
215L<Moose::Meta::Attribute::Native>.
1af5d116 216
e3c07b19 217=head1 AUTHORS
218
219Yuval Kogman
220
221Shawn M Moore
222
223Jesse Luehrs
224
225=head1 COPYRIGHT AND LICENSE
226
227Copyright 2007-2009 by Infinity Interactive, Inc.
228
229L<http://www.iinteractive.com>
230
231This library is free software; you can redistribute it and/or modify
232it under the same terms as Perl itself.
233
234=cut