more docs and clarifications
john napiorkowski [Wed, 27 May 2009 15:42:07 +0000 (11:42 -0400)]
lib/MooseX/Dependent.pm
lib/MooseX/Dependent/Types.pm

index 18f6e52..0803815 100644 (file)
@@ -20,53 +20,52 @@ Given some L<MooseX::Types> declared as:
     
     use MooseX::Types::Moose qw(Object, Int);
     use MooseX::Dependent::Types qw(Dependent);
-    use Moosex::Types -declare => [qw(Set UniqueID)];
+    use Moosex::Types -declare => [qw(Set UniqueInt)];
+    
+    use Set::Scalar;
 
        subtype Set,
-               as Object,
-               where {
-                   shift->can('find');
-               };
+               as class_type("Set::Scalar");
 
-       subtype UniqueID,
+       subtype UniqueInt,
                as Dependent[Int, Set],
                where {
                    my ($int, $set) = @_;
-                   return $set->find($int) ? 0:1;
+                   return !$set->has($int) ;
                };
 
 Assuming 'Set' is a class that creates and manages sets of values (lists of
-unique but unordered values) with a method '->find($n)', which returns true when
+unique but unordered values) with a method '->has($n)', which returns true when
 $n is a member of the set and which you instantiate like so:
 
     my $set_obj = Set->new(1,2,3,4,5); ## 1..5 are member of Set $set_obj'
 
 You can then use this $set_obj as a parameter on the previously declared type
-constraint 'UniqueID'.  This $set_obj become part of the constraint (you can't
+constraint 'UniqueInt'.  This $set_obj become part of the constraint (you can't
 actually use the constraint without it.)
 
-    UniqueID([$set_obj])->check(1); ## Not OK, since one isn't unique in $set_obj
-    UniqueID([$set_obj])->check('AAA'); ## Not OK, since AAA is not an Int
-    UniqueID([$set_obj])->check(100); ## OK, since 100 isn't in the set.
+    UniqueInt([$set_obj])->check(1); ## Not OK, since one isn't unique in $set_obj
+    UniqueInt([$set_obj])->check('AAA'); ## Not OK, since AAA is not an Int
+    UniqueInt([$set_obj])->check(100); ## OK, since 100 isn't in the set.
     
 You can assign the result of a parameterized dependent type to a variable or to
 another type constraint, as like any other type constraint:
 
     ## As variable
-    my $unique = UniqueID[$set_obj];
+    my $unique = UniqueInt[$set_obj];
     $unique->check(10); ## OK
     $unique->check(2); ## Not OK, '2' is already in the set.
     
     ## As a new subtype
-    subtype UniqueInSet, as UniqueID[$set_obj];
+    subtype UniqueInSet, as UniqueInt[$set_obj];
     UniqueInSet->check(99); ## OK
     UniqueInSet->check(3); ## Not OK, '3' is already in the set.
     
 However, you can't use a dependent type constraint to check or validate a value
 until you've parameterized the dependent value:
 
-    UniqueID->check(1000); ## Throws exception
-    UniqueID->validate(1000); ## Throws exception also
+    UniqueInt->check(1000); ## Throws exception
+    UniqueInt->validate(1000); ## Throws exception also
     
 This is a hard exception, rather than just returning a failure message (via the
 validate method) or a false boolean (via the check method) since I consider an
@@ -83,10 +82,10 @@ and set the dependency target to the value of another attribute or method:
     use Moose;
     use MooseX::Dependent (or maybe a role, or traits...?)
     use MooseX::Types::Moose qw();
-    use MyApp::Types qw(UniqueID Set);
+    use MyApp::Types qw(UniqueInt Set);
     
     has people => (is=>'ro', isa=>Set, required=>1);
-    has id => (is=>'ro', dependent_isa=>UniqueID, required=>1);
+    has id => (is=>'ro', dependent_isa=>UniqueInt, required=>1);
     
     TODO notes, coerce=>1 should coerce both check value and constraining value
 
@@ -106,6 +105,11 @@ attributes and methods (if you are using L<MooseX::Declare>).  Attribute traits
 are available to make it easy to assign the dependency to the value of another
 attribute or another method.
 
+A Dependent Type Constraint should be a 'drop in' replacement for any place you
+need the parent type (the type constraint being made dependent).  For example,
+if you are expecting an 'Int' type, you can use the 'UniqueInt' type constraint
+as described above, since a UniqueInt is considered a subtype of Int.
+
 =head1 TYPE CONSTRAINTS
 
 All type constraints are defined in L<MooseX::Dependent::Types>.  Please see
index c08f822..b23e750 100644 (file)
@@ -13,14 +13,41 @@ MooseX::Dependent::Types - L<MooseX::Types> constraints that depend on values.
 Within your L<MooseX::Types> declared library module:
 
     use MooseX::Dependent::Types qw(Dependent);
+       
+       subtype Set,
+               as class_type("Set::Scalar");
 
-    subtype UniqueID,
+    subtype UniqueInt,
         as Dependent[Int, Set],
         where {
             my ($int, $set) = @_;
-            return $set->find($int) ? 0:1;
+            return !$set->has($int);
         };
                
+       subtype PositiveSet,
+               as Set,
+               where {
+                       my ($set) = @_;
+                       return !grep {$_ <0 } $set->members;
+               };
+               
+    subtype PositiveUniqueInt,
+        as UniqueInt[PositiveSet];
+       
+       my $set = Set::Scalar->new(1,2,3);
+
+       UniqueInt([$set])->check(100);  ## Okay, 100 isn't in (1,2,3)
+       UniqueInt([$set])->check(-99);  ## Okay, -99 isn't in (1,2,3)
+       UniqueInt([$set])->check(2);  ## Not OK, 2 is in (1,2,3)
+       
+       PositiveUniqueInt([$set])->check(100);  ## Okay, 100 isn't in (1,2,3)
+       PositiveUniqueInt([$set])->check(-99);  ## Not OK, -99 not Positive Int
+       PositiveUniqueInt([$set])->check(2);  ## Not OK, 2 is in (1,2,3)
+       
+       my $negative_set = Set::Scalar->new(-1,-2,-3);
+       
+       UniqueInt([$negative_set])->check(100);  ## Throws exception
+               
 =head1 DESCRIPTION
 
 A L<MooseX::Types> library for creating dependent types.  A dependent type
@@ -108,7 +135,7 @@ Example subtype with additional constraints:
                        shift >= 0;                     
                };
                
-Or you could have done the following instead (example of re-paramterizing)
+Or you could have done the following instead:
 
        ## Subtype of Int for positive numbers
        subtype PositiveInt,