finished extended type examples
[gitmo/MooseX-Dependent.git] / lib / MooseX / Dependent / Types.pm
index 6053dfb..cec413e 100644 (file)
@@ -1,14 +1,9 @@
 package MooseX::Dependent::Types;
 
-use 5.008;
-
 use Moose::Util::TypeConstraints;
-use MooseX::Dependent::Meta::TypeConstraint::Parameterizable;
+use MooseX::Dependent::Meta::TypeConstraint::Dependent;
 use MooseX::Types -declare => [qw(Dependent)];
 
-our $VERSION = '0.01';
-our $AUTHORITY = 'cpan:JJNAPIORK';
-
 =head1 NAME
 
 MooseX::Dependent::Types - L<MooseX::Types> constraints that depend on values.
@@ -25,7 +20,7 @@ Within your L<MooseX::Types> declared library module:
             my ($int, $set) = @_;
             return $set->find($int) ? 0:1;
         };
-
+               
 =head1 DESCRIPTION
 
 A L<MooseX::Types> library for creating dependent types.  A dependent type
@@ -49,25 +44,48 @@ for a integer, such as in:
                where {
                        my ($value, $range) = @_;
                        return ($value >= $range->{min} &&
-                        $value =< $range->{max});
+                        $value <= $range->{max});
                };
                
-       RangedInt[{min=>10,max=>100}]->check(50); ## OK
-       RangedInt[{min=>50, max=>75}]->check(99); ## Not OK, 99 exceeds max
-       RangedInt[{min=>99, max=>10}]->check(10); ## Not OK, not a valid Range!
+       RangedInt([{min=>10,max=>100}])->check(50); ## OK
+       RangedInt([{min=>50, max=>75}])->check(99); ## Not OK, 99 exceeds max
+       
+This throws a hard Moose exception.  You'll need to capture it in an eval or
+related exception catching system (see L<Try::Catch>).
+
+       RangedInt([{min=>99, max=>10}])->check(10); ## Not OK, not a valid Range!
+
+If you can't accept a hard exception here, you'll need to test the constraining
+values first, as in:
+
+       my $range = {min=>99, max=>10};
+       if(my $err = Range->validate($range)) {
+               ## Handle #$err
+       } else {
+               RangedInt($range)->check(99);
+       }
        
 Please note that for ArrayRef or HashRef dependent type constraints, as in the
 example above, as a convenience we automatically ref the incoming type
 parameters, so that the above could also be written as:
 
-       RangedInt[min=>10,max=>100]->check(50); ## OK
-       RangedInt[min=>50, max=>75]->check(99); ## Not OK, 99 exceeds max
-       RangedInt[min=>99, max=>10]->check(10); ## Not OK, not a valid Range!
+       RangedInt([min=>10,max=>100])->check(50); ## OK
+       RangedInt([min=>50, max=>75])->check(99); ## Not OK, 99 exceeds max
+       RangedInt([min=>99, max=>10])->check(10); ## Exception, not a valid Range!
 
 This is the preferred syntax, as it improve readability and adds to the
 conciseness of your type constraint declarations.  An exception wil be thrown if
 your type parameters don't match the required reference type.
 
+Also not that if you 'chain' parameterization results with a method call like:
+
+       TypeConstraint([$ob])->method;
+       
+You need to have the "(...)" around the ArrayRef in the Type Constraint
+parameters.  This seems to have something to do with the precendent level of
+"->".  Patches or thoughts welcomed.  You only need to do this in the above
+case which I imagine is not a very common case.
+
 ==head2 Subtyping a Dependent type constraints
 
 When subclassing a dependent type you must be careful to match either the
@@ -96,19 +114,20 @@ Or you could have done the following instead (example of re-paramterizing)
        subtype PositiveInt,
                as Int,
                where {
-                       shift >= 0;
+                       my ($value, $range) = @_;
+                       return $value >= 0;
                };
 
        ## subtype Range to re-parameterize Range with subtypes
-       subtype PositveRange,
+       subtype PositiveRange,
                as Range[max=>PositiveInt, min=>PositiveInt];
        
        ## create subtype via reparameterizing
        subtype PositiveRangedInt,
-               as RangedInt[PositveRange];
+               as RangedInt[PositiveRange];
 
 Notice how re-parameterizing the dependent type 'RangedInt' works slightly
-differently from re-parameterizing 'PositiveRange'?  Although it initially takes
+differently from re-parameterizing 'PositiveRange'  Although it initially takes
 two type constraint values to declare a dependent type, should you wish to
 later re-parameterize it, you only use a subtype of the second type parameter
 (the dependent type constraint) since the first type constraint sets the parent
@@ -133,6 +152,9 @@ is a capacity we current don't have.
        
 =head2 Coercions
 
+You can place coercions on dependent types, however you need to pay attention to
+what you are actually coercion, the unparameterized or parameterized constraint.
+
     TBD: Need discussion and example of coercions working for both the
     constrainted and dependent type constraint.
        
@@ -145,8 +167,11 @@ is a capacity we current don't have.
 
 Which should work like:
 
-       OlderThanAge[{older_than=>25}]->check(39);  ## is OK
-               
+       OlderThanAge([{older_than=>25}])->check(39); ## is OK
+       OlderThanAge([older_than=>1])->check(9); ## OK, using reference type inference
+
+And you can create coercions like:
+
        coerce OlderThanAge,
                from Tuple[Int, Int],
                via {
@@ -194,13 +219,10 @@ will cause an exception.
 =cut
 
 Moose::Util::TypeConstraints::get_type_constraint_registry->add_type_constraint(
-    MooseX::Dependent::Meta::TypeConstraint::Parameterizable->new(
+    MooseX::Dependent::Meta::TypeConstraint::Dependent->new(
         name => 'MooseX::Dependent::Types::Dependent',
-        parent => find_type_constraint('ArrayRef'),
-        constraint_generator=> sub { 
-                       my ($dependent_val, $callback, $constraining_val) = @_;
-                       return $callback->($dependent_val, $constraining_val);
-        },
+        parent => find_type_constraint('Any'),
+               constraint => sub {1},
     )
 );