{
my %class_meta;
+ my %role_meta;
if ( $Moose::VERSION < 1.9900 ) {
require MooseX::StrictConstructor::Trait::Method::Constructor;
require MooseX::StrictConstructor::Trait::Class;
%class_meta
= ( class => ['MooseX::StrictConstructor::Trait::Class'] );
+ %role_meta
+ = (
+ role => ['MooseX::StrictConstructor::Trait::Role'],
+ application_to_class => ['MooseX::StrictConstructor::Trait::ApplicationToClass'],
+ application_to_role =>['MooseX::StrictConstructor::Trait::ApplicationToRole'],
+ );
}
Moose::Exporter->setup_import_methods(
class_metaroles => \%class_meta,
+ role_metaroles => \%role_meta,
base_class_roles => ['MooseX::StrictConstructor::Role::Object'],
);
}
does not declare, then it calls C<Moose->throw_error()>. This is a great way
to catch small typos.
+As of Moose 1.9900, this module can also be used in a role, in which case the
+constructor of the consuming class will become strict.
+
+
=head2 Subverting Strictness
You may find yourself wanting to have your constructor accept a
--- /dev/null
+package MooseX::StrictConstructor::Trait::ApplicationToClass;
+use Moose::Role;
+
+around apply => sub {
+ my $orig = shift;
+ my $self = shift;
+ my ($role, $class) = @_;
+
+ Moose::Util::MetaRole::apply_base_class_roles(
+ for => $class,
+ roles => ['MooseX::StrictConstructor::Role::Object'],
+ );
+
+ $class = Moose::Util::MetaRole::apply_metaroles(
+ for => $class,
+ class_metaroles => {
+ class => [ 'MooseX::StrictConstructor::Trait::Class' ],
+ }
+ );
+
+ $self->$orig( $role, $class );
+};
+
+no Moose::Role;
+
+1;
--- /dev/null
+package MooseX::StrictConstructor::Trait::ApplicationToRole;
+use Moose::Role;
+
+around apply => sub {
+ my $orig = shift;
+ my $self = shift;
+ my ($role1, $role2) = @_;
+
+ $role2 = Moose::Util::MetaRole::apply_metaroles(
+ for => $role2,
+ role_metaroles => {
+ application_to_class => [
+ 'MooseX::StrictConstructor::Trait::ApplicationToClass',
+ ],
+ application_to_role => [
+ 'MooseX::StrictConstructor::Trait::ApplicationToRole',
+ ],
+ }
+ );
+
+ $self->$orig( $role1, $role2 );
+};
+
+no Moose::Role;
+
+1;
--- /dev/null
+package MooseX::StrictConstructor::Trait::Composite;
+use Moose::Role;
+
+around apply_params => sub {
+ my $orig = shift;
+ my $self = shift;
+
+ $self->$orig(@_);
+
+ $self = Moose::Util::MetaRole::apply_metaroles(
+ for => $self,
+ role_metaroles => {
+ application_to_class =>
+ ['MooseX::StrictConstructor::Trait::ApplicationToClass'],
+ application_to_role =>
+ ['MooseX::StrictConstructor::Trait::ApplicationToRole'],
+ },
+ );
+
+ return $self;
+};
+
+no Moose::Role;
+
+1;
--- /dev/null
+package MooseX::StrictConstructor::Trait::Role;
+
+use Moose::Role;
+
+sub composition_class_roles { 'MooseX::StrictConstructor::Trait::Composite' }
+
+no Moose::Role;
+
+1;
--- /dev/null
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Fatal;
+use Test::Moose qw( with_immutable );
+
+{
+ package Role;
+
+ use Moose::Role;
+ use MooseX::StrictConstructor;
+
+ has 'size' => ( is => 'rw' );
+}
+
+{
+ package Standard;
+
+ use Moose;
+ with 'Role';
+
+ has 'thing' => ( is => 'rw' );
+}
+
+my @classes = qw( Standard );
+with_immutable {
+
+ like(
+ exception { Standard->new( thing => 1, bad => 99 ) },
+ qr/unknown attribute.+: bad/,
+ 'strict constructor applied from role blows up on unknown params'
+ );
+}
+@classes;
+
+done_testing();