more specification and documentation
[gitmo/MooseX-Dependent.git] / lib / MooseX / Dependent.pm
1 package MooseX::Dependent;
2
3 use 5.008;
4
5 use strict;
6 use warnings;
7
8 our $VERSION = '0.01';
9 our $AUTHORITY = 'cpan:JJNAPIORK';
10
11 =head1 NAME
12
13 MooseX::Dependent - Dependent L<MooseX::Types> constraints and L<Moose> attributes
14
15 =head1 SYNOPSIS
16
17 Given 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);
23     use Moosex::Types -declare => [qw(Set UniqueID)];
24
25         subtype Set,
26                 as Object,
27                 where {
28                         shift->can('find');
29                 };
30
31         subtype UniqueID,
32                 as Dependent[Int, Set],
33                 where {
34                         my ($int, $set) = @_;
35                         return $set->find($int) ? 0:1;
36                 };
37
38 Assuming 'Set' is a class that creates and manages sets of values (lists of
39 unique but unordered values) with a method '->find($n)', which returns true when
40 $n is a member of the set and which you instantiate like so:
41
42         my $set_obj = Set->new(1,2,3,4,5); ## 1..5 are member of Set $set_obj'
43
44 You can then use this $set_obj as a parameter on the previously declared type
45 constraint 'UniqueID'.  This $set_obj become part of the constraint (you can't
46 actually use the constraint without it.)
47
48         UniqueID[$set_obj]->check(1); ## Not OK, since one isn't unique in $set_obj
49     UniqueID[$set_obj]->check(100);  ## OK, since 100 isn't in the set.
50
51 Additionally, you can use these dependent types on your L<Moose> based classes
52 and set the dependency target to the value of another attribute or method:
53
54     TDB: Following is tentative
55     
56     package MyApp::MyClass;
57
58     use Moose;
59     use MooseX::Dependent (or maybe a role, or traits...?)
60     use MooseX::Types::Moose qw();
61     use MyApp::Types qw(UniqueID Set);
62     
63     has people => (is=>'ro', isa=>Set, required=>1);
64     has id => (is=>'ro', isa=>UniqueID, required=>1);
65
66 Please see the test cases for more examples.
67
68 =head1 DESCRIPTION
69
70 A dependent type is a type constraint whose validity is dependent on a second
71 value.  You defined the dependent type constraint with a primary type constraint
72 (such as 'Int') a 'constraining' value type constraint (such as a 'Set' object)
73 and a coderef (such as a 'where' clause in your type constraint declaration)
74 which will compare the incoming value to be checked with a value that conforms
75 to the constraining type constraint.
76
77 Once created, you can use dependent types directly, or in your L<Moose> based
78 attributes and methods (if you are using L<MooseX::Declare>).  Attribute traits
79 are available to make it easy to assign the dependency to the value of another
80 attribute or another method.
81
82 =head1 TYPE CONSTRAINTS
83
84 All type constraints are defined in L<MooseX::Dependent::Types>.  Please see
85 that class for more documentation and examples of how to create type constraint
86 libraries using dependent types.
87
88 =cut
89
90 =head1 ATTRIBUTE TRAITS
91
92     TBD
93
94 =head1 SEE ALSO
95
96 L<Moose>, L<Moose::Meta::TypeConstraints>, L<MooseX::Types>
97
98 =head1 AUTHOR
99
100 John Napiorkowski, C<< <jjnapiork@cpan.org> >>
101
102 =head1 COPYRIGHT & LICENSE
103
104 This program is free software; you can redistribute it and/or modify
105 it under the same terms as Perl itself.
106
107 =cut
108
109 1;