Add built local::lib
[catagits/Gitalist.git] / local-lib5 / man / man3 / MooseX::Types::Structured.3pm
CommitLineData
3fea05b9 1.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.10)
2.\"
3.\" Standard preamble:
4.\" ========================================================================
5.de Sp \" Vertical space (when we can't use .PP)
6.if t .sp .5v
7.if n .sp
8..
9.de Vb \" Begin verbatim text
10.ft CW
11.nf
12.ne \\$1
13..
14.de Ve \" End verbatim text
15.ft R
16.fi
17..
18.\" Set up some character translations and predefined strings. \*(-- will
19.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
20.\" double quote, and \*(R" will give a right double quote. \*(C+ will
21.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
22.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
23.\" nothing in troff, for use with C<>.
24.tr \(*W-
25.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
26.ie n \{\
27. ds -- \(*W-
28. ds PI pi
29. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
30. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
31. ds L" ""
32. ds R" ""
33. ds C` ""
34. ds C' ""
35'br\}
36.el\{\
37. ds -- \|\(em\|
38. ds PI \(*p
39. ds L" ``
40. ds R" ''
41'br\}
42.\"
43.\" Escape single quotes in literal strings from groff's Unicode transform.
44.ie \n(.g .ds Aq \(aq
45.el .ds Aq '
46.\"
47.\" If the F register is turned on, we'll generate index entries on stderr for
48.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
49.\" entries marked with X<> in POD. Of course, you'll have to process the
50.\" output yourself in some meaningful fashion.
51.ie \nF \{\
52. de IX
53. tm Index:\\$1\t\\n%\t"\\$2"
54..
55. nr % 0
56. rr F
57.\}
58.el \{\
59. de IX
60..
61.\}
62.\"
63.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
64.\" Fear. Run. Save yourself. No user-serviceable parts.
65. \" fudge factors for nroff and troff
66.if n \{\
67. ds #H 0
68. ds #V .8m
69. ds #F .3m
70. ds #[ \f1
71. ds #] \fP
72.\}
73.if t \{\
74. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
75. ds #V .6m
76. ds #F 0
77. ds #[ \&
78. ds #] \&
79.\}
80. \" simple accents for nroff and troff
81.if n \{\
82. ds ' \&
83. ds ` \&
84. ds ^ \&
85. ds , \&
86. ds ~ ~
87. ds /
88.\}
89.if t \{\
90. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
91. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
92. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
93. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
94. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
95. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
96.\}
97. \" troff and (daisy-wheel) nroff accents
98.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
99.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
100.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
101.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
102.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
103.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
104.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
105.ds ae a\h'-(\w'a'u*4/10)'e
106.ds Ae A\h'-(\w'A'u*4/10)'E
107. \" corrections for vroff
108.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
109.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
110. \" for low resolution devices (crt and lpr)
111.if \n(.H>23 .if \n(.V>19 \
112\{\
113. ds : e
114. ds 8 ss
115. ds o a
116. ds d- d\h'-1'\(ga
117. ds D- D\h'-1'\(hy
118. ds th \o'bp'
119. ds Th \o'LP'
120. ds ae ae
121. ds Ae AE
122.\}
123.rm #[ #] #H #V #F C
124.\" ========================================================================
125.\"
126.IX Title "MooseX::Types::Structured 3"
127.TH MooseX::Types::Structured 3 "2010-03-26" "perl v5.8.8" "User Contributed Perl Documentation"
128.\" For nroff, turn off justification. Always turn off hyphenation; it makes
129.\" way too many mistakes in technical documents.
130.if n .ad l
131.nh
132.SH "NAME"
133MooseX::Types::Structured \- Structured Type Constraints for Moose
134.SH "SYNOPSIS"
135.IX Header "SYNOPSIS"
136The following is example usage for this module.
137.PP
138.Vb 1
139\& package Person;
140\&
141\& use Moose;
142\& use MooseX::Types::Moose qw(Str Int HashRef);
143\& use MooseX::Types::Structured qw(Dict Tuple Optional);
144\&
145\& ## A name has a first and last part, but middle names are not required
146\& has name => (
147\& isa=>Dict[
148\& first => Str,
149\& last => Str,
150\& middle => Optional[Str],
151\& ],
152\& );
153\&
154\& ## description is a string field followed by a HashRef of tagged data.
155\& has description => (
156\& isa=>Tuple[
157\& Str,
158\& Optional[HashRef],
159\& ],
160\& );
161\&
162\& ## Remainder of your class attributes and methods
163.Ve
164.PP
165Then you can instantiate this class with something like:
166.PP
167.Vb 10
168\& my $john = Person\->new(
169\& name => {
170\& first => \*(AqJohn\*(Aq,
171\& middle => \*(AqJames\*(Aq
172\& last => \*(AqNapiorkowski\*(Aq,
173\& },
174\& description => [
175\& \*(AqA cool guy who loves Perl and Moose.\*(Aq, {
176\& married_to => \*(AqVanessa Li\*(Aq,
177\& born_in => \*(AqUSA\*(Aq,
178\& };
179\& ]
180\& );
181.Ve
182.PP
183Or with:
184.PP
185.Vb 7
186\& my $vanessa = Person\->new(
187\& name => {
188\& first => \*(AqVanessa\*(Aq,
189\& last => \*(AqLi\*(Aq
190\& },
191\& description => [\*(AqA great student!\*(Aq],
192\& );
193.Ve
194.PP
195But all of these would cause a constraint error for the 'name' attribute:
196.PP
197.Vb 2
198\& ## Value for \*(Aqname\*(Aq not a HashRef
199\& Person\->new( name => \*(AqJohn\*(Aq );
200\&
201\& ## Value for \*(Aqname\*(Aq has incorrect hash key and missing required keys
202\& Person\->new( name => {
203\& first_name => \*(AqJohn\*(Aq
204\& });
205\&
206\& ## Also incorrect keys
207\& Person\->new( name => {
208\& first_name => \*(AqJohn\*(Aq,
209\& age => 39,
210\& });
211\&
212\& ## key \*(Aqmiddle\*(Aq incorrect type, should be a Str not a ArrayRef
213\& Person\->new( name => {
214\& first => \*(AqVanessa\*(Aq,
215\& middle => [1,2],
216\& last => \*(AqLi\*(Aq,
217\& });
218.Ve
219.PP
220And these would cause a constraint error for the 'description' attribute:
221.PP
222.Vb 2
223\& ## Should be an ArrayRef
224\& Person\->new( description => \*(AqHello I am a String\*(Aq );
225\&
226\& ## First element must be a string not a HashRef.
227\& Person\->new (description => [{
228\& tag1 => \*(Aqvalue1\*(Aq,
229\& tag2 => \*(Aqvalue2\*(Aq
230\& }]);
231.Ve
232.PP
233Please see the test cases for more examples.
234.SH "DESCRIPTION"
235.IX Header "DESCRIPTION"
236A structured type constraint is a standard container Moose type constraint,
237such as an ArrayRef or HashRef, which has been enhanced to allow you to
238explicitly name all the allowed type constraints inside the structure. The
239generalized form is:
240.PP
241.Vb 1
242\& TypeConstraint[@TypeParameters or %TypeParameters]
243.Ve
244.PP
245Where 'TypeParameters' is an array reference or hash references of
246Moose::Meta::TypeConstraint objects.
247.PP
248This type library enables structured type constraints. It is built on top of the
249MooseX::Types library system, so you should review the documentation for that
250if you are not familiar with it.
251.SS "Comparing Parameterized types to Structured types"
252.IX Subsection "Comparing Parameterized types to Structured types"
253Parameterized constraints are built into core Moose and you are probably already
254familiar with the type constraints 'HashRef' and 'ArrayRef'. Structured types
255have similar functionality, so their syntax is likewise similar. For example,
256you could define a parameterized constraint like:
257.PP
258.Vb 2
259\& subtype ArrayOfInts,
260\& as ArrayRef[Int];
261.Ve
262.PP
263which would constrain a value to something like [1,2,3,...] and so on. On the
264other hand, a structured type constraint explicitly names all it's allowed
265\&'internal' type parameter constraints. For the example:
266.PP
267.Vb 2
268\& subtype StringFollowedByInt,
269\& as Tuple[Str,Int];
270.Ve
271.PP
272would constrain it's value to things like ['hello', 111] but ['hello', 'world']
273would fail, as well as ['hello', 111, 'world'] and so on. Here's another
274example:
275.PP
276.Vb 1
277\& package MyApp::Types;
278\&
279\& use MooseX::Types \-declare [qw(StringIntOptionalHashRef)];
280\& use MooseX::Types::Moose qw(Str Int);
281\& use MooseX::Types::Structured qw(Tuple Optional);
282\&
283\& subtype StringIntOptionalHashRef,
284\& as Tuple[
285\& Str, Int,
286\& Optional[HashRef]
287\& ];
288.Ve
289.PP
290This defines a type constraint that validates values like:
291.PP
292.Vb 2
293\& [\*(AqHello\*(Aq, 100, {key1 => \*(Aqvalue1\*(Aq, key2 => \*(Aqvalue2\*(Aq}];
294\& [\*(AqWorld\*(Aq, 200];
295.Ve
296.PP
297Notice that the last type constraint in the structure is optional. This is
298enabled via the helper Optional type constraint, which is a variation of the
299core Moose type constraint 'Maybe'. The main difference is that Optional type
300constraints are required to validate if they exist, while 'Maybe' permits
301undefined values. So the following example would not validate:
302.PP
303.Vb 1
304\& StringIntOptionalHashRef\->validate([\*(AqHello Undefined\*(Aq, 1000, undef]);
305.Ve
306.PP
307Please note the subtle difference between undefined and null. If you wish to
308allow both null and undefined, you should use the core Moose 'Maybe' type
309constraint instead:
310.PP
311.Vb 1
312\& package MyApp::Types;
313\&
314\& use MooseX::Types \-declare [qw(StringIntMaybeHashRef)];
315\& use MooseX::Types::Moose qw(Str Int Maybe);
316\& use MooseX::Types::Structured qw(Tuple);
317\&
318\& subtype StringIntMaybeHashRef,
319\& as Tuple[
320\& Str, Int, Maybe[HashRef]
321\& ];
322.Ve
323.PP
324This would validate the following:
325.PP
326.Vb 3
327\& [\*(AqHello\*(Aq, 100, {key1 => \*(Aqvalue1\*(Aq, key2 => \*(Aqvalue2\*(Aq}];
328\& [\*(AqWorld\*(Aq, 200, undef];
329\& [\*(AqWorld\*(Aq, 200];
330.Ve
331.PP
332Structured constraints are not limited to arrays. You can define a structure
333against a HashRef with the 'Dict' type constaint as in this example:
334.PP
335.Vb 5
336\& subtype FirstNameLastName,
337\& as Dict[
338\& firstname => Str,
339\& lastname => Str,
340\& ];
341.Ve
342.PP
343This would constrain a HashRef that validates something like:
344.PP
345.Vb 1
346\& {firstname => \*(AqChristopher\*(Aq, lastname => \*(AqParsons\*(Aq};
347.Ve
348.PP
349but all the following would fail validation:
350.PP
351.Vb 2
352\& ## Incorrect keys
353\& {first => \*(AqChristopher\*(Aq, last => \*(AqParsons\*(Aq};
354\&
355\& ## Too many keys
356\& {firstname => \*(AqChristopher\*(Aq, lastname => \*(AqParsons\*(Aq, middlename => \*(AqAllen\*(Aq};
357\&
358\& ## Not a HashRef
359\& [\*(AqChristopher\*(Aq, \*(AqParsons\*(Aq];
360.Ve
361.PP
362These structures can be as simple or elaborate as you wish. You can even
363combine various structured, parameterized and simple constraints all together:
364.PP
365.Vb 6
366\& subtype Crazy,
367\& as Tuple[
368\& Int,
369\& Dict[name=>Str, age=>Int],
370\& ArrayRef[Int]
371\& ];
372.Ve
373.PP
374Which would match:
375.PP
376.Vb 1
377\& [1, {name=>\*(AqJohn\*(Aq, age=>25},[10,11,12]];
378.Ve
379.PP
380Please notice how the type parameters can be visually arranged to your liking
381and to improve the clarity of your meaning. You don't need to run then
382altogether onto a single line. Additionally, since the 'Dict' type constraint
383defines a hash constraint, the key order is not meaningful. For example:
384.PP
385.Vb 6
386\& subtype AnyKeyOrder,
387\& as Dict[
388\& key1=>Int,
389\& key2=>Str,
390\& key3=>Int,
391\& ];
392.Ve
393.PP
394Would validate both:
395.PP
396.Vb 2
397\& {key1 => 1, key2 => "Hi!", key3 => 2};
398\& {key2 => "Hi!", key1 => 100, key3 => 300};
399.Ve
400.PP
401As you would expect, since underneath its just a plain old Perl hash at work.
402.SS "Alternatives"
403.IX Subsection "Alternatives"
404You should exercise some care as to whether or not your complex structured
405constraints would be better off contained by a real object as in the following
406example:
407.PP
408.Vb 2
409\& package MyApp::MyStruct;
410\& use Moose;
411\&
412\& ## lazy way to make a bunch of attributes
413\& has $_ for qw(full_name age_in_years);
414\&
415\& package MyApp::MyClass;
416\& use Moose;
417\&
418\& has person => (isa => \*(AqMyApp::MyStruct\*(Aq);
419\&
420\& my $instance = MyApp::MyClass\->new(
421\& person=>MyApp::MyStruct\->new(
422\& full_name => \*(AqJohn\*(Aq,
423\& age_in_years => 39,
424\& ),
425\& );
426.Ve
427.PP
428This method may take some additional time to setup but will give you more
429flexibility. However, structured constraints are highly compatible with this
430method, granting some interesting possibilities for coercion. Try:
431.PP
432.Vb 1
433\& package MyApp::MyClass;
434\&
435\& use Moose;
436\& use MyApp::MyStruct;
437\&
438\& ## It\*(Aqs recommended your type declarations live in a separate class in order
439\& ## to promote reusability and clarity. Inlined here for brevity.
440\&
441\& use MooseX::Types::DateTime qw(DateTime);
442\& use MooseX::Types \-declare [qw(MyStruct)];
443\& use MooseX::Types::Moose qw(Str Int);
444\& use MooseX::Types::Structured qw(Dict);
445\&
446\& ## Use class_type to create an ISA type constraint if your object doesn\*(Aqt
447\& ## inherit from Moose::Object.
448\& class_type \*(AqMyApp::MyStruct\*(Aq;
449\&
450\& ## Just a shorter version really.
451\& subtype MyStruct,
452\& as \*(AqMyApp::MyStruct\*(Aq;
453\&
454\& ## Add the coercions.
455\& coerce MyStruct,
456\& from Dict[
457\& full_name=>Str,
458\& age_in_years=>Int
459\& ], via {
460\& MyApp::MyStruct\->new(%$_);
461\& },
462\& from Dict[
463\& lastname=>Str,
464\& firstname=>Str,
465\& dob=>DateTime
466\& ], via {
467\& my $name = $_\->{firstname} .\*(Aq \*(Aq. $_\->{lastname};
468\& my $age = DateTime\->now \- $_\->{dob};
469\&
470\& MyApp::MyStruct\->new(
471\& full_name=>$name,
472\& age_in_years=>$age\->years,
473\& );
474\& };
475\&
476\& has person => (isa=>MyStruct);
477.Ve
478.PP
479This would allow you to instantiate with something like:
480.PP
481.Vb 4
482\& my $obj = MyApp::MyClass\->new( person => {
483\& full_name=>\*(AqJohn Napiorkowski\*(Aq,
484\& age_in_years=>39,
485\& });
486.Ve
487.PP
488Or even:
489.PP
490.Vb 5
491\& my $obj = MyApp::MyClass\->new( person => {
492\& lastname=>\*(AqJohn\*(Aq,
493\& firstname=>\*(AqNapiorkowski\*(Aq,
494\& dob=>DateTime\->new(year=>1969),
495\& });
496.Ve
497.PP
498If you are not familiar with how coercions work, check out the Moose cookbook
499entry Moose::Cookbook::Recipe5 for an explanation. The section \*(L"Coercions\*(R"
500has additional examples and discussion.
501.SS "Subtyping a Structured type constraint"
502.IX Subsection "Subtyping a Structured type constraint"
503You need to exercise some care when you try to subtype a structured type as in
504this example:
505.PP
506.Vb 2
507\& subtype Person,
508\& as Dict[name => Str];
509\&
510\& subtype FriendlyPerson,
511\& as Person[
512\& name => Str,
513\& total_friends => Int,
514\& ];
515.Ve
516.PP
517This will actually work \s-1BUT\s0 you have to take care that the subtype has a
518structure that does not contradict the structure of it's parent. For now the
519above works, but I will clarify the syntax for this at a future point, so
520it's recommended to avoid (should not really be needed so much anyway). For
521now this is supported in an \s-1EXPERIMENTAL\s0 way. Your thoughts, test cases and
522patches are welcomed for discussion. If you find a good use for this, please
523let me know.
524.SS "Coercions"
525.IX Subsection "Coercions"
526Coercions currently work for 'one level' deep. That is you can do:
527.PP
528.Vb 5
529\& subtype Person,
530\& as Dict[
531\& name => Str,
532\& age => Int
533\& ];
534\&
535\& subtype Fullname,
536\& as Dict[
537\& first => Str,
538\& last => Str
539\& ];
540\&
541\& coerce Person,
542\& ## Coerce an object of a particular class
543\& from BlessedPersonObject, via {
544\& +{
545\& name=>$_\->name,
546\& age=>$_\->age,
547\& };
548\& },
549\&
550\& ## Coerce from [$name, $age]
551\& from ArrayRef, via {
552\& +{
553\& name=>$_\->[0],
554\& age=>$_\->[1],
555\& },
556\& },
557\& ## Coerce from {fullname=>{first=>...,last=>...}, dob=>$DateTimeObject}
558\& from Dict[fullname=>Fullname, dob=>DateTime], via {
559\& my $age = $_\->dob \- DateTime\->now;
560\& my $firstn = $_\->{fullname}\->{first};
561\& my $lastn = $_\->{fullname}\->{last}
562\& +{
563\& name => $_\->{fullname}\->{first} .\*(Aq \*(Aq. ,
564\& age =>$age\->years
565\& }
566\& };
567.Ve
568.PP
569And that should just work as expected. However, if there are any 'inner'
570coercions, such as a coercion on 'Fullname' or on 'DateTime', that coercion
571won't currently get activated.
572.PP
573Please see the test '07\-coerce.t' for a more detailed example. Discussion on
574extending coercions to support this welcome on the Moose development channel or
575mailing list.
576.SS "Recursion"
577.IX Subsection "Recursion"
578Newer versions of MooseX::Types support recursive type constraints. That is
579you can include a type constraint as a contained type constraint of itself. For
580example:
581.PP
582.Vb 7
583\& subtype Person,
584\& as Dict[
585\& name=>Str,
586\& friends=>Optional[
587\& ArrayRef[Person]
588\& ],
589\& ];
590.Ve
591.PP
592This would declare a Person subtype that contains a name and an optional
593ArrayRef of Persons who are friends as in:
594.PP
595.Vb 10
596\& {
597\& name => \*(AqMike\*(Aq,
598\& friends => [
599\& { name => \*(AqJohn\*(Aq },
600\& { name => \*(AqVincent\*(Aq },
601\& {
602\& name => \*(AqTracey\*(Aq,
603\& friends => [
604\& { name => \*(AqStephenie\*(Aq },
605\& { name => \*(AqIlya\*(Aq },
606\& ],
607\& },
608\& ],
609\& };
610.Ve
611.PP
612Please take care to make sure the recursion node is either Optional, or declare
613a Union with an non recursive option such as:
614.PP
615.Vb 5
616\& subtype Value
617\& as Tuple[
618\& Str,
619\& Str|Tuple,
620\& ];
621.Ve
622.PP
623Which validates:
624.PP
625.Vb 10
626\& [
627\& \*(AqHello\*(Aq, [
628\& \*(AqWorld\*(Aq, [
629\& \*(AqIs\*(Aq, [
630\& \*(AqGetting\*(Aq,
631\& \*(AqOld\*(Aq,
632\& ],
633\& ],
634\& ],
635\& ];
636.Ve
637.PP
638Otherwise you will define a subtype thatis impossible to validate since it is
639infinitely recursive. For more information about defining recursive types,
640please see the documentation in MooseX::Types and the test cases.
641.SH "TYPE CONSTRAINTS"
642.IX Header "TYPE CONSTRAINTS"
643This type library defines the following constraints.
644.SS "Tuple[@constraints]"
645.IX Subsection "Tuple[@constraints]"
646This defines an ArrayRef based constraint which allows you to validate a specific
647list of contained constraints. For example:
648.PP
649.Vb 2
650\& Tuple[Int,Str]; ## Validates [1,\*(Aqhello\*(Aq]
651\& Tuple[Str|Object, Int]; ## Validates [\*(Aqhello\*(Aq, 1] or [$object, 2]
652.Ve
653.PP
654The Values of \f(CW@constraints\fR should ideally be MooseX::Types declared type
655constraints. We do support 'old style' Moose string based constraints to a
656limited degree but these string type constraints are considered deprecated.
657There will be limited support for bugs resulting from mixing string and
658MooseX::Types in your structures. If you encounter such a bug and really
659need it fixed, we will required a detailed test case at the minimum.
660.SS "Dict[%constraints]"
661.IX Subsection "Dict[%constraints]"
662This defines a HashRef based constraint which allowed you to validate a specific
663hashref. For example:
664.PP
665.Vb 1
666\& Dict[name=>Str, age=>Int]; ## Validates {name=>\*(AqJohn\*(Aq, age=>39}
667.Ve
668.PP
669The keys in \f(CW%constraints\fR follow the same rules as \f(CW@constraints\fR in the above
670section.
671.ie n .SS "Map[ $key_constraint, $value_constraint ]"
672.el .SS "Map[ \f(CW$key_constraint\fP, \f(CW$value_constraint\fP ]"
673.IX Subsection "Map[ $key_constraint, $value_constraint ]"
674This defines a HashRef based constraint in which both the keys and values are
675required to meet certain constraints. For example, to map hostnames to \s-1IP\s0
676addresses, you might say:
677.PP
678.Vb 1
679\& Map[ HostName, IPAddress ]
680.Ve
681.PP
682The type constraint would only be met if every key was a valid HostName and
683every value was a valid IPAddress.
684.SS "Optional[$constraint]"
685.IX Subsection "Optional[$constraint]"
686This is primarily a helper constraint for Dict and Tuple type constraints. What
687this allows is for you to assert that a given type constraint is allowed to be
688null (but \s-1NOT\s0 undefined). If the value is null, then the type constraint passes
689but if the value is defined it must validate against the type constraint. This
690makes it easy to make a Dict where one or more of the keys doesn't have to exist
691or a tuple where some of the values are not required. For example:
692.PP
693.Vb 5
694\& subtype Name() => as Dict[
695\& first=>Str,
696\& last=>Str,
697\& middle=>Optional[Str],
698\& ];
699.Ve
700.PP
701Creates a constraint that validates against a hashref with the keys 'first' and
702\&'last' being strings and required while an optional key 'middle' is must be a
703string if it appears but doesn't have to appear. So in this case both the
704following are valid:
705.PP
706.Vb 2
707\& {first=>\*(AqJohn\*(Aq, middle=>\*(AqJames\*(Aq, last=>\*(AqNapiorkowski\*(Aq}
708\& {first=>\*(AqVanessa\*(Aq, last=>\*(AqLi\*(Aq}
709.Ve
710.PP
711If you use the 'Maybe' type constraint instead, your values will also validate
712against 'undef', which may be incorrect for you.
713.SH "EXPORTABLE SUBROUTINES"
714.IX Header "EXPORTABLE SUBROUTINES"
715This type library makes available for export the following subroutines
716.SS "slurpy"
717.IX Subsection "slurpy"
718Structured type constraints by their nature are closed; that is validation will
719depend on an exact match between your structure definition and the arguments to
720be checked. Sometimes you might wish for a slightly looser amount of validation.
721For example, you may wish to validate the first 3 elements of an array reference
722and allow for an arbitrary number of additional elements. At first thought you
723might think you could do it this way:
724.PP
725.Vb 8
726\& # I want to validate stuff like: [1,"hello", $obj, 2,3,4,5,6,...]
727\& subtype AllowTailingArgs,
728\& as Tuple[
729\& Int,
730\& Str,
731\& Object,
732\& ArrayRef[Int],
733\& ];
734.Ve
735.PP
736However what this will actually validate are structures like this:
737.PP
738.Vb 1
739\& [10,"Hello", $obj, [11,12,13,...] ]; # Notice element 4 is an ArrayRef
740.Ve
741.PP
742In order to allow structured validation of, \*(L"and then some\*(R", arguments, you can
743use the \*(L"slurpy\*(R" method against a type constraint. For example:
744.PP
745.Vb 1
746\& use MooseX::Types::Structured qw(Tuple slurpy);
747\&
748\& subtype AllowTailingArgs,
749\& as Tuple[
750\& Int,
751\& Str,
752\& Object,
753\& slurpy ArrayRef[Int],
754\& ];
755.Ve
756.PP
757This will now work as expected, validating ArrayRef structures such as:
758.PP
759.Vb 1
760\& [1,"hello", $obj, 2,3,4,5,6,...]
761.Ve
762.PP
763A few caveats apply. First, the slurpy type constraint must be the last one in
764the list of type constraint parameters. Second, the parent type of the slurpy
765type constraint must match that of the containing type constraint. That means
766that a Tuple can allow a slurpy ArrayRef (or children of ArrayRefs, including
767another Tuple) and a Dict can allow a slurpy HashRef (or children/subtypes of
768HashRef, also including other Dict constraints).
769.PP
770Please note the the technical way this works 'under the hood' is that the
771slurpy keyword transforms the target type constraint into a coderef. Please do
772not try to create your own custom coderefs; always use the slurpy method. The
773underlying technology may change in the future but the slurpy keyword will be
774supported.
775.SH "ERROR MESSAGES"
776.IX Header "ERROR MESSAGES"
777Error reporting has been improved to return more useful debugging messages. Now
778I will stringify the incoming check value with Devel::PartialDump so that you
779can see the actual structure that is tripping up validation. Also, I report the
780\&'internal' validation error, so that if a particular element inside the
781Structured Type is failing validation, you will see that. There's a limit to
782how deep this internal reporting goes, but you shouldn't see any of the \*(L"failed
783with \s-1ARRAY\s0(\s-1XXXXXX\s0)\*(R" that we got with earlier versions of this module.
784.PP
785This support is continuing to expand, so it's best to use these messages for
786debugging purposes and not for creating messages that 'escape into the wild'
787such as error messages sent to the user.
788.PP
789Please see the test '12\-error.t' for a more lengthy example. Your thoughts and
790preferable tests or code patches very welcome!
791.SH "EXAMPLES"
792.IX Header "EXAMPLES"
793Here are some additional example usage for structured types. All examples can
794be found also in the 't/examples.t' test. Your contributions are also welcomed.
795.SS "Normalize a HashRef"
796.IX Subsection "Normalize a HashRef"
797You need a hashref to conform to a canonical structure but are required accept a
798bunch of different incoming structures. You can normalize using the Dict type
799constraint and coercions. This example also shows structured types mixed which
800other MooseX::Types libraries.
801.PP
802.Vb 1
803\& package Test::MooseX::Meta::TypeConstraint::Structured::Examples::Normalize;
804\&
805\& use Moose;
806\& use DateTime;
807\&
808\& use MooseX::Types::Structured qw(Dict Tuple);
809\& use MooseX::Types::DateTime qw(DateTime);
810\& use MooseX::Types::Moose qw(Int Str Object);
811\& use MooseX::Types \-declare => [qw(Name Age Person)];
812\&
813\& subtype Person,
814\& as Dict[
815\& name=>Str,
816\& age=>Int,
817\& ];
818\&
819\& coerce Person,
820\& from Dict[
821\& first=>Str,
822\& last=>Str,
823\& years=>Int,
824\& ], via { +{
825\& name => "$_\->{first} $_\->{last}",
826\& age => $_\->{years},
827\& }},
828\& from Dict[
829\& fullname=>Dict[
830\& last=>Str,
831\& first=>Str,
832\& ],
833\& dob=>DateTime,
834\& ],
835\& ## DateTime needs to be inside of single quotes here to disambiguate the
836\& ## class package from the DataTime type constraint imported via the
837\& ## line "use MooseX::Types::DateTime qw(DateTime);"
838\& via { +{
839\& name => "$_\->{fullname}{first} $_\->{fullname}{last}",
840\& age => ($_\->{dob} \- \*(AqDateTime\*(Aq\->now)\->years,
841\& }};
842\&
843\& has person => (is=>\*(Aqrw\*(Aq, isa=>Person, coerce=>1);
844.Ve
845.PP
846And now you can instantiate with all the following:
847.PP
848.Vb 6
849\& _\|_PACKAGE_\|_\->new(
850\& person=>{
851\& name=>\*(AqJohn Napiorkowski\*(Aq,
852\& age=>39,
853\& },
854\& );
855\&
856\& _\|_PACKAGE_\|_\->new(
857\& person=>{
858\& first=>\*(AqJohn\*(Aq,
859\& last=>\*(AqNapiorkowski\*(Aq,
860\& years=>39,
861\& },
862\& );
863\&
864\& _\|_PACKAGE_\|_\->new(
865\& person=>{
866\& fullname => {
867\& first=>\*(AqJohn\*(Aq,
868\& last=>\*(AqNapiorkowski\*(Aq
869\& },
870\& dob => \*(AqDateTime\*(Aq\->new(
871\& year=>1969,
872\& month=>2,
873\& day=>13
874\& ),
875\& },
876\& );
877.Ve
878.PP
879This technique is a way to support various ways to instantiate your class in a
880clean and declarative way.
881.SH "SEE ALSO"
882.IX Header "SEE ALSO"
883The following modules or resources may be of interest.
884.PP
885Moose, MooseX::Types, Moose::Meta::TypeConstraint,
886MooseX::Meta::TypeConstraint::Structured
887.SH "TODO"
888.IX Header "TODO"
889Here's a list of stuff I would be happy to get volunteers helping with:
890.PP
891.Vb 4
892\& * All POD examples need test cases in t/documentation/*.t
893\& * Want to break out the examples section to a separate cookbook style POD.
894\& * Want more examples and best practice / usage guidance for authors
895\& * Need to clarify deep coercions,
896.Ve
897.SH "AUTHOR"
898.IX Header "AUTHOR"
899John Napiorkowski <jjnapiork@cpan.org>
900.SH "CONTRIBUTORS"
901.IX Header "CONTRIBUTORS"
902The following people have contributed to this module and agree with the listed
903Copyright & license information included below:
904.PP
905.Vb 3
906\& Florian Ragwitz, <rafl@debian.org>
907\& Yuval Kogman, <nothingmuch@woobling.org>
908\& Tomas Doran, <bobtfish@bobtfish.net>
909.Ve
910.SH "COPYRIGHT & LICENSE"
911.IX Header "COPYRIGHT & LICENSE"
912Copyright 2008\-2009, John Napiorkowski <jjnapiork@cpan.org>
913.PP
914This program is free software; you can redistribute it and/or modify it under
915the same terms as Perl itself.