Commit | Line | Data |
32726d88 |
1 | package MooseX::StrictConstructor; |
2 | |
3 | use strict; |
4 | use warnings; |
5 | |
2c33a849 |
6 | use Moose 0.94 (); |
0cdff431 |
7 | use Moose::Exporter; |
fbfaa61f |
8 | use Moose::Util::MetaRole; |
7815dbf4 |
9 | |
10 | { |
0dc0aea2 |
11 | my %class_meta = ( class => ['MooseX::StrictConstructor::Trait::Class'] ); |
12 | |
7815dbf4 |
13 | |
14 | if ( $Moose::VERSION < 1.9900 ) { |
1a4f7732 |
15 | require MooseX::StrictConstructor::Trait::Method::Constructor; |
0dc0aea2 |
16 | $class_meta{constructor} |
17 | = ['MooseX::StrictConstructor::Trait::Method::Constructor']; |
7815dbf4 |
18 | } |
19 | |
20 | Moose::Exporter->setup_import_methods( |
709eccb9 |
21 | class_metaroles => \%class_meta, |
7815dbf4 |
22 | ); |
4a070866 |
23 | |
24 | my $old_import = __PACKAGE__->can('import'); |
25 | no warnings 'redefine'; |
26 | *import = sub { |
27 | my $caller = caller; |
28 | Carp::croak "$_[0] can only be applied to Moose classes" |
29 | unless eval { $caller->meta->isa('Moose::Meta::Class') }; |
30 | |
31 | goto &$old_import; |
32 | }; |
7815dbf4 |
33 | } |
32726d88 |
34 | |
32726d88 |
35 | 1; |
36 | |
5b66b6d4 |
37 | # ABSTRACT: Make your object constructors blow up on unknown attributes |
38 | |
32726d88 |
39 | __END__ |
40 | |
41 | =pod |
42 | |
32726d88 |
43 | =head1 SYNOPSIS |
44 | |
2ffa7b60 |
45 | package My::Class; |
32726d88 |
46 | |
f2f2a5dc |
47 | use Moose; |
48 | use MooseX::StrictConstructor; |
32726d88 |
49 | |
2ffa7b60 |
50 | has 'size' => ...; |
32726d88 |
51 | |
2ffa7b60 |
52 | # then later ... |
53 | |
54 | # this blows up because color is not a known attribute |
55 | My::Class->new( size => 5, color => 'blue' ); |
32726d88 |
56 | |
57 | =head1 DESCRIPTION |
58 | |
f2f2a5dc |
59 | Simply loading this module makes your constructors "strict". If your |
60 | constructor is called with an attribute init argument that your class |
714128ef |
61 | does not declare, then it calls C<Moose->throw_error()>. This is a great way |
f2f2a5dc |
62 | to catch small typos. |
2ffa7b60 |
63 | |
64 | =head2 Subverting Strictness |
65 | |
fbfaa61f |
66 | You may find yourself wanting to have your constructor accept a |
67 | parameter which does not correspond to an attribute. |
2ffa7b60 |
68 | |
fbfaa61f |
69 | In that case, you'll probably also be writing a C<BUILD()> or |
70 | C<BUILDARGS()> method to deal with that parameter. In a C<BUILDARGS()> |
71 | method, you can simply make sure that this parameter is not included |
72 | in the hash reference you return. Otherwise, in a C<BUILD()> method, |
73 | you can delete it from the hash reference of parameters. |
2ffa7b60 |
74 | |
75 | sub BUILD { |
76 | my $self = shift; |
77 | my $params = shift; |
32726d88 |
78 | |
2ffa7b60 |
79 | if ( delete $params->{do_something} ) { |
80 | ... |
81 | } |
82 | } |
32726d88 |
83 | |
98630abc |
84 | =head2 Usage from roles |
85 | |
86 | It usually doesn't make sense for a role to force its consuming class to use a |
87 | strict constructor, so this is not normally permitted. If you desire this |
88 | behaviour, you can use C<MooseX::StrictConstructor::FromRole> instead. |
89 | |
32726d88 |
90 | =head1 BUGS |
91 | |
2ffa7b60 |
92 | Please report any bugs or feature requests to |
93 | C<bug-moosex-strictconstructor@rt.cpan.org>, or through the web |
94 | interface at L<http://rt.cpan.org>. I will be notified, and then |
95 | you'll automatically be notified of progress on your bug as I make |
96 | changes. |
32726d88 |
97 | |
32726d88 |
98 | =cut |