From: john napiorkowski Date: Wed, 27 May 2009 15:42:07 +0000 (-0400) Subject: more docs and clarifications X-Git-Tag: 0.01~7 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=88f58fbff42a62f89cac9407546e9e45e3288bac;p=gitmo%2FMooseX-Dependent.git more docs and clarifications --- diff --git a/lib/MooseX/Dependent.pm b/lib/MooseX/Dependent.pm index 18f6e52..0803815 100644 --- a/lib/MooseX/Dependent.pm +++ b/lib/MooseX/Dependent.pm @@ -20,53 +20,52 @@ Given some L 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). 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. Please see diff --git a/lib/MooseX/Dependent/Types.pm b/lib/MooseX/Dependent/Types.pm index c08f822..b23e750 100644 --- a/lib/MooseX/Dependent/Types.pm +++ b/lib/MooseX/Dependent/Types.pm @@ -13,14 +13,41 @@ MooseX::Dependent::Types - L constraints that depend on values. Within your L 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 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,