bump version to 0.09
[gitmo/MooseX-UndefTolerant.git] / lib / MooseX / UndefTolerant.pm
index e8662fd..f666558 100644 (file)
@@ -4,11 +4,22 @@ use Moose qw();
 use Moose::Exporter;
 
 use MooseX::UndefTolerant::Attribute;
+use MooseX::UndefTolerant::Class;
+use MooseX::UndefTolerant::Constructor;
+
+our $VERSION = '0.09';
+
+my %metaroles = ( attribute => [ 'MooseX::UndefTolerant::Attribute' ] );
+if ( $Moose::VERSION < 1.9900 ) {
+        $metaroles{constructor} = [ 'MooseX::UndefTolerant::Constructor' ];
+}
+else {
+        $metaroles{class} = [ 'MooseX::UndefTolerant::Class' ];
+}
 
-our $VERSION = '0.01';
 
 Moose::Exporter->setup_import_methods(
-    attribute_metaclass_roles => [ 'MooseX::UndefTolerant::Attribute' ]
+    class_metaroles => \%metaroles,
 );
 
 1;
@@ -17,12 +28,91 @@ __END__
 
 =head1 NAME
 
-MooseX::Attribute::UndefTolerant - The great new MooseX::Attribute::UndefTolerant!
+MooseX::UndefTolerant - Make your attribute(s) tolerant to undef initialization
 
 =head1 SYNOPSIS
 
-    use MooseX::Attribute::UndefTolerant;
+  package My::Class;
+
+  use Moose;
+  use MooseX::UndefTolerant;
+
+  has 'name' => (
+    is => 'ro',
+    isa => 'Str',
+    predicate => 'has_name'
+  );
+
+  # Meanwhile, under the city...
+
+  # Doesn't explode
+  my $class = My::Class->new(name => undef);
+  $class->has_name # False!
+
+Or, if you only want one attribute to have this behaviour:
+
+  package My:Class;
+  use Moose;
+
+  use MooseX::UndefTolerant::Attribute;
+
+  has 'bar' => (
+      traits => [ qw(MooseX::UndefTolerant::Attribute)],
+      is => 'ro',
+      isa => 'Num',
+      predicate => 'has_bar'
+  );
+
+=head1 DESCRIPTION
+
+Loading this module in your L<Moose> class makes initialization of your
+attributes tolerant of undef.  If you specify the value of undef to any of
+the attributes they will not be initialized, effectively behaving as if you
+had not provided a value at all.
+
+=head1 MOTIVATION
+
+I often found myself in this quandry:
 
+  package My:Class;
+  use Moose;
+
+  has 'foo' => (
+    is => 'ro',
+    isa => 'Str',
+  );
+
+  # ... then
+
+  my $foo = ... # get the param from something
+
+  my $class = My:Class->new(foo => $foo, bar => 123);
+
+What if foo is undefined?  I didn't want to change my attribute to be
+Maybe[Str] and I still want my predicate (C<has_foo>) to work.  The only
+real solution was:
+
+  if(defined($foo)) {
+    $class = My:Class->new(foo => $foo, bar => 123);
+  } else {
+    $class = My:Class->new(bar => 123);
+  }
+
+Or some type of codemulch using ternarys.  This module allows you to make
+your attributes more tolerant of undef so that you can keep the first
+example: have your cake and eat it too!
+
+=head1 PER ATTRIBUTE
+
+See L<MooseX::UndefTolerant::Attribute>.
+
+=head1 CAVEATS
+
+This extension does not currently work in immutable classes when applying the
+trait to some (but not all) attributes in the class. This is because the
+inlined constructor initialization code currently lives in
+L<Moose::Meta::Method::Constructor>, not L<Moose::Meta::Attribute>. The good
+news is that this is expected to be changing shortly.
 
 =head1 AUTHOR
 
@@ -30,6 +120,8 @@ Cory G Watson, C<< <gphat at cpan.org> >>
 
 =head1 ACKNOWLEDGEMENTS
 
+Many thanks to the crew in #moose who talked me through this module:
+
 Hans Dieter Pearcey (confound)
 
 Jesse Luehrs (doy)
@@ -52,5 +144,4 @@ by the Free Software Foundation; or the Artistic License.
 
 See http://dev.perl.org/licenses/ for more information.
 
-
 =cut