more pod and clarified license
[gitmo/MooseX-Dependent.git] / lib / MooseX / Dependent.pm
CommitLineData
5964b3ca 1package MooseX::Dependent;
2
3use 5.008;
4
5use strict;
6use warnings;
7
8our $VERSION = '0.01';
9our $AUTHORITY = 'cpan:JJNAPIORK';
10
11=head1 NAME
12
13MooseX::Dependent - Dependent L<MooseX::Types> constraints and L<Moose> attributes
14
15=head1 SYNOPSIS
16
17Given some L<MooseX::Types> declared as:
18
19 package MyApp::Types;
20
21 use MooseX::Types::Moose qw(Object, Int);
22 use MooseX::Dependent::Types qw(Dependent);
88f58fbf 23 use Moosex::Types -declare => [qw(Set UniqueInt)];
24
25 use Set::Scalar;
5964b3ca 26
27 subtype Set,
88f58fbf 28 as class_type("Set::Scalar");
5964b3ca 29
88f58fbf 30 subtype UniqueInt,
5964b3ca 31 as Dependent[Int, Set],
32 where {
613e1e97 33 my ($int, $set) = @_;
88f58fbf 34 return !$set->has($int) ;
5964b3ca 35 };
36
37Assuming 'Set' is a class that creates and manages sets of values (lists of
88f58fbf 38unique but unordered values) with a method '->has($n)', which returns true when
5964b3ca 39$n is a member of the set and which you instantiate like so:
40
613e1e97 41 my $set_obj = Set->new(1,2,3,4,5); ## 1..5 are member of Set $set_obj'
5964b3ca 42
43You can then use this $set_obj as a parameter on the previously declared type
88f58fbf 44constraint 'UniqueInt'. This $set_obj become part of the constraint (you can't
5964b3ca 45actually use the constraint without it.)
46
88f58fbf 47 UniqueInt([$set_obj])->check(1); ## Not OK, since one isn't unique in $set_obj
48 UniqueInt([$set_obj])->check('AAA'); ## Not OK, since AAA is not an Int
49 UniqueInt([$set_obj])->check(100); ## OK, since 100 isn't in the set.
613e1e97 50
51You can assign the result of a parameterized dependent type to a variable or to
52another type constraint, as like any other type constraint:
53
54 ## As variable
88f58fbf 55 my $unique = UniqueInt[$set_obj];
613e1e97 56 $unique->check(10); ## OK
57 $unique->check(2); ## Not OK, '2' is already in the set.
58
59 ## As a new subtype
88f58fbf 60 subtype UniqueInSet, as UniqueInt[$set_obj];
613e1e97 61 UniqueInSet->check(99); ## OK
62 UniqueInSet->check(3); ## Not OK, '3' is already in the set.
63
64However, you can't use a dependent type constraint to check or validate a value
65until you've parameterized the dependent value:
66
88f58fbf 67 UniqueInt->check(1000); ## Throws exception
68 UniqueInt->validate(1000); ## Throws exception also
613e1e97 69
70This is a hard exception, rather than just returning a failure message (via the
71validate method) or a false boolean (via the check method) since I consider an
72unparameterized type constraint to be more than just an invalid condition. You
73will have to catch these in an eval if you think you might have them.
5964b3ca 74
613e1e97 75Afterward, you can use these dependent types on your L<Moose> based classes
5964b3ca 76and set the dependency target to the value of another attribute or method:
77
78 TDB: Following is tentative
79
80 package MyApp::MyClass;
81
82 use Moose;
83 use MooseX::Dependent (or maybe a role, or traits...?)
84 use MooseX::Types::Moose qw();
88f58fbf 85 use MyApp::Types qw(UniqueInt Set);
5964b3ca 86
87 has people => (is=>'ro', isa=>Set, required=>1);
88f58fbf 88 has id => (is=>'ro', dependent_isa=>UniqueInt, required=>1);
9c319add 89
90 TODO notes, coerce=>1 should coerce both check value and constraining value
5964b3ca 91
92Please see the test cases for more examples.
93
94=head1 DESCRIPTION
95
96A dependent type is a type constraint whose validity is dependent on a second
97value. You defined the dependent type constraint with a primary type constraint
98(such as 'Int') a 'constraining' value type constraint (such as a 'Set' object)
99and a coderef (such as a 'where' clause in your type constraint declaration)
100which will compare the incoming value to be checked with a value that conforms
101to the constraining type constraint.
102
103Once created, you can use dependent types directly, or in your L<Moose> based
104attributes and methods (if you are using L<MooseX::Declare>). Attribute traits
105are available to make it easy to assign the dependency to the value of another
106attribute or another method.
107
88f58fbf 108A Dependent Type Constraint should be a 'drop in' replacement for any place you
109need the parent type (the type constraint being made dependent). For example,
110if you are expecting an 'Int' type, you can use the 'UniqueInt' type constraint
111as described above, since a UniqueInt is considered a subtype of Int.
112
5964b3ca 113=head1 TYPE CONSTRAINTS
114
115All type constraints are defined in L<MooseX::Dependent::Types>. Please see
116that class for more documentation and examples of how to create type constraint
117libraries using dependent types.
118
119=cut
120
121=head1 ATTRIBUTE TRAITS
122
123 TBD
124
125=head1 SEE ALSO
126
127L<Moose>, L<Moose::Meta::TypeConstraints>, L<MooseX::Types>
128
129=head1 AUTHOR
130
131John Napiorkowski, C<< <jjnapiork@cpan.org> >>
132
133=head1 COPYRIGHT & LICENSE
134
91623f94 135Copyright 2008-2009, John Napiorkowski C<< <jjnapiork@cpan.org> >>
136
5964b3ca 137This program is free software; you can redistribute it and/or modify
138it under the same terms as Perl itself.
139
140=cut
141
1421;