tabs to spaces
John Napiorkowski [Wed, 23 Jun 2010 23:37:53 +0000 (19:37 -0400)]
lib/MooseX/Types/Parameterizable.pm

index 1f257da..c28a086 100644 (file)
@@ -18,9 +18,9 @@ MooseX::Types::Parameterizable - Create your own Parameterizable Types.
 Within your L<MooseX::Types> declared library module:
 
     use MooseX::Types::Parameterizable qw(Parameterizable);
-       
-       subtype Set,
-               as class_type("Set::Scalar");
+    
+    subtype Set,
+       as class_type("Set::Scalar");
 
     subtype UniqueInt,
         as Parameterizable[Int, Set],
@@ -28,31 +28,31 @@ Within your L<MooseX::Types> declared library module:
             my ($int, $set) = @_;
             return !$set->has($int);
         };
-               
-       subtype PositiveSet,
-               as Set,
-               where {
-                       my ($set) = @_;
-                       return !grep {$_ <0 } $set->members;
-               };
-               
+       
+    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
-               
+    
+    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 parameterizable types.  A parameterizable type
@@ -64,46 +64,46 @@ This allows you to create a type that has additional runtime advice, such as a
 set of numbers within which another number must be unique, or allowable ranges
 for a integer, such as in:
 
-       subtype Range,
-               as Dict[max=>Int, min=>Int],
-               where {
-                       my ($range) = @_;
-                       return $range->{max} > $range->{min};
-               };
-
-       subtype RangedInt,
-               as Parameterizable[Int, Range],
-               where {
-                       my ($value, $range) = @_;
-                       return ($value >= $range->{min} &&
-                        $value <= $range->{max});
-               };
-               
-       RangedInt([{min=>10,max=>100}])->check(50); ## OK
-       RangedInt([{min=>50, max=>75}])->check(99); ## Not OK, 99 exceeds max
-       
+    subtype Range,
+       as Dict[max=>Int, min=>Int],
+       where {
+               my ($range) = @_;
+               return $range->{max} > $range->{min};
+       };
+
+    subtype RangedInt,
+       as Parameterizable[Int, Range],
+       where {
+               my ($value, $range) = @_;
+               return ($value >= $range->{min} &&
+                $value <= $range->{max});
+       };
+       
+    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<TryCatch>).
+related exception catching system (see L<TryCatch> or <Try::Tiny>.)
 
-       RangedInt([{min=>99, max=>10}])->check(10); ## Not OK, not a valid Range!
+    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);
-       }
-       
+    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 parameterizable 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); ## Exception, 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
@@ -111,8 +111,8 @@ 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;
-       
+    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
@@ -124,39 +124,39 @@ When subclassing a parameterizable type you must be careful to match either the
 required type parameter type constraint, or if re-parameterizing, the new
 type constraints are a subtype of the parent.  For example:
 
-       subtype RangedInt,
-               as Parameterizable[Int, Range],
-               where {
-                       my ($value, $range) = @_;
-                       return ($value >= $range->{min} &&
-                        $value =< $range->{max});
-               };
+    subtype RangedInt,
+       as Parameterizable[Int, Range],
+       where {
+               my ($value, $range) = @_;
+               return ($value >= $range->{min} &&
+                $value =< $range->{max});
+       };
 
 Example subtype with additional constraints:
 
-       subtype PositiveRangedInt,
-               as RangedInt,
-               where {
-                       shift >= 0;                     
-               };
-               
+    subtype PositiveRangedInt,
+       as RangedInt,
+       where {
+               shift >= 0;                     
+       };
+       
 Or you could have done the following instead:
 
-       ## Subtype of Int for positive numbers
-       subtype PositiveInt,
-               as Int,
-               where {
-                       my ($value, $range) = @_;
-                       return $value >= 0;
-               };
-
-       ## subtype Range to re-parameterize Range with subtypes
-       subtype PositiveRange,
-               as Range[max=>PositiveInt, min=>PositiveInt];
-       
-       ## create subtype via reparameterizing
-       subtype PositiveRangedInt,
-               as RangedInt[PositiveRange];
+    ## Subtype of Int for positive numbers
+    subtype PositiveInt,
+       as Int,
+       where {
+               my ($value, $range) = @_;
+               return $value >= 0;
+       };
+
+    ## subtype Range to re-parameterize Range with subtypes
+    subtype PositiveRange,
+       as Range[max=>PositiveInt, min=>PositiveInt];
+    
+    ## create subtype via reparameterizing
+    subtype PositiveRangedInt,
+       as RangedInt[PositiveRange];
 
 Notice how re-parameterizing the parameterizable type 'RangedInt' works slightly
 differently from re-parameterizing 'PositiveRange'  Although it initially takes
@@ -167,21 +167,21 @@ type for the parameterizable type.  In other words, given the example above, a t
 constraint of 'RangedInt' would have a parent of 'Int', not 'Parameterizable' and for
 all intends and uses you could stick it wherever you'd need an Int.
 
-       subtype NameAge,
-               as Tuple[Str, Int];
-       
-       ## re-parameterized subtypes of NameAge containing a Parameterizable Int        
-       subtype NameBetween18and35Age,
-               as NameAge[
-                       Str,
-                       PositiveRangedInt[min=>18,max=>35],
-               ];
+    subtype NameAge,
+       as Tuple[Str, Int];
+    
+    ## re-parameterized subtypes of NameAge containing a Parameterizable Int   
+    subtype NameBetween18and35Age,
+       as NameAge[
+               Str,
+               PositiveRangedInt[min=>18,max=>35],
+       ];
 
 One caveat is that you can't stick an unparameterized parameterizable type inside a
 structure, such as L<MooseX::Types::Structured> since that would require the
 ability to convert a 'containing' type constraint into a parameterizable type, which
 is a capacity we current don't have.
-       
+    
 =head2 Coercions
 
 Parameterizable types have some limited support for coercions.  Several things must
@@ -189,41 +189,41 @@ be kept in mind.  The first is that the coercion targets the type constraint
 which is being made parameterizable, Not the parameterizable type.  So for example if you
 create a Parameterizable type like:
 
-       subtype RequiredAgeInYears,
-         as Int;
+    subtype RequiredAgeInYears,
+      as Int;
 
-       subtype PersonOverAge,
-         as Parameterizable[Person, RequiredAgeInYears]
-         where {
-               my ($person, $required_years_old) = @_;
-               return $person->years_old > $required_years_old;
-         }
+    subtype PersonOverAge,
+      as Parameterizable[Person, RequiredAgeInYears]
+      where {
+       my ($person, $required_years_old) = @_;
+       return $person->years_old > $required_years_old;
+      }
 
 This would validate the following:
-       
-       my $person = Person->new(age=>35);
-       PersonOverAge([18])->check($person);
-       
+    
+    my $person = Person->new(age=>35);
+    PersonOverAge([18])->check($person);
+    
 You can then apply the following coercion
 
-       coerce PersonOverAge,
-         from Dict[age=>int],
-         via {Person->new(%$_)},
-         from Int,
-         via {Person->new(age=>$_)};
-         
+    coerce PersonOverAge,
+      from Dict[age=>int],
+      via {Person->new(%$_)},
+      from Int,
+      via {Person->new(age=>$_)};
+      
 This coercion would then apply to all the following:
 
-       PersonOverAge([18])->check(30); ## via the Int coercion
-       PersonOverAge([18])->check({age=>50}); ## via the Dict coercion
+    PersonOverAge([18])->check(30); ## via the Int coercion
+    PersonOverAge([18])->check({age=>50}); ## via the Dict coercion
 
 However, you are not allowed to place coercions on parameterizable types that have
 had their constraining value filled, nor subtypes of such.  For example:
 
-       coerce PersonOverAge[18],
-         from DateTime,
-         via {$_->years};
-         
+    coerce PersonOverAge[18],
+      from DateTime,
+      via {$_->years};
+      
 That would generate a hard exception.  This is a limitation for now until I can
 devise a smarter way to cache the generated type constraints.  However, I doubt
 it will be a significant limitation, since the general use case is supported.
@@ -231,24 +231,24 @@ it will be a significant limitation, since the general use case is supported.
 Lastly, the constraining value is available in the coercion in much the same way
 it is available to the constraint.
 
-       ## Create a type constraint where a Person must be in the set
-       subtype PersonInSet,
-               as Parameterizable[Person, PersonSet],
-               where {
-                       my ($person, $person_set) = @_;
-                       $person_set->find($person);
-               }
-
-       coerce PersonInSet,
-               from HashRef,
-               via {
-                       my ($hashref, $person_set) = @_;
-                       return $person_set->create($hash_ref);
-               };
+    ## Create a type constraint where a Person must be in the set
+    subtype PersonInSet,
+       as Parameterizable[Person, PersonSet],
+       where {
+               my ($person, $person_set) = @_;
+               $person_set->find($person);
+       }
+
+    coerce PersonInSet,
+       from HashRef,
+       via {
+               my ($hashref, $person_set) = @_;
+               return $person_set->create($hash_ref);
+       };
 
 =head2 Recursion
 
-       TBD
+    TBD
 
 =head1 TYPE CONSTRAINTS
 
@@ -270,7 +270,7 @@ Moose::Util::TypeConstraints::get_type_constraint_registry->add_type_constraint(
     MooseX::Meta::TypeConstraint::Parameterizable->new(
         name => 'MooseX::Types::Parameterizable::Parameterizable',
         parent => find_type_constraint('Any'),
-               constraint => sub {1},
+       constraint => sub {1},
     )
 );