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
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
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
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
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,