move repository to http://github.com/moose/MooseX-AlwaysCoerce
[gitmo/MooseX-AlwaysCoerce.git] / lib / MooseX / AlwaysCoerce.pm
CommitLineData
7a603ffa 1package MooseX::AlwaysCoerce;
2bf37211 2# ABSTRACT: Automatically enable coercions for Moose attributes
7a603ffa 3
4use strict;
5use warnings;
6
f99502c4 7use namespace::autoclean 0.12;
ad1917d7 8use Moose ();
f99502c4 9use MooseX::ClassAttribute 0.24 ();
ad1917d7 10use Moose::Exporter;
2429fb7e 11use Moose::Util::MetaRole;
ad1917d7 12use Carp;
13
2429fb7e 14Moose::Exporter->setup_import_methods;
ad1917d7 15
c3fabb0c 16=pod
17
d4914d04 18=for stopwords coercions
19
7a603ffa 20=head1 SYNOPSIS
21
22 package MyClass;
23
24 use Moose;
25 use MooseX::AlwaysCoerce;
26 use MyTypeLib 'SomeType';
27
ad1917d7 28 has foo => (is => 'rw', isa => SomeType); # coerce => 1 automatically added
29
2429fb7e 30 # same, MooseX::ClassAttribute is automatically applied
ad1917d7 31 class_has bar => (is => 'rw', isa => SomeType);
32
33=head1 DESCRIPTION
34
d4914d04 35Have you ever spent an hour or more trying to figure out "Hey, why did my
ad1917d7 36coercion not run?" only to find out that you forgot C<< coerce => 1 >> ?
37
38Just load this module in your L<Moose> class and C<< coerce => 1 >> will be
2429fb7e 39enabled for every attribute and class attribute automatically.
ad1917d7 40
44b44091 41Use C<< coerce => 0 >> to disable a coercion explicitly.
42
ad1917d7 43=cut
44
2429fb7e 45{
46 package MooseX::AlwaysCoerce::Role::Meta::Attribute;
47 use namespace::autoclean;
48 use Moose::Role;
49
62e7cdef 50 around should_coerce => sub {
51 my $orig = shift;
52 my $self = shift;
53
54 my $current_val = $self->$orig(@_);
b058bf61 55
90d2721a 56 return $current_val if defined $current_val;
57
bb7cca58 58 return 1 if $self->type_constraint && $self->type_constraint->has_coercion;
62e7cdef 59 return 0;
60 };
2429fb7e 61
62 package MooseX::AlwaysCoerce::Role::Meta::Class;
63 use namespace::autoclean;
64 use Moose::Role;
b058bf61 65 use Moose::Util::TypeConstraints;
2429fb7e 66
67 around add_class_attribute => sub {
68 my $next = shift;
69 my $self = shift;
44b44091 70 my ($what, %opts) = @_;
71
bb7cca58 72 if (exists $opts{isa}) {
73 my $type = Moose::Util::TypeConstraints::find_or_parse_type_constraint($opts{isa});
74 $opts{coerce} = 1 if not exists $opts{coerce} and $type->has_coercion;
75 }
44b44091 76
77 $self->$next($what, %opts);
e6737767 78 };
ad1917d7 79}
80
e307e391 81my (undef, undef, $init_meta) = Moose::Exporter->build_import_methods(
a193e05d 82
e307e391 83 install => [ qw(import unimport) ],
a193e05d 84
e307e391 85 class_metaroles => {
86 attribute => ['MooseX::AlwaysCoerce::Role::Meta::Attribute'],
87 class => ['MooseX::AlwaysCoerce::Role::Meta::Class'],
88 },
a193e05d 89
62e7cdef 90 role_metaroles => {
4fb8b2bf 91 (Moose->VERSION >= 1.9900
92 ? (applied_attribute => ['MooseX::AlwaysCoerce::Role::Meta::Attribute'])
93 : ()),
62e7cdef 94 role => ['MooseX::AlwaysCoerce::Role::Meta::Class'],
95 }
e307e391 96);
97
2429fb7e 98sub init_meta {
e307e391 99 my ($class, %options) = @_;
2429fb7e 100 my $for_class = $options{for_class};
101
62e7cdef 102 MooseX::ClassAttribute->import({ into => $for_class });
2429fb7e 103
e307e391 104 # call generated method to do the rest of the work.
105 goto $init_meta;
ad1917d7 106}
7a603ffa 107
f4017198 1081;
109# vim:et sts=4 sw=4 tw=0:
110__END__
111
112=for Pod::Coverage
113 init_meta
114
7a603ffa 115=head1 BUGS
116
117Please report any bugs or feature requests to C<bug-moosex-alwayscoerce at rt.cpan.org>, or through
118the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=MooseX-AlwaysCoerce>. I will be notified, and then you'll
119automatically be notified of progress on your bug as I make changes.
120
121=head1 SUPPORT
122
123You can find more information at:
124
125=over 4
126
127=item * RT: CPAN's request tracker
128
129L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=MooseX-AlwaysCoerce>
130
d4914d04 131=for stopwords AnnoCPAN
132
7a603ffa 133=item * AnnoCPAN: Annotated CPAN documentation
134
135L<http://annocpan.org/dist/MooseX-AlwaysCoerce>
136
137=item * CPAN Ratings
138
139L<http://cpanratings.perl.org/d/MooseX-AlwaysCoerce>
140
141=item * Search CPAN
142
143L<http://search.cpan.org/dist/MooseX-AlwaysCoerce/>
144
145=back
146
147=head1 ACKNOWLEDGEMENTS
148
149My own stupidity, for inspiring me to write this module.
150
d4914d04 151=for stopwords Rolsky
152
2429fb7e 153Dave Rolsky, for telling me how to do it the L<Moose> way.
154
7a603ffa 155=cut