redo constructor class as a role too
[gitmo/MooseX-StrictConstructor.git] / lib / MooseX / StrictConstructor.pm
CommitLineData
32726d88 1package MooseX::StrictConstructor;
2
3use strict;
4use warnings;
5
c94bcaec 6our $VERSION = '0.06';
32726d88 7
0cdff431 8use Class::MOP ();
9use Moose ();
10use Moose::Exporter;
11use MooseX::StrictConstructor::Role::Object;
12use MooseX::StrictConstructor::Role::Metaclass;
32726d88 13
0cdff431 14Moose::Exporter->setup_import_methods( also => 'Moose' );
32726d88 15
0cdff431 16sub init_meta
32726d88 17{
0cdff431 18 shift;
19 my %p = @_;
20
21 Moose->init_meta(%p);
22
23 my $caller = $p{for_class};
24
25 my $metameta = $caller->meta()->meta();
26 unless ( $metameta->can('does_role')
27 && $metameta->does_role( 'MooseX::StrictConstructor::Role::Metaclass' ) )
28 {
29 my $new_meta =
30 Moose::Meta::Class->create_anon_class
31 ( superclasses => [ ref $caller->meta() ],
32 roles => [ 'MooseX::StrictConstructor::Role::Metaclass' ],
33 cache => 1,
34 );
35
36 Class::MOP::remove_metaclass_by_name($caller);
37
38 $new_meta->name()->initialize($caller);
39 }
40
41 unless ( $caller->meta()->does_role('MooseX::StrictConstructor::Role::Object') )
42 {
43 my $new_base =
44 Moose::Meta::Class->create_anon_class
45 ( superclasses => [ $caller->meta()->superclasses() ],
46 roles => [ 'MooseX::StrictConstructor::Role::Object' ],
47 cache => 1,
48 );
49
50 $caller->meta()->superclasses( $new_base->name() );
51 }
52
53 return $caller->meta();
32726d88 54}
55
32726d88 561;
57
58__END__
59
60=pod
61
62=head1 NAME
63
2ffa7b60 64MooseX::StrictConstructor - Make your object constructors blow up on unknown attributes
32726d88 65
66=head1 SYNOPSIS
67
2ffa7b60 68 package My::Class;
32726d88 69
2ffa7b60 70 use MooseX::StrictConstructor; # instead of use Moose
32726d88 71
2ffa7b60 72 has 'size' => ...;
32726d88 73
2ffa7b60 74 # then later ...
75
76 # this blows up because color is not a known attribute
77 My::Class->new( size => 5, color => 'blue' );
32726d88 78
79=head1 DESCRIPTION
80
2ffa7b60 81Using this class to load Moose instead of just loading using Moose
82itself makes your constructors "strict". If your constructor is called
a83dec43 83with an attribute init argument that your class does not declare, then
84it calls "Carp::confess()". This is a great way to catch small typos.
2ffa7b60 85
86=head2 Subverting Strictness
87
88You may find yourself wanting to accept a parameter to the constructor
89that is not the name of an attribute.
90
91In that case, you'll probably be writing a C<BUILD()> method to deal
92with it. Your C<BUILD()> method will receive two parameters, the new
93object, and a hash reference of parameters passed to the constructor.
94
95If you delete keys from this hash reference, then they will not be
96seen when this class does its checking.
97
98 sub BUILD {
99 my $self = shift;
100 my $params = shift;
32726d88 101
2ffa7b60 102 if ( delete $params->{do_something} ) {
103 ...
104 }
105 }
32726d88 106
c001451a 107=head2 Caveats
108
109Using this class replaces the default Moose meta class,
110C<Moose::Meta::Class>, with its own,
111C<MooseX::StrictConstructor::Meta::Class>. If you have your own meta
112class, this distro will probably not work for you.
113
32726d88 114=head1 AUTHOR
115
116Dave Rolsky, C<< <autarch@urth.org> >>
117
118=head1 BUGS
119
2ffa7b60 120Please report any bugs or feature requests to
121C<bug-moosex-strictconstructor@rt.cpan.org>, or through the web
122interface at L<http://rt.cpan.org>. I will be notified, and then
123you'll automatically be notified of progress on your bug as I make
124changes.
32726d88 125
126=head1 COPYRIGHT & LICENSE
127
128Copyright 2007 Dave Rolsky, All Rights Reserved.
129
130This program is free software; you can redistribute it and/or modify
131it under the same terms as Perl itself.
132
133=cut