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