--- /dev/null
+use strict;
+use warnings;
+
+use Module::Build;
+
+my $builder = Module::Build->new
+ ( module_name => 'MooseX::StrictConstructor',
+ license => 'perl',
+ requires => { 'Test::More' => 0,
+ },
+ create_makefile_pl => 'passthrough',
+ create_readme => 1,
+ sign => 1,
+ );
+
+$builder->create_build_script();
--- /dev/null
+0.01 Date/time
+
+* First version, released on an unsuspecting world.
--- /dev/null
+Build.PL
+Changes
+MANIFEST
+MANIFEST.SKIP
+META.yml # Will be created by "make dist"
+README # Will be created by "make dist"
+lib/MooseX/StrictConstructor.pm
+t/perlcritic.t
+t/pod-coverage.t
+t/pod.t
--- /dev/null
+# Avoid version control files.
+\bRCS\b
+\bCVS\b
+,v$
+\B\.svn\b
+
+# Avoid Makemaker generated and utility files.
+\bMakefile$
+\bblib
+\bMakeMaker-\d
+\bpm_to_blib$
+\bblibdirs$
+^MANIFEST\.SKIP$
+
+# Avoid Module::Build generated and utility files.
+\bBuild$
+\b_build
+
+# Avoid temp and backup files.
+~$
+\.old$
+\.bak$
+\#$
+\b\.#
+
+# Avoid tarballs
+\.(?:tar|tgz|tar\.gz)$
--- /dev/null
+package MooseX::Object::StrictConstructor;
+
+use strict;
+use warnings;
+
+use Moose;
+
+use Carp 'confess';
+
+extends 'Moose::Object';
+
+after 'BUILDALL' => sub
+{
+ my $self = shift;
+ my $params = shift;
+
+ my %attrs = map { $_->name() => 1 } $self->meta()->compute_all_applicable_attributes();
+
+ my @bad = grep { ! $attrs{$_} } keys %{ $params };
+
+ if (@bad)
+ {
+ confess "Found unknown attribute(s) passed to the constructor: @bad";
+ }
+
+ return;
+};
+
+
+1;
--- /dev/null
+package MooseX::StrictConstructor;
+
+use strict;
+use warnings;
+
+our $VERSION = '0.01';
+
+use Moose;
+use MooseX::Object::StrictConstructor;
+
+
+sub import
+{
+ my $caller = caller();
+
+ return if $caller eq 'main';
+
+ Moose::init_meta( $caller, 'MooseX::Object::StrictConstructor', 'Moose::Meta::Class' );
+
+ Moose->import( { into => $caller } );
+
+ return;
+}
+
+
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+MooseX::StrictConstructor - The fantastic new MooseX::StrictConstructor!
+
+=head1 SYNOPSIS
+
+XXX - change this!
+
+ use MooseX::StrictConstructor;
+
+ my $foo = MooseX::StrictConstructor->new();
+
+ ...
+
+=head1 DESCRIPTION
+
+=head1 METHODS
+
+This class provides the following methods
+
+=head1 AUTHOR
+
+Dave Rolsky, C<< <autarch@urth.org> >>
+
+=head1 BUGS
+
+Please report any bugs or feature requests to C<bug-moosex-strictconstructor@rt.cpan.org>,
+or through the web interface at L<http://rt.cpan.org>. I will be
+notified, and then you'll automatically be notified of progress on
+your bug as I make changes.
+
+=head1 COPYRIGHT & LICENSE
+
+Copyright 2007 Dave Rolsky, All Rights Reserved.
+
+This program is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
--- /dev/null
+use strict;
+use warnings;
+
+use Test::More tests => 4;
+
+
+{
+ package Standard;
+
+ use Moose;
+
+ has 'thing' => ( is => 'rw' );
+}
+
+{
+ package Stricter;
+
+ use MooseX::StrictConstructor;
+
+ has 'thing' => ( is => 'rw' );
+}
+
+{
+ package Tricky;
+
+ use MooseX::StrictConstructor;
+
+ has 'thing' => ( is => 'rw' );
+
+ sub BUILD
+ {
+ my $self = shift;
+ my $params = shift;
+
+ delete $params->{spy};
+ }
+}
+
+
+eval { Standard->new( thing => 1, bad => 99 ) };
+is( $@, '', 'standard Moose class ignores unknown params' );
+
+eval { Stricter->new( thing => 1, bad => 99 ) };
+like( $@, qr/unknown attribute.+: bad/, 'strict constructor blows up on unknown params' );
+
+eval { Tricky->new( thing => 1, spy => 99 ) };
+is( $@, '', 'can work around strict constructor by deleting params in BUILD()' );
+
+eval { Tricky->new( thing => 1, agent => 99 ) };
+like( $@, qr/unknown attribute.+: agent/, 'Tricky still blows up on unknown params other than spy' );
--- /dev/null
+use strict;
+use warnings;
+
+use Test::More;
+
+
+plan skip_all => 'This test is only run for the module author'
+ unless -d '.svn' || $ENV{IS_MAINTAINER};
+
+eval 'use Test::Perl::Critic ( -severity => 4 )';
+plan skip_all => 'Test::Perl::Critic required for testing POD' if $@;
+
+all_critic_ok();
--- /dev/null
+use strict;
+use warnings;
+
+use Test::More;
+
+
+plan skip_all => 'This test is only run for the module author'
+ unless -d '.svn' || $ENV{IS_MAINTAINER};
+
+eval "use Test::Pod::Coverage 1.04";
+plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage"
+ if $@;
+
+all_pod_coverage_ok();
--- /dev/null
+use strict;
+use warnings;
+
+use Test::More;
+
+
+plan skip_all => 'This test is only run for the module author'
+ unless -d '.svn' || $ENV{IS_MAINTAINER};
+
+eval "use Test::Pod 1.14";
+plan skip_all => "Test::Pod 1.14 required for testing POD" if $@;
+
+all_pod_files_ok();