also test adding strictness in a subclass -- and fix mutable case (thanks doy!) :)
[gitmo/MooseX-StrictConstructor.git] / lib / MooseX / StrictConstructor / Trait / Class.pm
1 package MooseX::StrictConstructor::Trait::Class;
2
3 # applied as class_metaroles => { class => [ __PACKAGE__ ] }, for Moose 1.99x and later
4
5 use Moose::Role;
6
7 use namespace::autoclean;
8
9 use B ();
10
11 around '_inline_BUILDALL' => sub {
12     my $orig = shift;
13     my $self = shift;
14
15     my @source = $self->$orig();
16
17     my @attrs = (
18         '__INSTANCE__ => 1,',
19         map { B::perlstring($_) . ' => 1,' }
20         grep {defined}
21         map  { $_->init_arg() } $self->get_all_attributes()
22     );
23
24     return (
25         @source,
26         'my %attrs = (' . ( join ' ', @attrs ) . ');',
27         'my @bad = sort grep { !$attrs{$_} } keys %{ $params };',
28         'if (@bad) {',
29             'Moose->throw_error("Found unknown attribute(s) passed to the constructor: @bad");',
30         '}',
31     );
32 };
33
34 # if the Object role is applied first, and then a superclass added, we just
35 # lost our BUILDALL modification.
36 after superclasses => sub
37 {
38     my $self = shift;
39     return if not @_;
40     Moose::Util::MetaRole::apply_base_class_roles(
41         for => $self->name,
42         roles => ['MooseX::StrictConstructor::Role::Object'],
43     )
44 };
45
46 1;
47
48 # ABSTRACT: A role to make immutable constructors strict
49
50 __END__
51
52 =pod
53
54 =head1 DESCRIPTION
55
56 This role simply wraps C<_inline_BUILDALL()> (from
57 C<Moose::Meta::Class>) so that immutable classes have a
58 strict constructor.
59
60 =cut