A working first version.
Dave Rolsky [Thu, 15 Nov 2007 05:49:20 +0000 (05:49 +0000)]
lib/MooseX/Object/StrictConstructor.pm
lib/MooseX/StrictConstructor.pm
t/basic.t
t/pod-coverage.t

index 394c003..c21a667 100644 (file)
@@ -28,3 +28,30 @@ after 'BUILDALL' => sub
 
 
 1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+MooseX::Object::StrictConstructor - Implements strict constructors as a Moose::Object subclass
+
+=head1 DESCRIPTION
+
+This class has no external interface. When you use
+C<MooseX::StrictConstructor>, your objects will subclass this class
+rather than Moose::Object.
+
+=head1 AUTHOR
+
+Dave Rolsky, C<< <autarch@urth.org> >>
+
+=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
index 3be669a..69d671c 100644 (file)
@@ -32,23 +32,48 @@ __END__
 
 =head1 NAME
 
-MooseX::StrictConstructor - The fantastic new MooseX::StrictConstructor!
+MooseX::StrictConstructor - Make your object constructors blow up on unknown attributes
 
 =head1 SYNOPSIS
 
-XXX - change this!
+    package My::Class;
 
-    use MooseX::StrictConstructor;
+    use MooseX::StrictConstructor; # instead of use Moose
 
-    my $foo = MooseX::StrictConstructor->new();
+    has 'size' => ...;
 
-    ...
+    # then later ...
+
+    # this blows up because color is not a known attribute
+    My::Class->new( size => 5, color => 'blue' );
 
 =head1 DESCRIPTION
 
-=head1 METHODS
+Using this class to load Moose instead of just loading using Moose
+itself makes your constructors "strict". If your constructor is called
+with an attribute that your class does not declare, then it calls
+"Carp::confess()". This is a great way to catch small typos.
+
+=head2 Subverting Strictness
+
+You may find yourself wanting to accept a parameter to the constructor
+that is not the name of an attribute.
+
+In that case, you'll probably be writing a C<BUILD()> method to deal
+with it. Your C<BUILD()> method will receive two parameters, the new
+object, and a hash reference of parameters passed to the constructor.
+
+If you delete keys from this hash reference, then they will not be
+seen when this class does its checking.
+
+  sub BUILD {
+      my $self   = shift;
+      my $params = shift;
 
-This class provides the following methods
+      if ( delete $params->{do_something} ) {
+          ...
+      }
+  }
 
 =head1 AUTHOR
 
@@ -56,10 +81,11 @@ 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.
+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
 
index d91d3c9..d06235f 100644 (file)
--- a/t/basic.t
+++ b/t/basic.t
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 4;
+use Test::More tests => 6;
 
 
 {
@@ -21,6 +21,16 @@ use Test::More tests => 4;
 }
 
 {
+    package Subclass;
+
+    use MooseX::StrictConstructor;
+
+    extends 'Stricter';
+
+    has 'size' => ( is => 'rw' );
+}
+
+{
     package Tricky;
 
     use MooseX::StrictConstructor;
@@ -48,3 +58,9 @@ 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' );
+
+eval { Subclass->new( thing => 1, bad => 99 ) };
+like( $@, qr/unknown attribute.+: bad/, 'subclass constructor blows up on unknown params' );
+
+eval { Subclass->new( thing => 1, size => 'large' ) };
+is( $@, '', 'subclass constructor handles known attributes correctly' );
index aa1f35b..12bfc77 100644 (file)
@@ -11,4 +11,6 @@ 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();
+all_pod_coverage_ok( { coverage_class => 'Pod::Coverage::Moose',
+                       trustme        => [ qr/BUILDALL/ ],
+                     } );