Commit | Line | Data |
1a4f7732 |
1 | package MooseX::StrictConstructor::Trait::Class; |
c001451a |
2 | |
d99e6f32 |
3 | use Moose::Role; |
4 | |
5 | use namespace::autoclean; |
c001451a |
6 | |
79b37c7d |
7 | use B (); |
c001451a |
8 | |
4e914932 |
9 | my %pkg_attrs; |
10 | |
709eccb9 |
11 | around new_object => sub { |
eb63f59e |
12 | my $orig = shift; |
13 | my $self = shift; |
14 | my $params = @_ == 1 ? $_[0] : {@_}; |
709eccb9 |
15 | my $instance = $self->$orig(@_); |
16 | |
4e914932 |
17 | my $attrs = |
18 | $pkg_attrs{ref($instance)} ||= { |
19 | __INSTANCE__ => 1, |
20 | map { $_ => 1 } |
21 | grep {defined} |
22 | map { $_->init_arg() } $self->get_all_attributes() |
23 | }; |
709eccb9 |
24 | |
4e914932 |
25 | if (my @bad = sort grep { !$attrs->{$_} } keys %$params) { |
709eccb9 |
26 | $self->throw_error( |
eb63f59e |
27 | "Found unknown attribute(s) init_arg passed to the constructor: @bad" |
28 | ); |
709eccb9 |
29 | } |
30 | |
31 | return $instance; |
32 | }; |
33 | |
01265e2a |
34 | around '_inline_BUILDALL' => sub { |
64c958ef |
35 | my $orig = shift; |
c001451a |
36 | my $self = shift; |
37 | |
01265e2a |
38 | my @source = $self->$orig(); |
c001451a |
39 | |
5a0d4921 |
40 | my @attrs = ( |
df9653e6 |
41 | '__INSTANCE__ => 1,', |
79b37c7d |
42 | map { B::perlstring($_) . ' => 1,' } |
5a0d4921 |
43 | grep {defined} |
01265e2a |
44 | map { $_->init_arg() } $self->get_all_attributes() |
5a0d4921 |
45 | ); |
c001451a |
46 | |
4e914932 |
47 | my $MY = 'my'; |
48 | if ($] >= 5.009004) { |
49 | push @source, "use feature 'state';"; |
50 | $MY = 'state'; |
51 | } |
52 | |
01265e2a |
53 | return ( |
54 | @source, |
4e914932 |
55 | $MY.' $attrs = {' . ( join ' ', @attrs ) . '};', |
56 | 'if (my @bad = sort grep { !$attrs->{$_} } keys %$params) {', |
714128ef |
57 | 'Moose->throw_error("Found unknown attribute(s) passed to the constructor: @bad");', |
01265e2a |
58 | '}', |
59 | ); |
0dc0aea2 |
60 | } if $Moose::VERSION >= 1.9900; |
c001451a |
61 | |
c001451a |
62 | 1; |
58370717 |
63 | |
0639c294 |
64 | # ABSTRACT: A role to make immutable constructors strict |
65 | |
58370717 |
66 | __END__ |
67 | |
68 | =pod |
69 | |
58370717 |
70 | =head1 DESCRIPTION |
71 | |
01265e2a |
72 | This role simply wraps C<_inline_BUILDALL()> (from |
73 | C<Moose::Meta::Class>) so that immutable classes have a |
fbfaa61f |
74 | strict constructor. |
58370717 |
75 | |
58370717 |
76 | =cut |