File Coverage

blib/lib/MooX/Pression.pm
Criterion Covered Total %
statement 513 640 80.1
branch 173 310 55.8
condition 47 91 51.6
subroutine 66 78 84.6
pod 4 6 66.6
total 803 1125 71.3


line stmt bran cond sub pod time code
1 25     25   1243510 use 5.014;
  25         215  
2 25     21   115 use strict;
  21         32  
  21         364  
3 21     20   87 use warnings;
  20         29  
  20         426  
4 20     20   87 use B ();
  20         26  
  20         294  
5 20     20   79 use Carp ();
  20         29  
  20         267  
6 20     20   7322 use Import::Into ();
  20         41092  
  20         444  
7 20     20   10674 use MooX::Press 0.025 ();
  20         2152688  
  20         586  
8 20     20   7237 use MooX::Press::Keywords ();
  20         1718733  
  20         503  
9 20     20   8088 use Syntax::Keyword::Try ();
  20         11869  
  20         411  
10 20     20   116 use feature ();
  20         43  
  20         775  
11              
12             package MooX::Pression;
13              
14             our $AUTHORITY = 'cpan:TOBYINK';
15             our $VERSION = '0.301';
16              
17 20     20   6679 use Keyword::Simple ();
  20         38264  
  20         404  
18 20     20   11686 use PPR;
  20         630706  
  20         679  
19 20     20   163 use B::Hooks::EndOfScope;
  20         37  
  20         210  
20 20     20   9360 use Exporter::Shiny our @EXPORT = qw( version authority overload );
  20         7121  
  20         127  
21 20     20   7342 use Devel::StrictMode qw(STRICT);
  20         5596  
  20         14703  
22              
23             BEGIN {
24             package MooX::Pression::_Gather;
25 20     20   79 my %gather;
26             my %stack;
27             sub import {
28 235     235   6630 my ($me, $action, $caller) = (shift, shift, scalar caller);
29 235 100       911 if ($action eq -gather) {
    100          
    100          
    50          
30 87         254 while (@_) {
31 167         369 my ($k, $v) = splice @_, 0, 2;
32 167 100       757 if (my ($kind,$pkg) = ($k =~ /^(class|role|class_generator|role_generator):(.+)$/)) {
33 61 50       100 if ( my @stack = @{ $stack{$me}{$caller}||[] } ) {
  61 50       379  
34 61 50       182 pop @stack if $stack[-1] eq $pkg;
35 61 100       177 if (@stack) {
36 25         48 $v->{_stack} = \@stack;
37 25         49 $kind = '_defer_'.$kind;
38             }
39             }
40 61   100     107 push @{ $gather{$me}{$caller}{$kind}||=[] }, $pkg, $v;
  61         2062  
41             }
42             else {
43 106         302 $gather{$me}{$caller}{$k} = $v;
44             }
45             }
46             }
47             elsif ($action eq -go) {
48 26 50       116 if ($gather{$me}{$caller}{'_defer_role'}) {
49 0         0 require Carp;
50 0         0 Carp::croak('Nested roles are not supported');
51             }
52 26 50       112 if ($gather{$me}{$caller}{'_defer_role_generator'}) {
53 0         0 require Carp;
54 0         0 Carp::croak('Nested role generators are not supported');
55             }
56 26 100       96 if ($gather{$me}{$caller}{'_defer_class_generator'}) {
57 1   50     9 $me->_undefer_class_generators($gather{$me}{$caller}{'class_generator'}||=[], delete $gather{$me}{$caller}{'_defer_class_generator'});
58             }
59 26 100       99 if ($gather{$me}{$caller}{'_defer_class'}) {
60 5         25 $me->_undefer_classes($gather{$me}{$caller}{'class'}, delete $gather{$me}{$caller}{'_defer_class'});
61             }
62            
63 23 50       111 if ($gather{$me}{$caller}{debug}) {
64 0         0 require Data::Dumper;
65 0         0 warn Data::Dumper::Dumper($gather{$me}{$caller});
66             }
67            
68 23         77 @_ = ('MooX::Press' => $gather{$me}{$caller});
69 23         167 goto \&MooX::Press::import;
70             }
71             elsif ($action eq -parent) {
72 61   100     116 push @{ $stack{$me}{$caller}||=[] }, $_[0];
  61         2914  
73             }
74             elsif ($action eq -unparent) {
75 61         111 pop @{ $stack{$me}{$caller} };
  61         1170  
76             }
77             else {
78 0         0 die;
79             }
80             }
81             sub _undefer_classes {
82 5     5   17 my ($me, $classes, $d) = @_;
83 5 100       10 my %class_hash = @{$classes||[]};
  5         33  
84 5         11 my @deferred;
85 5         7 my $max_depth = 0;
86 5         16 while (@$d) {
87 24         45 my ($class, $spec) = splice(@$d, 0, 2);
88 24         37 $spec->{_class_name} = $class;
89 24         34 $spec->{_depth} = @{ $spec->{_stack} };
  24         34  
90 24         37 push @deferred, $spec;
91 24 100       51 $max_depth = $spec->{_depth} if $spec->{_depth} > $max_depth;
92             }
93 5         29 DEPTH: for my $depth (1 .. $max_depth) {
94 8         13 SPEC: for my $spec (@deferred) {
95 84 100       126 next SPEC unless $spec->{_depth} == $depth;
96 24         27 my $parent_key = join('|', @{$spec->{_stack}});
  24         47  
97 24         27 my $my_key = join('|', @{$spec->{_stack}}, $spec->{_class_name});
  24         39  
98 24 100       41 if (not $class_hash{$parent_key}) {
99 3         11 require Carp;
100             Carp::croak(sprintf(
101             '%s is nested in %s but %s is not a class',
102             $spec->{_class_name},
103             $spec->{_stack}[-1],
104 3         914 $spec->{_stack}[-1],
105             ));
106             }
107 21   100     25 push @{ $class_hash{$parent_key}{subclass} ||=[] }, $spec->{_class_name}, $spec;
  21         57  
108 21         43 $class_hash{$my_key} = $spec;
109             }
110             }
111 2         6 for my $spec (@deferred) {
112 21         27 delete $spec->{_stack};
113 21         23 delete $spec->{_class_name};
114 21         29 delete $spec->{_depth};
115             }
116             }
117             sub _undefer_class_generators {
118 1     1   4 my ($me, $classes, $d) = @_;
119 1         3 while (@$d) {
120 1         4 my ($class, $spec) = splice(@$d, 0, 2);
121 1         2 my $extends = $spec->{_stack}[-1];
122 1         2 my $next = delete($spec->{code});
123             $spec->{code} = sub {
124 2     2   75146 my $got = $next->(@_);
125 2   50     18 $got->{extends} ||= [$extends];
126 2         10 $got;
127 1         7 };
128 1         3 delete $spec->{_stack};
129 1         3 push @$classes, $class, $spec;
130             }
131             }
132              
133 20         71144 $INC{'MooX/Pression/_Gather.pm'} = __FILE__;
134             };
135              
136             #
137             # GRAMMAR
138             #
139              
140             our $GRAMMAR = qr{
141             (?(DEFINE)
142            
143             (?<PerlKeyword>
144            
145             (?: include (?&MxpIncludeSyntax) )|
146             (?: class (?&MxpClassSyntax) )|
147             (?: abstract (?&MxpAbstractSyntax) )|
148             (?: role (?&MxpRoleSyntax) )|
149             (?: interface (?&MxpRoleSyntax) )|
150             (?: toolkit (?&MxpToolkitSyntax) )|
151             (?: begin (?&MxpHookSyntax) )|
152             (?: end (?&MxpHookSyntax) )|
153             (?: type_name (?&MxpTypeNameSyntax) )|
154             (?: extends (?&MxpExtendsSyntax) )|
155             (?: with (?&MxpWithSyntax) )|
156             (?: requires (?&MxpWithSyntax) )|
157             (?: has (?&MxpHasSyntax) )|
158             (?: constant (?&MxpConstantSyntax) )|
159             (?: coerce (?&MxpCoerceSyntax) )|
160             (?: method (?&MxpMethodSyntax) )|
161             (?: factory (?&MxpFactorySyntax) )|
162             (?: factory (?&MxpFactoryViaSyntax))|
163             (?: before (?&MxpModifierSyntax) )|
164             (?: after (?&MxpModifierSyntax) )|
165             (?: around (?&MxpModifierSyntax) )|
166             (?: multi (?&MxpMultiSyntax) )
167             )#</PerlKeyword>
168            
169             (?<MxpSimpleIdentifier>
170            
171             (?&PerlIdentifier)|(?&PerlBlock)
172             )#</MxpSimpleIdentifier>
173            
174             (?<MxpSimpleIdentifiers>
175            
176             (?&MxpSimpleIdentifier)
177             (?:
178             (?&PerlOWS)
179             ,
180             (?&PerlOWS)
181             (?&MxpSimpleIdentifier)
182             )*
183             )#</MxpSimpleIdentifiers>
184            
185             (?<MxpDecoratedIdentifier>
186            
187             (?: \+ )? # CAPTURE:plus
188             (?: \* )? # CAPTURE:asterisk
189             (?: (?&MxpSimpleIdentifier) ) # CAPTURE:name
190             (?: \! | \? )? # CAPTURE:postfix
191             )#</MxpDecoratedIdentifier>
192            
193             (?<MxpDecoratedIdentifierSolo>
194             (?: (?&MxpDecoratedIdentifier) ) # deliberately non-capturing
195             )#</MxpDecoratedIdentifierSolo>
196            
197             (?<MxpDecoratedIdentifiers>
198            
199             (?&MxpDecoratedIdentifier)
200             (?:
201             (?&PerlOWS)
202             ,
203             (?&PerlOWS)
204             (?&MxpDecoratedIdentifier)
205             )*
206             )#</MxpDecoratedIdentifiers>
207            
208             (?<MxpSimpleTypeSpec>
209            
210             ~?(?&PerlBareword)(?&PerlAnonymousArray)?
211             )#</MxpSimpleTypeSpec>
212            
213             (?<MxpTypeSpec>
214            
215             (?&MxpSimpleTypeSpec)
216             (?:
217             \s*\&\s*
218             (?&MxpSimpleTypeSpec)
219             )*
220             (?:
221             \s*\|\s*
222             (?&MxpSimpleTypeSpec)
223             (?:
224             \s*\&\s*
225             (?&MxpSimpleTypeSpec)
226             )*
227             )*
228             )#</MxpTypeSpec>
229            
230             (?<MxpExtendedTypeSpec>
231            
232             (?&MxpTypeSpec)|(?&PerlBlock)
233             )#</MxpExtendedTypeSpec>
234            
235             (?<MxpSignatureElement>
236            
237             (?&PerlOWS)
238             (?: (?&MxpExtendedTypeSpec))? # CAPTURE:type
239             (?&PerlOWS)
240             (?: # CAPTURE:name
241             (?&PerlVariable) | (\*(?&PerlIdentifier))
242             )
243             (?: # CAPTURE:postamble
244             \? | ((?&PerlOWS)=(?&PerlOWS)(?&PerlTerm))
245             )?
246             )#</MxpSignatureElement>
247            
248             (?<MxpSignatureList>
249            
250             (?&MxpSignatureElement)
251             (?:
252             (?&PerlOWS)
253             ,
254             (?&PerlOWS)
255             (?&MxpSignatureElement)
256             )*
257             )#</MxpSignatureList>
258            
259             (?<MxpAttribute>
260            
261             :
262             [^\W0-9]\w*
263             (?:
264             [(]
265             [^\)]+
266             [)]
267             )?
268             )#</MxpAttribute>
269            
270             (?<MxpRoleList>
271            
272             (?&PerlOWS)
273             (?:
274             (?&PerlBlock) | (?&PerlQualifiedIdentifier)
275             )
276             (?:
277             (?:\s*\?) | (?: (?&PerlOWS)(?&PerlList))
278             )?
279             (?:
280             (?&PerlOWS)
281             ,
282             (?&PerlOWS)
283             (?:
284             (?&PerlBlock) | (?&PerlQualifiedIdentifier)
285             )
286             (?:
287             (?:\s*\?) | (?: (?&PerlOWS)(?&PerlList))
288             )?
289             )*
290             )#</MxpRoleList>
291            
292             (?<MxpClassSyntax>
293            
294             (?&PerlOWS)
295             (?: [+] )? # CAPTURE:plus
296             (?: (?&PerlQualifiedIdentifier) )? # CAPTURE:name
297             (?&PerlOWS)
298             (?:
299             [(]
300             (?&PerlOWS)
301             (?: # CAPTURE:sig
302             (?&MxpSignatureList)?
303             )
304             (?&PerlOWS)
305             [)]
306             )?
307             (?&PerlOWS)
308             (?: (?&PerlBlock) )? # CAPTURE:block
309             (?&PerlOWS)
310             )#</MxpClassSyntax>
311            
312             (?<MxpIncludeSyntax>
313            
314             (?&PerlOWS)
315             (?: (?&PerlQualifiedIdentifier) )? # CAPTURE:name
316             (?&PerlOWS)
317             )#</MxpIncludeSyntax>
318            
319             (?<MxpAbstractSyntax>
320            
321             (?&PerlOWS)
322             class
323             (?&PerlOWS)
324             (?: [+] )? # CAPTURE:plus
325             (?: (?&PerlQualifiedIdentifier) )? # CAPTURE:name
326             (?&PerlOWS)
327             (?:
328             [(]
329             (?&PerlOWS)
330             (?: # CAPTURE:sig
331             (?&MxpSignatureList)?
332             )
333             (?&PerlOWS)
334             [)]
335             )?
336             (?&PerlOWS)
337             (?: (?&PerlBlock) )? # CAPTURE:block
338             (?&PerlOWS)
339             )#</MxpAbstractSyntax>
340            
341             (?<MxpRoleSyntax>
342            
343             (?&PerlOWS)
344             (?: (?&PerlQualifiedIdentifier) )? # CAPTURE:name
345             (?&PerlOWS)
346             (?:
347             [(]
348             (?&PerlOWS)
349             (?: # CAPTURE:sig
350             (?&MxpSignatureList)?
351             )
352             (?&PerlOWS)
353             [)]
354             )?
355             (?&PerlOWS)
356             (?: (?&PerlBlock) )? # CAPTURE:block
357             (?&PerlOWS)
358             )#</MxpRoleSyntax>
359            
360             (?<MxpHookSyntax>
361            
362             (?&PerlOWS)
363             (?: (?&PerlBlock) ) # CAPTURE:hook
364             (?&PerlOWS)
365             )#</MxpHookSyntax>
366            
367             (?<MxpTypeNameSyntax>
368            
369             (?&PerlOWS)
370             (?: (?&PerlIdentifier) ) # CAPTURE:name
371             (?&PerlOWS)
372             )#</MxpTypeNameSyntax>
373            
374             (?<MxpToolkitSyntax>
375            
376             (?&PerlOWS)
377             (?: (?&PerlIdentifier) ) # CAPTURE:name
378             (?&PerlOWS)
379             (?:
380             [(]
381             (?&PerlOWS)
382             (?: # CAPTURE:imports
383             (?: (?&PerlQualifiedIdentifier)|(?&PerlComma)|(?&PerlOWS) )*
384             )
385             (?&PerlOWS)
386             [)]
387             )?
388             (?&PerlOWS)
389             )#</MxpToolkitSyntax>
390            
391             (?<MxpExtendsSyntax>
392            
393             (?&PerlOWS)
394             (?: # CAPTURE:list
395             (?&MxpRoleList)
396             )
397             (?&PerlOWS)
398             )#</MxpExtendsSyntax>
399            
400             (?<MxpWithSyntax>
401            
402             (?&PerlOWS)
403             (?: # CAPTURE:list
404             (?&MxpRoleList)
405             )
406             (?&PerlOWS)
407             )#</MxpWithSyntax>
408            
409             (?<MxpRequiresSyntax>
410            
411             (?&PerlOWS)
412             (?: (?&MxpSimpleIdentifier) ) # CAPTURE:name
413             (?&PerlOWS)
414             (?:
415             [(]
416             (?&PerlOWS)
417             (?: # CAPTURE:sig
418             (?&MxpSignatureList)?
419             )
420             (?&PerlOWS)
421             [)]
422             )?
423             (?&PerlOWS)
424             )#</MxpRequiresSyntax>
425            
426             (?<MxpHasSyntax>
427            
428             (?&PerlOWS)
429             (?: (?&MxpDecoratedIdentifiers) ) # CAPTURE:name
430             (?&PerlOWS)
431             (?:
432             [(]
433             (?&PerlOWS)
434             (?: (?&PerlList) ) # CAPTURE:spec
435             (?&PerlOWS)
436             [)]
437             )?
438             (?&PerlOWS)
439             (?:
440             [=]
441             (?&PerlOWS)
442             (?: (?&PerlAssignment) ) # CAPTURE:default
443             )?
444             (?&PerlOWS)
445             )#</MxpHasSyntax>
446            
447             (?<MxpConstantSyntax>
448            
449             (?&PerlOWS)
450             (?: (?&PerlIdentifier) ) # CAPTURE:name
451             (?&PerlOWS)
452             =
453             (?&PerlOWS)
454             (?: (?&PerlExpression) ) # CAPTURE:expr
455             (?&PerlOWS)
456             )#</MxpConstantSyntax>
457            
458             (?<MxpMethodSyntax>
459            
460             (?&PerlOWS)
461             (?: (?&MxpSimpleIdentifier) )? # CAPTURE:name
462             (?&PerlOWS)
463             (?: ( (?&MxpAttribute) (?&PerlOWS) )+ )? # CAPTURE:attributes
464             (?&PerlOWS)
465             (?:
466             [(]
467             (?&PerlOWS)
468             (?: # CAPTURE:sig
469             (?&MxpSignatureList)?
470             )
471             (?&PerlOWS)
472             [)]
473             )?
474             (?&PerlOWS)
475             (?: (?&PerlBlock) ) # CAPTURE:code
476             (?&PerlOWS)
477             )#</MxpMethodSyntax>
478            
479             (?<MxpMultiSyntax>
480            
481             (?&PerlOWS)
482             method
483             (?&PerlOWS)
484             (?: (?&MxpSimpleIdentifier) ) # CAPTURE:name
485             (?&PerlOWS)
486             (?: ( (?&MxpAttribute) (?&PerlOWS) )+ )? # CAPTURE:attributes
487             (?&PerlOWS)
488             (?:
489             [(]
490             (?&PerlOWS)
491             (?: # CAPTURE:sig
492             (?&MxpSignatureList)?
493             )
494             (?&PerlOWS)
495             [)]
496             )?
497             (?&PerlOWS)
498             (?: (?&PerlBlock) ) # CAPTURE:code
499             (?&PerlOWS)
500             )#</MxpMultiSyntax>
501            
502             (?<MxpModifierSyntax>
503            
504             (?&PerlOWS)
505             (?: (?&MxpSimpleIdentifiers) ) # CAPTURE:name
506             (?&PerlOWS)
507             (?: ( (?&MxpAttribute) (?&PerlOWS) )+ )? # CAPTURE:attributes
508             (?&PerlOWS)
509             (?:
510             [(]
511             (?&PerlOWS)
512             (?: # CAPTURE:sig
513             (?&MxpSignatureList)?
514             )
515             (?&PerlOWS)
516             [)]
517             )?
518             (?&PerlOWS)
519             (?: (?&PerlBlock) ) # CAPTURE:code
520             (?&PerlOWS)
521             )#</MxpModifierSyntax>
522            
523             # Easier to provide two separate patterns for `factory`
524            
525             (?<MxpFactorySyntax>
526            
527             (?&PerlOWS)
528             (?: (?&MxpSimpleIdentifier) ) # CAPTURE:name
529             (?&PerlOWS)
530             (?: ( (?&MxpAttribute) (?&PerlOWS) )+ )? # CAPTURE:attributes
531             (?&PerlOWS)
532             (?:
533             [(]
534             (?&PerlOWS)
535             (?: # CAPTURE:sig
536             (?&MxpSignatureList)?
537             )
538             (?&PerlOWS)
539             [)]
540             )?
541             (?&PerlOWS)
542             (?: (?&PerlBlock) ) # CAPTURE:code
543             (?&PerlOWS)
544             )#</MxpFactorySyntax>
545            
546             (?<MxpFactoryViaSyntax>
547            
548             (?&PerlOWS)
549             (?: (?&MxpSimpleIdentifier) ) # CAPTURE:name
550             (?&PerlOWS)
551             (?:
552             (: via )
553             (?: # CAPTURE:via
554             (?&PerlBlock)|(?&PerlIdentifier)|(?&PerlString)
555             )
556             )?
557             (?&PerlOWS)
558             )#</MxpFactoryViaSyntax>
559            
560             (?<MxpCoerceSyntax>
561            
562             (?&PerlOWS)
563             (?: from )?
564             (?&PerlOWS)
565             (?: # CAPTURE:from
566             (?&MxpExtendedTypeSpec)
567             )
568             (?&PerlOWS)
569             (?: via )
570             (?&PerlOWS)
571             (?: # CAPTURE:via
572             (?&PerlBlock)|(?&PerlIdentifier)|(?&PerlString)
573             )
574             (?&PerlOWS)
575             (?: (?&PerlBlock) ) # CAPTURE:code
576             (?&PerlOWS)
577             )#</MxpCoerceSyntax>
578            
579              
580             )
581             $PPR::GRAMMAR
582             }xso;
583              
584             my %_fetch_re_cache;
585             sub _fetch_re {
586 162     162   552 my $key = "@_";
587 162         260 my $name = shift;
588 162         426 my %opts = @_;
589            
590 162   100     569 $opts{anchor} ||= '';
591            
592 162   66     11041 $_fetch_re_cache{$key} ||= do {
593 88 50       72971 "$GRAMMAR" =~ m{<$name>(.+)</$name>}s or die "could not fetch re for $name";
594 88         870 (my $re = $1) =~ s/\)\#$//;
595 88         753 my @lines = split /\n/, $re;
596 88         242 for (@lines) {
597 1236 100       2611 if (my ($named_capture) = /# CAPTURE:(\w+)/) {
598 201         970 s/\(\?\:/\(\?<$named_capture>/;
599             }
600             }
601 88         313 $re = join "\n", @lines;
602             $opts{anchor} eq 'start' ? qr/ ^ $re $GRAMMAR /xs :
603             $opts{anchor} eq 'end' ? qr/ $re $GRAMMAR $ /xs :
604 88 50       2868108 $opts{anchor} eq 'both' ? qr/ ^ $re $GRAMMAR $ /xs : qr/ $re $GRAMMAR /xs
    50          
    100          
605             }
606             }
607              
608             #
609             # HELPERS
610             #
611              
612             sub _handle_signature_list {
613 23     23   53 my $me = shift;
614 23         47 my $sig = $_[0];
615 23         33 my $seen_named = 0;
616 23         56 my $seen_pos = 0;
617 23         43 my @parsed;
618            
619             return (
620 23 100       83 0,
621             '',
622             '[]',
623             '',
624             ) if !$sig;
625            
626 19         78 while ($sig) {
627 28         101 $sig =~ s/^\s+//xs;
628 28 50       81 last if !$sig;
629            
630 28         89 push @parsed, {};
631            
632 28 100       607833 if ($sig =~ /^((?&PerlBlock)) $GRAMMAR/xso) {
    100          
633 3         65 my $type = $1;
634 3         9 $parsed[-1]{type} = $type;
635 3         5 $parsed[-1]{type_is_block} = 1;
636 3         26 $sig =~ s/^\Q$type//xs;
637 3         31761 $sig =~ s/^((?&PerlOWS)) $GRAMMAR//xso;
638             }
639             elsif ($sig =~ /^((?&MxpTypeSpec)) $GRAMMAR/xso) {
640 19         110 my $type = $1;
641 19         82 $parsed[-1]{type} = $type;
642 19         60 $parsed[-1]{type_is_block} = 0;
643 19         288 $sig =~ s/^\Q$type//xs;
644 19         253972 $sig =~ s/^((?&PerlOWS)) $GRAMMAR//xso;
645             }
646             else {
647 6         20 $parsed[-1]{type} = 'Any';
648 6         12 $parsed[-1]{type_is_block} = 0;
649             }
650            
651 28 100       635833 if ($sig =~ /^\*((?&PerlIdentifier)) $GRAMMAR/xso) {
    50          
652 2         6 my $name = $1;
653 2         6 $parsed[-1]{name} = $name;
654 2         6 $parsed[-1]{named} = 1;
655 2         4 $parsed[-1]{positional} = 0;
656 2         4 ++$seen_named;
657 2         22 $sig =~ s/^\*\Q$name//xs;
658 2         31316 $sig =~ s/^((?&PerlOWS)) $GRAMMAR//xso;
659             }
660             elsif ($sig =~ /^((?&PerlVariable)) $GRAMMAR/xso) {
661 26         177 my $name = $1;
662 26         83 $parsed[-1]{name} = $name;
663 26         64 $parsed[-1]{named} = 0;
664 26         56 $parsed[-1]{positional} = 1;
665 26         43 ++$seen_pos;
666 26         353 $sig =~ s/^\Q$name//xs;
667 26         823513 $sig =~ s/^((?&PerlOWS)) $GRAMMAR//xs;
668             }
669            
670 28 50       367204 if ($sig =~ /^\?/) {
    100          
671 0         0 $parsed[-1]{optional} = 1;
672 0         0 $sig =~ s/^\?((?&PerlOWS)) $GRAMMAR//xso;
673             }
674             elsif ($sig =~ /^=((?&PerlOWS))((?&PerlTerm)) $GRAMMAR/xso) {
675 2         20 my ($ws, $default) = ($1, $2);
676 2         10 $parsed[-1]{default} = $default;
677 2         31 $sig =~ s/^=\Q$ws$default//xs;
678 2         63227 $sig =~ s/^((?&PerlOWS)) $GRAMMAR//xso;
679             }
680            
681 28 100       1627 if ($sig) {
682 9 50       81 $sig =~ /^,/ or die "WEIRD SIGNATURE??? $sig";
683 9         94 $sig =~ s/^,//;
684             }
685             }
686            
687 19         122 my @signature_var_list;
688 19         50 my $type_params_stuff = '[';
689            
690 19         51 my (@head, @tail);
691 19 50 66     175 if ($seen_named and $seen_pos) {
692 0   0     0 while (@parsed and $parsed[0]{positional}) {
693 0         0 push @head, shift @parsed;
694             }
695 0   0     0 while (@parsed and $parsed[-1]{positional}) {
696 0         0 unshift @tail, pop @parsed;
697             }
698 0 0       0 if (grep $_->{positional}, @parsed) {
699 0         0 require Carp;
700 0         0 Carp::croak("Signature contains an unexpected mixture of positional and named parameters");
701             }
702 0         0 for my $p (@head, @tail) {
703 0         0 my $is_optional = $p->{optional};
704 0   0     0 $is_optional ||= ($p->{type} =~ /^Optional/s);
705 0 0       0 if ($is_optional) {
    0          
    0          
706 0         0 require Carp;
707 0         0 Carp::croak("Cannot have optional positional parameter $p->{name} in signature with named parameters");
708             }
709             elsif ($p->{default}) {
710 0         0 require Carp;
711 0         0 Carp::croak("Cannot have positional parameter $p->{name} with default in signature with named parameters");
712             }
713             elsif ($p->{name} =~ /^[\@\%]/) {
714 0         0 require Carp;
715 0         0 Carp::croak("Cannot have slurpy parameter $p->{name} in signature with named parameters");
716             }
717             }
718             }
719            
720 19         200 require B;
721              
722 19         47 my $extra = '';
723 19         45 my $count = @parsed;
724 19         79 while (my $p = shift @parsed) {
725 28 100       79 $type_params_stuff .= B::perlstring($p->{name}) . ',' if $seen_named;
726 28 100       136 if ($p->{name} =~ /^[\@\%]/) {
727 3 50       11 die "Cannot have slurpy in non-final position" if @parsed;
728             $extra .= sprintf(
729             'my (%s) = (@_==%d ? %s{$_[-1]} : ());',
730             $p->{name},
731             $count,
732 3         26 substr($p->{name}, 0, 1),
733             );
734 3         11 $p->{slurpy} = 1;
735 3 100       39 if ($p->{type} eq 'Any') {
736 2 100       9 $p->{type} = substr($p->{name}, 0, 1) eq '%' ? 'HashRef' : 'ArrayRef';
737             }
738             }
739             else {
740 25         115 push @signature_var_list, $p->{name};
741             }
742            
743 28 100       70 if ($p->{type_is_block}) {
744 3         18 $type_params_stuff .= sprintf('scalar(do %s)', $p->{type}) . ',';
745             }
746             else {
747 25         140 $type_params_stuff .= B::perlstring($p->{type}) . ',';
748             }
749 28 100 66     300 if (exists $p->{optional} or exists $p->{default} or $p->{slurpy}) {
      100        
750 5         14 $type_params_stuff .= '{';
751 5 50       15 $type_params_stuff .= sprintf('optional=>%d,', !!$p->{optional}) if exists $p->{optional};
752 5 100       84 $type_params_stuff .= sprintf('default=>sub{scalar(%s)},', $p->{default}) if exists $p->{default};
753 5 100       22 $type_params_stuff .= sprintf('slurpy=>%d,', !!$p->{slurpy}) if exists $p->{slurpy};
754 5         45 $type_params_stuff .= '},';
755             }
756             }
757            
758 19 100       80 @signature_var_list = '$arg' if $seen_named;
759 19         44 $type_params_stuff .= ']';
760            
761 19 50 33     90 if (@head or @tail) {
762 0         0 require Type::Params;
763 0         0 'Type::Params'->VERSION(1.009002);
764 0 0       0 my $head_stuff = join(q[,] => map { $_->{type_is_block} ? sprintf('scalar(do %s)', $_->{type}) : B::perlstring($_->{type}) } @head);
  0         0  
765 0 0       0 my $tail_stuff = join(q[,] => map { $_->{type_is_block} ? sprintf('scalar(do %s)', $_->{type}) : B::perlstring($_->{type}) } @tail);
  0         0  
766 0 0       0 my $opts = sprintf('{head=>%s,tail=>%s},', $head_stuff?"[$head_stuff]":0, $tail_stuff?"[$tail_stuff]":0);
    0          
767 0         0 substr($type_params_stuff, 1, 0) = $opts; # insert options after "["
768 0         0 unshift @signature_var_list, map $_->{name}, @head;
769 0         0 push @signature_var_list, map $_->{name}, @tail;
770             }
771            
772             return (
773 19         167 $seen_named,
774             join(',', @signature_var_list),
775             $type_params_stuff,
776             $extra,
777             );
778             }
779              
780             sub _handle_role_list {
781 14     14   34 my $me = shift;
782 14         40 my ($rolelist, $kind) = @_;
783 14         27 my @return;
784            
785 14         71 while (length $rolelist) {
786 15         52 $rolelist =~ s/^\s+//xs;
787            
788 15         31 my $prefix = '';
789 15         49 my $role = undef;
790 15         25 my $role_is_block = 0;
791 15         28 my $suffix = '';
792 15         31 my $role_params = undef;
793            
794 15 100       507950 if ($rolelist =~ /^((?&PerlBlock)) $GRAMMAR/xso) {
    50          
795 3         79 $role = $1;
796 3         6 $role_is_block = 1;
797 3         60 $rolelist =~ s/^\Q$role//xs;
798 3         10 $rolelist =~ s/^\s+//xs;
799             }
800             elsif ($rolelist =~ /^((?&PerlQualifiedIdentifier)) $GRAMMAR/xso) {
801 12         64 $role = $1;
802 12         189 $rolelist =~ s/^\Q$role//xs;
803 12         50 $rolelist =~ s/^\s+//xs;
804             }
805             else {
806 0         0 die "expected role name, got $rolelist";
807             }
808            
809 15 100       295475 if ($rolelist =~ /^\?/xs) {
    100          
810 4 50       15 die 'unexpected question mark' if $kind eq 'class';
811 4         7 $suffix = '?';
812 4         13 $rolelist =~ s/^\?\s*//xs;
813             }
814             elsif ($rolelist =~ /^((?&PerlList)) $GRAMMAR/xso) {
815 4         23 $role_params = $1;
816 4         67 $rolelist =~ s/^\Q$role_params//xs;
817 4         15 $rolelist =~ s/^\s+//xs;
818             }
819            
820 15 100       1110 if ($role_is_block) {
821 3         29 push @return, sprintf('sprintf(q(%s%%s%s), scalar(do %s))', $prefix, $suffix, $role);
822             }
823             else {
824 12         218 push @return, B::perlstring("$prefix$role$suffix");
825             }
826 15 100       109 if ($role_params) {
827 4         20 push @return, sprintf('[%s]', $role_params);
828             }
829            
830 15         50 $rolelist =~ s/^\s+//xs;
831 15 100       145 if (length $rolelist) {
832 1 50       5 $rolelist =~ /^,/ or die "expected comma, got $rolelist";
833 1         10 $rolelist =~ s/^\,\s*//;
834             }
835             }
836            
837 14         1182 return join(",", @return);
838             }
839              
840             sub _handle_name_list {
841 28     28   77 my ($me, $names) = @_;
842 28 50       78 return unless $names;
843            
844 28         68 state $re = _fetch_re('MxpDecoratedIdentifierSolo');
845 28         2009733 my @names = grep defined, ($names =~ /($re) $GRAMMAR/xg);
846 28         6456 return @names;
847             }
848              
849             sub _handle_factory_keyword {
850 2     2   7 my ($me, $name, $via, $code, $has_sig, $sig, $attrs) = @_;
851            
852 2         3 my $optim;
853 2         8 for my $attr (@$attrs) {
854 0 0       0 $optim = 1 if $attr =~ /^:optimize\b/;
855             }
856            
857 2 50       6 if ($via) {
858 0 0       0 return sprintf(
    0          
859             'q[%s]->_factory(%s, \\(%s));',
860             $me,
861             ($name =~ /^\{/ ? "scalar(do $name)" : B::perlstring($name)),
862             ($via =~ /^\{/ ? "scalar(do $via)" : B::perlstring($via)),
863             );
864             }
865 2 50       56 if (!$has_sig) {
866 0         0 my $munged_code = sprintf('sub { my ($factory, $class) = (@_); do %s }', $code);
867 0 0       0 return sprintf(
    0          
868             'q[%s]->_factory(%s, { caller => __PACKAGE__, code => %s, optimize => %d });',
869             $me,
870             ($name =~ /^\{/ ? "scalar(do $name)" : B::perlstring($name)),
871             $optim ? B::perlstring($munged_code) : $munged_code,
872             !!$optim,
873             );
874             }
875 2         10 my ($signature_is_named, $signature_var_list, $type_params_stuff, $extra) = $me->_handle_signature_list($sig);
876 2         15 my $munged_code = sprintf('sub { my($factory,$class,%s)=(shift,shift,@_); %s; do %s }', $signature_var_list, $extra, $code);
877 2 50       31 sprintf(
    50          
878             'q[%s]->_factory(%s, { caller => __PACKAGE__, code => %s, named => %d, signature => %s, optimize => %d });',
879             $me,
880             ($name =~ /^\{/ ? "scalar(do $name)" : B::perlstring($name)),
881             $optim ? B::perlstring($munged_code) : $munged_code,
882             !!$signature_is_named,
883             $type_params_stuff,
884             !!$optim,
885             );
886             }
887              
888             sub _handle_method_keyword {
889 13     13   35 my $me = shift;
890 13         39 my ($name, $code, $has_sig, $sig, $attrs) = @_;
891            
892 13         28 my $optim;
893 13         44 for my $attr (@$attrs) {
894 1 50       7 $optim = 1 if $attr =~ /^:optimize\b/;
895             }
896            
897 13 100       38 if (defined $name) {
898 12 100       31 if ($has_sig) {
899 9         39 my ($signature_is_named, $signature_var_list, $type_params_stuff, $extra) = $me->_handle_signature_list($sig);
900 9         49 my $munged_code = sprintf('sub { my($self,%s)=(shift,@_); %s; my $class = ref($self)||$self; do %s }', $signature_var_list, $extra, $code);
901 9 50       1744 return sprintf(
    100          
902             'q[%s]->_can(%s, { caller => __PACKAGE__, code => %s, named => %d, signature => %s, optimize => %d });',
903             $me,
904             ($name =~ /^\{/ ? "scalar(do $name)" : B::perlstring($name)),
905             $optim ? B::perlstring($munged_code) : $munged_code,
906             !!$signature_is_named,
907             $type_params_stuff,
908             !!$optim,
909             );
910             }
911             else {
912 3         20 my $munged_code = sprintf('sub { my $self = $_[0]; my $class = ref($self)||$self; do %s }', $code);
913 3 50       426 return sprintf(
    50          
914             'q[%s]->_can(%s, { caller => __PACKAGE__, code => %s, optimize => %d });',
915             $me,
916             ($name =~ /^\{/ ? "scalar(do $name)" : B::perlstring($name)),
917             $optim ? B::perlstring($munged_code) : $munged_code,
918             !!$optim,
919             );
920             }
921             }
922             else {
923 1 50       4 if ($has_sig) {
924 1         3 my ($signature_is_named, $signature_var_list, $type_params_stuff, $extra) = $me->_handle_signature_list($sig);
925 1         50 my $munged_code = sprintf('sub { my($self,%s)=(shift,@_); %s; my $class = ref($self)||$self; do %s }', $signature_var_list, $extra, $code);
926 1 50       180 return sprintf(
927             'q[%s]->wrap_coderef({ caller => __PACKAGE__, code => %s, named => %d, signature => %s, optimize => %d });',
928             'MooX::Press',
929             $optim ? B::perlstring($munged_code) : $munged_code,
930             !!$signature_is_named,
931             $type_params_stuff,
932             !!$optim,
933             );
934             }
935             else {
936 0         0 my $munged_code = sprintf('sub { my $self = $_[0]; my $class = ref($self)||$self; do %s }', $code);
937 0 0       0 return sprintf(
938             'q[%s]->wrap_coderef({ caller => __PACKAGE__, code => %s, optimize => %d });',
939             'MooX::Press',
940             $optim ? B::perlstring($munged_code) : $munged_code,
941             !!$optim,
942             );
943             }
944             }
945             }
946              
947             sub _handle_multimethod_keyword {
948 0     0   0 my $me = shift;
949 0         0 my ($name, $code, $has_sig, $sig, $attrs) = @_;
950            
951 0         0 my $optim;
952 0         0 my $extra_code = '';
953 0         0 for my $attr (@$attrs) {
954 0 0       0 $optim = 1 if $attr =~ /^:optimize\b/;
955 0 0       0 $extra_code .= sprintf('alias=>%s', B::perlstring($1)) if $attr =~ /^:alias\((.+)\)$/;
956             }
957            
958 0 0       0 if ($has_sig) {
959 0         0 my ($signature_is_named, $signature_var_list, $type_params_stuff, $extra) = $me->_handle_signature_list($sig);
960 0         0 my $munged_code = sprintf('sub { my($self,%s)=(shift,@_); %s; my $class = ref($self)||$self; do %s }', $signature_var_list, $extra, $code);
961 0 0       0 return sprintf(
962             'q[%s]->_multimethod(%s, { caller => __PACKAGE__, code => %s, named => %d, signature => %s, %s });',
963             $me,
964             ($name =~ /^\{/ ? "scalar(do $name)" : B::perlstring($name)),
965             $munged_code,
966             !!$signature_is_named,
967             $type_params_stuff,
968             $extra_code,
969             );
970             }
971             else {
972 0         0 my $munged_code = sprintf('sub { my $self = $_[0]; my $class = ref($self)||$self; do %s }', $code);
973 0 0       0 return sprintf(
974             'q[%s]->_multimethod(%s, { caller => __PACKAGE__, code => %s, named => 0, signature => sub { @_ }, %s });',
975             $me,
976             ($name =~ /^\{/ ? "scalar(do $name)" : B::perlstring($name)),
977             $munged_code,
978             $extra_code,
979             );
980             }
981             }
982              
983             sub _handle_modifier_keyword {
984 2     2   10 my ($me, $kind, $names, $code, $has_sig, $sig, $attrs) = @_;
985              
986 2         4 my $optim;
987 2         7 for my $attr (@$attrs) {
988 0 0       0 $optim = 1 if $attr =~ /^:optimize\b/;
989             }
990            
991 2         9 my @names = $me->_handle_name_list($names);
992            
993             my $processed_names =
994             join q[, ],
995 2 50       8 map { /^\{/ ? "scalar(do $_)" : B::perlstring($_) } @names;
  3         34  
996              
997 2 100       12 if ($has_sig) {
    50          
998 1         5 my ($signature_is_named, $signature_var_list, $type_params_stuff, $extra) = $me->_handle_signature_list($sig);
999 1         2 my $munged_code;
1000 1 50       3 if ($kind eq 'around') {
1001 0         0 $munged_code = sprintf('sub { my($next,$self,%s)=(shift,shift,@_); %s; my $class = ref($self)||$self; do %s }', $signature_var_list, $extra, $code);
1002             }
1003             else {
1004 1         7 $munged_code = sprintf('sub { my($self,%s)=(shift,@_); %s; my $class = ref($self)||$self; do %s }', $signature_var_list, $extra, $code);
1005             }
1006 1 50       260 sprintf(
1007             'q[%s]->_modifier(q(%s), %s, { caller => __PACKAGE__, code => %s, named => %d, signature => %s, optimize => %d });',
1008             $me,
1009             $kind,
1010             $processed_names,
1011             $optim ? B::perlstring($munged_code) : $munged_code,
1012             !!$signature_is_named,
1013             $type_params_stuff,
1014             !!$optim,
1015             );
1016             }
1017             elsif ($kind eq 'around') {
1018 1         11 my $munged_code = sprintf('sub { my ($next, $self) = @_; my $class = ref($self)||$self; do %s }', $code);
1019 1 50       136 sprintf(
1020             'q[%s]->_modifier(q(%s), %s, { caller => __PACKAGE__, code => %s, optimize => %d });',
1021             $me,
1022             $kind,
1023             $processed_names,
1024             $optim ? B::perlstring($munged_code) : $munged_code,
1025             !!$optim,
1026             );
1027             }
1028             else {
1029 0         0 my $munged_code = sprintf('sub { my $self = $_[0]; my $class = ref($self)||$self; do %s }', $code);
1030 0 0       0 sprintf(
1031             'q[%s]->_modifier(q(%s), %s, { caller => __PACKAGE__, code => %s, optimize => %d });',
1032             $me,
1033             $kind,
1034             $processed_names,
1035             $optim ? B::perlstring($munged_code) : $munged_code,
1036             !!$optim,
1037             );
1038             }
1039             }
1040              
1041             sub _handle_package_keyword {
1042 66     66   209 my ($me, $kind, $name, $code, $has_sig, $sig, $plus, $opts) = @_;
1043            
1044 66 100       180 if ($kind eq 'abstract') {
1045 1         2 $kind = 'class';
1046 1         4 $code = "{ q[$me]->_abstract(1); $code }";
1047             }
1048            
1049 66 50       170 if ($kind eq 'interface') {
1050 0         0 $kind = 'role';
1051 0         0 $code = "{ q[$me]->_interface(1); $code }";
1052             }
1053            
1054 66 100 100     341 if ($name and $has_sig) {
    100          
    100          
1055 7         31 my ($signature_is_named, $signature_var_list, $type_params_stuff, $extra) = $me->_handle_signature_list($sig);
1056 7         47 my $munged_code = sprintf('sub { q(%s)->_package_callback(sub { my ($generator,%s)=(shift,@_); %s; do %s }, @_) }', $me, $signature_var_list, $extra, $code);
1057 7         726 sprintf(
1058             'use MooX::Pression::_Gather -parent => %s; use MooX::Pression::_Gather -gather, %s => { code => %s, named => %d, signature => %s }; use MooX::Pression::_Gather -unparent;',
1059             B::perlstring("$plus$name"),
1060             B::perlstring("$kind\_generator:$plus$name"),
1061             $munged_code,
1062             !!$signature_is_named,
1063             $type_params_stuff,
1064             );
1065             }
1066             elsif ($has_sig) {
1067 1         5 my ($signature_is_named, $signature_var_list, $type_params_stuff, $extra) = $me->_handle_signature_list($sig);
1068 1         8 my $munged_code = sprintf('sub { q(%s)->_package_callback(sub { my ($generator,%s)=(shift,@_); %s; do %s }, @_) }', $me, $signature_var_list, $extra, $code);
1069             sprintf(
1070             'q[%s]->anonymous_generator(%s => { code => %s, named => %d, signature => %s }, toolkit => %s, prefix => %s, factory_package => %s, type_library => %s)',
1071             $me,
1072             $kind,
1073             $munged_code,
1074             !!$signature_is_named,
1075             $type_params_stuff,
1076             B::perlstring($opts->{toolkit}||'Moo'),
1077             B::perlstring($opts->{prefix}),
1078             B::perlstring($opts->{factory_package}),
1079 1   50     161 B::perlstring($opts->{type_library}),
1080             );
1081             }
1082             elsif ($name) {
1083 54 50       3287 $code
1084             ? sprintf(
1085             'use MooX::Pression::_Gather -parent => %s; use MooX::Pression::_Gather -gather, %s => q[%s]->_package_callback(sub %s); use MooX::Pression::_Gather -unparent;',
1086             B::perlstring("$plus$name"),
1087             B::perlstring("$kind:$plus$name"),
1088             $me,
1089             $code,
1090             )
1091             : sprintf(
1092             'use MooX::Pression::_Gather -gather, %s => {};',
1093             B::perlstring("$kind:$plus$name"),
1094             );
1095             }
1096             else {
1097 4   50     13 $code ||= '{}';
1098             sprintf(
1099             'q[%s]->anonymous_package(%s => sub { do %s }, toolkit => %s, prefix => %s, factory_package => %s, type_library => %s)',
1100             $me,
1101             $kind,
1102             $code,
1103             B::perlstring($opts->{toolkit}||'Moo'),
1104             B::perlstring($opts->{prefix}),
1105             B::perlstring($opts->{factory_package}),
1106 4   50     221 B::perlstring($opts->{type_library}),
1107             );
1108             }
1109             }
1110              
1111             sub _handle_has_keyword {
1112 26     26   83 my ($me, $names, $rawspec, $default) = @_;
1113            
1114 26 100       82 $rawspec = '()' if !defined $rawspec;
1115            
1116 26 50 66     135 if (defined $default and $default =~ /\$self/) {
    100          
1117 0         0 $rawspec = "lazy => !!1, default => sub { my \$self = \$_[0]; $default }, $rawspec";
1118             }
1119             elsif (defined $default) {
1120 5         17 $rawspec = "default => sub { $default }, $rawspec";
1121             }
1122            
1123 26         101 my @names = $me->_handle_name_list($names);
1124            
1125 26         127 my @r;
1126 26         105 for my $name (@names) {
1127 28         94 $name =~ s/^\+\*/+/;
1128 28         68 $name =~ s/^\*//;
1129 28 100       418 push @r, sprintf(
1130             'q[%s]->_has(%s, %s)',
1131             $me,
1132             ($name =~ /^\{/) ? "scalar(do $name)" : B::perlstring($name),
1133             $rawspec,
1134             );
1135             }
1136 26         2572 join ";", @r;
1137             }
1138              
1139             sub _handle_requires_keyword {
1140 3     3   11 my ($me, $name, $has_sig, $sig) = @_;
1141 3 50       23 my $r1 = sprintf(
1142             'q[%s]->_requires(%s);',
1143             $me,
1144             ($name =~ /^\{/ ? "scalar(do $name)" : B::perlstring($name)),
1145             );
1146 3         6 my $r2 = '';
1147 3 100       9 if (STRICT and $has_sig) {
1148 2         7 my ($signature_is_named, $signature_var_list, $type_params_stuff, $extra) = $me->_handle_signature_list($sig);
1149 2 50       23 $r2 = sprintf(
1150             'q[%s]->_modifier(q(around), %s, { caller => __PACKAGE__, code => %s, named => %d, signature => %s, optimize => %d });',
1151             $me,
1152             ($name =~ /^\{/ ? "scalar(do $name)" : B::perlstring($name)),
1153             'sub { my $next = shift; goto $next }',
1154             !!$signature_is_named,
1155             $type_params_stuff,
1156             1,
1157             );
1158             }
1159 3         320 "$r1$r2";
1160             }
1161              
1162             sub _syntax_error {
1163 0     0   0 my $ref = pop;
1164 0         0 my ($me, $kind, @poss) = @_;
1165 0         0 require Carp;
1166 0         0 Carp::croak(
1167             "Unexpected syntax in $kind.\n" .
1168             "Expected:\n" .
1169             join("", map "\t$_\n", @poss) .
1170             "Got:\n" .
1171             "\t" . substr($$ref, 0, 32)
1172             );
1173             }
1174              
1175             #
1176             # KEYWORDS/UTILITIES
1177             #
1178              
1179             sub import {
1180 20     20   149 no warnings 'closure';
  20         42  
  20         16563  
1181 26     26   20612 my ($me, %opts) = (shift, @_);
1182 26   33     299 my $caller = ($opts{caller} ||= caller);
1183            
1184             # Need to reproduce this logic from MooX::Press to find out
1185             # the name of the type library.
1186             #
1187 26         348 require MooX::Press;
1188 26 100       148 $opts{prefix} = $opts{caller} unless exists $opts{prefix};
1189 26 50       94 $opts{factory_package} = $opts{prefix} unless exists $opts{factory_package};
1190 26 50       163 $opts{type_library} = 'Types' unless exists $opts{type_library};
1191 26         151 $opts{type_library} = 'MooX::Press'->qualify_name($opts{type_library}, $opts{prefix});
1192            
1193             # Optionally export wrapper subs for pre-declared types
1194             #
1195 26 50       542 if ($opts{declare}) {
1196 0         0 my $types = $opts{type_library};
1197 0         0 for my $name (@{ $opts{declare} }) {
  0         0  
1198 0 0       0 eval qq{
1199             sub $caller\::$name () { goto \\&$types\::$name }
1200             sub $caller\::is_$name (\$) { goto \\&$types\::is_$name }
1201             sub $caller\::assert_$name (\$) { goto \\&$types\::assert_$name }
1202             1;
1203             } or die($@);
1204             }
1205             }
1206            
1207             # Export utility stuff
1208             #
1209 26         238 MooX::Pression::_Gather->import::into($caller, -gather => %opts);
1210 26         347 MooX::Press::Keywords->import::into($caller, qw( -booleans -privacy -util )); # imports strict and warnings
1211 26         54664 Syntax::Keyword::Try->import::into($caller);
1212 26 50       5011 if ($] >= 5.018) {
    0          
1213 26         168 feature->import::into($caller, qw( say state unicode_strings unicode_eval evalbytes current_sub fc ));
1214             }
1215             elsif ($] >= 5.014) {
1216 0         0 feature->import::into($caller, qw( say state unicode_strings ));
1217             }
1218             $_->import::into($caller, qw( -types -is -assert ))
1219 26         6305 for qw(Types::Standard Types::Common::Numeric Types::Common::String);
1220            
1221             # `include` keyword
1222             #
1223             Keyword::Simple::define include => sub {
1224 2     2   5 my $ref = shift;
1225            
1226 2 50       7 $$ref =~ _fetch_re('MxpIncludeSyntax', anchor => 'start') or $me->_syntax_error(
1227             'include directive',
1228             'include <name>',
1229             $ref,
1230             );
1231            
1232 2         26 my ($pos, $name) = ($+[0], $+{name});
1233 2         22 my $qualified = 'MooX::Press'->qualify_name($name, $opts{prefix});
1234 2         190 substr($$ref, 0, $pos) = sprintf('BEGIN { eval(q[%s]->_include(%s)) or die($@) };', $me, B::perlstring($qualified));
1235 26         479894 };
1236              
1237             # `class` keyword
1238             #
1239             Keyword::Simple::define class => sub {
1240 58     58   5686 my $ref = shift;
1241            
1242 58 50       289 $$ref =~ _fetch_re('MxpClassSyntax', anchor => 'start') or $me->_syntax_error(
1243             'class declaration',
1244             'class <name> (<signature>) { <block> }',
1245             'class <name> { <block> }',
1246             'class <name>',
1247             'class (<signature>) { <block> }',
1248             'class { <block> }',
1249             'class;',
1250             $ref,
1251             );
1252            
1253 58         70591 my ($pos, $plus, $name, $sig, $block) = ($+[0], $+{plus}, $+{name}, $+{sig}, $+{block});
1254 58         338 my $has_sig = !!exists $+{sig};
1255 58   100     315 $plus ||= '';
1256 58   100     165 $block ||= '{}';
1257            
1258 58         274 substr($$ref, 0, $pos) = $me->_handle_package_keyword(class => $name, $block, $has_sig, $sig, $plus, \%opts);
1259 26         739 };
1260              
1261             Keyword::Simple::define abstract => sub {
1262 1     1   290 my $ref = shift;
1263            
1264 1 50       7 $$ref =~ _fetch_re('MxpAbstractSyntax', anchor => 'start') or $me->_syntax_error(
1265             'abstract class declaration',
1266             'abstract class <name> (<signature>) { <block> }',
1267             'abstract class <name> { <block> }',
1268             'abstract class <name>',
1269             'abstract class (<signature>) { <block> }',
1270             'abstract class { <block> }',
1271             'abstract class;',
1272             $ref,
1273             );
1274            
1275 1         17 my ($pos, $plus, $name, $sig, $block) = ($+[0], $+{plus}, $+{name}, $+{sig}, $+{block});
1276 1         6 my $has_sig = !!exists $+{sig};
1277 1   50     6 $plus ||= '';
1278 1   50     4 $block ||= '{}';
1279            
1280 1         4 substr($$ref, 0, $pos) = $me->_handle_package_keyword(abstract => $name, $block, $has_sig, $sig, $plus, \%opts);
1281 26         483 };
1282              
1283 26         382 for my $kw (qw/ role interface /) {
1284             Keyword::Simple::define $kw => sub {
1285 7     7   1397 my $ref = shift;
1286            
1287 7 50       29 $$ref =~ _fetch_re('MxpRoleSyntax', anchor => 'start') or $me->_syntax_error(
1288             "$kw declaration",
1289             "$kw <name> (<signature>) { <block> }",
1290             "$kw <name> { <block> }",
1291             "$kw <name>",
1292             "$kw (<signature>) { <block> }",
1293             "$kw { <block> }",
1294             "$kw;",
1295             $ref,
1296             );
1297            
1298 7         6136 my ($pos, $name, $sig, $block) = ($+[0], $+{name}, $+{sig}, $+{block});
1299 7         40 my $has_sig = !!exists $+{sig};
1300 7   50     25 $block ||= '{}';
1301            
1302 7         33 substr($$ref, 0, $pos) = $me->_handle_package_keyword($kw => $name, $block, $has_sig, $sig, '', \%opts);
1303 52         541 };
1304             }
1305              
1306             Keyword::Simple::define toolkit => sub {
1307 0     0   0 my $ref = shift;
1308            
1309 0 0       0 $$ref =~ _fetch_re('MxpToolkitSyntax', anchor => 'start') or $me->_syntax_error(
1310             'toolkit declaration',
1311             'toolkit <toolkit> (<extensions>)',
1312             'toolkit <toolkit>;',
1313             $ref,
1314             );
1315            
1316 0         0 my ($pos, $name, $imports) = ($+[0], $+{name}, $+{imports});
1317            
1318 0 0       0 if ($imports) {
1319 0         0 my @imports = grep defined,
1320             ($imports =~ / ((?&PerlQualifiedIdentifier)|(?&PerlComma)) $GRAMMAR /xg);
1321 0         0 my @processed_imports;
1322 0         0 while (@imports) {
1323 20     20   137 no warnings 'uninitialized';
  20         37  
  20         56692  
1324 0         0 my $next = shift @imports;
1325 0 0       0 if ($next =~ /^::(.+)$/) {
    0          
1326 0         0 push @processed_imports, $1;
1327             }
1328             elsif ($next =~ /^[^\W0-9]/) {
1329 0         0 push @processed_imports, sprintf('%sX::%s', $name, $next);
1330             }
1331             else {
1332 0         0 die "Expected package name, got $next";
1333             }
1334 0 0       0 $imports[0] eq ',' and shift @imports;
1335             }
1336 0         0 substr($$ref, 0, $pos) = sprintf('q[%s]->_toolkit(%s);', $me, join ",", map(B::perlstring($_), $name, @processed_imports));
1337             }
1338            
1339             else {
1340 0         0 substr($$ref, 0, $pos) = sprintf('q[%s]->_toolkit(%s);', $me, B::perlstring($name));
1341             }
1342 26         489 };
1343              
1344             # `begin` and `end` keywords
1345             #
1346 26         368 for my $kw (qw/ begin end /) {
1347             Keyword::Simple::define $kw => sub {
1348 0     0   0 my $ref = shift;
1349            
1350 0 0       0 $$ref =~ _fetch_re('MxpHookSyntax', anchor => 'start') or $me->_syntax_error(
1351             "$kw hook",
1352             "$kw { <block> }",
1353             $ref,
1354             );
1355            
1356 0         0 my ($pos, $capture) = ($+[0], $+{hook});
1357 0         0 substr($$ref, 0, $pos) = sprintf('q[%s]->_begin(sub { my ($package, $kind) = (shift, @_); do %s });', $me, $capture);
1358 52         555 };
1359             }
1360            
1361             # `type_name` keyword
1362             #
1363             Keyword::Simple::define type_name => sub {
1364 1     1   2 my $ref = shift;
1365            
1366 1 50       4 $$ref =~ _fetch_re('MxpTypeNameSyntax', anchor => 'start') or $me->_syntax_error(
1367             'type name declaration',
1368             'type_name <identifier>',
1369             $ref,
1370             );
1371            
1372 1         14 my ($pos, $capture) = ($+[0], $+{name});
1373 1         62 substr($$ref, 0, $pos) = sprintf('q[%s]->_type_name(%s);', $me, B::perlstring($capture));
1374 26         469 };
1375            
1376             # `extends` keyword
1377             #
1378             Keyword::Simple::define extends => sub {
1379 7     7   25 my $ref = shift;
1380            
1381 7 50       42 $$ref =~ _fetch_re('MxpExtendsSyntax', anchor => 'start') or $me->_syntax_error(
1382             'extends declaration',
1383             'extends <classes>',
1384             $ref,
1385             );
1386            
1387 7         286 my ($pos, $capture) = ($+[0], $+{list});
1388 7         71 substr($$ref, 0, $pos) = sprintf('q[%s]->_extends(%s);', $me, $me->_handle_role_list($capture, 'class'));
1389 26         461 };
1390            
1391             # `with` keyword
1392             #
1393             Keyword::Simple::define with => sub {
1394 7     7   23 my $ref = shift;
1395            
1396 7 50       21 $$ref =~ _fetch_re('MxpWithSyntax', anchor => 'start') or $me->_syntax_error(
1397             'with declaration',
1398             'with <roles>',
1399             $ref,
1400             );
1401            
1402 7         161 my ($pos, $capture) = ($+[0], $+{list});
1403            
1404 7         57 substr($$ref, 0, $pos) = sprintf('q[%s]->_with(%s);', $me, $me->_handle_role_list($capture, 'role'));
1405 26         488 };
1406            
1407             # `requires` keyword
1408             #
1409             Keyword::Simple::define requires => sub {
1410 3     3   8 my $ref = shift;
1411            
1412 3 50       10 $$ref =~ _fetch_re('MxpRequiresSyntax', anchor => 'start') or $me->_syntax_error(
1413             'requires declaration',
1414             'requires <name> (<signature>)',
1415             'requires <name>',
1416             $ref,
1417             );
1418            
1419 3         36 my ($pos, $name, $sig) = ($+[0], $+{name}, $+{sig});
1420 3         16 my $has_sig = !!exists $+{sig};
1421 3         49 substr($$ref, 0, $pos) = $me->_handle_requires_keyword($name, $has_sig, $sig)
1422 26         471 };
1423            
1424             # `has` keyword
1425             #
1426             Keyword::Simple::define has => sub {
1427 26     26   79 my $ref = shift;
1428            
1429 26 50       129 $$ref =~ _fetch_re('MxpHasSyntax', anchor => 'start') or $me->_syntax_error(
1430             'attribute declaration',
1431             'has <name> (<spec>) = <default>',
1432             'has <name> (<spec>)',
1433             'has <name> = <default>',
1434             'has <name>',
1435             $ref,
1436             );
1437            
1438 26         1135 my ($pos, $name, $spec, $default) = ($+[0], $+{name}, $+{spec}, $+{default});
1439 26         152 my $has_spec = !!exists $+{spec};
1440 26         99 my $has_default = !!exists $+{default};
1441 26 100       253 substr($$ref, 0, $pos) = $me->_handle_has_keyword($name, $has_spec ? $spec : undef, $has_default ? $default : undef);
    100          
1442 26         467 };
1443            
1444             # `constant` keyword
1445             #
1446             Keyword::Simple::define constant => sub {
1447 6     6   20 my $ref = shift;
1448            
1449 6 50       27 $$ref =~ _fetch_re('MxpConstantSyntax', anchor => 'start') or $me->_syntax_error(
1450             'constant declaration',
1451             'constant <name> = <value>',
1452             $ref,
1453             );
1454            
1455 6         69 my ($pos, $name, $expr) = ($+[0], $+{name}, $+{expr});
1456 6         361 substr($$ref, 0, $pos) = sprintf('q[%s]->_constant(%s, %s);', $me, B::perlstring($name), $expr);
1457 26         485 };
1458            
1459             # `method` keyword
1460             #
1461             Keyword::Simple::define method => sub {
1462 13     13   44 my $ref = shift;
1463            
1464 13         45 state $re_attr = _fetch_re('MxpAttribute');
1465            
1466 13 50       85 $$ref =~ _fetch_re('MxpMethodSyntax', anchor => 'start') or $me->_syntax_error(
1467             'method declaration',
1468             'method <name> <attributes> (<signature>) { <block> }',
1469             'method <name> (<signature>) { <block> }',
1470             'method <name> <attributes> { <block> }',
1471             'method <name> { <block> }',
1472             'method <attributes> (<signature>) { <block> }',
1473             'method (<signature>) { <block> }',
1474             'method <attributes> { <block> }',
1475             'method { <block> }',
1476             $ref,
1477             );
1478            
1479 13         15705 my ($pos, $name, $attributes, $sig, $code) = ($+[0], $+{name}, $+{attributes}, $+{sig}, $+{code});
1480 13         84 my $has_sig = !!exists $+{sig};
1481 13 100       32068 my @attrs = $attributes ? grep(defined, ( ($attributes) =~ /($re_attr)/xg )) : ();
1482            
1483 13         177 substr($$ref, 0, $pos) = $me->_handle_method_keyword($name, $code, $has_sig, $sig, \@attrs);
1484 26         488 };
1485              
1486             # `multi` keyword
1487             #
1488             Keyword::Simple::define multi => sub {
1489 0     0   0 my $ref = shift;
1490            
1491 0         0 state $re_attr = _fetch_re('MxpAttribute');
1492            
1493 0 0       0 $$ref =~ _fetch_re('MxpMultiSyntax', anchor => 'start') or $me->_syntax_error(
1494             'multimethod declaration',
1495             'multi method <name> <attributes> (<signature>) { <block> }',
1496             'multi method <name> (<signature>) { <block> }',
1497             'multi method <name> <attributes> { <block> }',
1498             'multi method <name> { <block> }',
1499             $ref,
1500             );
1501            
1502 0         0 my ($pos, $name, $attributes, $sig, $code) = ($+[0], $+{name}, $+{attributes}, $+{sig}, $+{code});
1503 0         0 my $has_sig = !!exists $+{sig};
1504 0 0       0 my @attrs = $attributes ? grep(defined, ( ($attributes) =~ /($re_attr)/xg )) : ();
1505            
1506 0         0 substr($$ref, 0, $pos) = $me->_handle_multimethod_keyword($name, $code, $has_sig, $sig, \@attrs);
1507 26         529 };
1508              
1509             # `before`, `after`, and `around` keywords
1510             #
1511 26         446 for my $kw (qw( before after around )) {
1512             Keyword::Simple::define $kw => sub {
1513 2     2   7 my $ref = shift;
1514            
1515 2         17 state $re_attr = _fetch_re('MxpAttribute');
1516            
1517 2 50       7 $$ref =~ _fetch_re('MxpModifierSyntax', anchor => 'start') or $me->_syntax_error(
1518             "$kw method modifier declaration",
1519             "$kw <name> <attributes> (<signature>) { <block> }",
1520             "$kw <name> (<signature>) { <block> }",
1521             "$kw <name> <attributes> { <block> }",
1522             "$kw <name> { <block> }",
1523             $ref,
1524             );
1525            
1526 2         1276 my ($pos, $name, $attributes, $sig, $code) = ($+[0], $+{name}, $+{attributes}, $+{sig}, $+{code});
1527 2         14 my $has_sig = !!exists $+{sig};
1528 2 50       10 my @attrs = $attributes ? grep(defined, ( ($attributes) =~ /($re_attr)/xg )) : ();
1529            
1530 2         16 substr($$ref, 0, $pos) = $me->_handle_modifier_keyword($kw, $name, $code, $has_sig, $sig, \@attrs);
1531 78         1139 };
1532             }
1533            
1534             Keyword::Simple::define factory => sub {
1535 2     2   9 my $ref = shift;
1536            
1537 2 50       10 if ( $$ref =~ _fetch_re('MxpFactorySyntax', anchor => 'start') ) {
1538 2         2351 state $re_attr = _fetch_re('MxpAttribute');
1539 2         63 my ($pos, $name, $attributes, $sig, $code) = ($+[0], $+{name}, $+{attributes}, $+{sig}, $+{code});
1540 2         11 my $has_sig = !!exists $+{sig};
1541 2 50       10 my @attrs = $attributes ? grep(defined, ( ($attributes) =~ /($re_attr)/xg )) : ();
1542 2         24 substr($$ref, 0, $pos) = $me->_handle_factory_keyword($name, undef, $code, $has_sig, $sig, \@attrs);
1543 2         326 return;
1544             }
1545            
1546 0 0       0 $$ref =~ _fetch_re('MxpFactoryViaSyntax', anchor => 'start') or $me->_syntax_error(
1547             'factory method declaration',
1548             'factory <name> <attributes> (<signature>) { <block> }',
1549             'factory <name> (<signature>) { <block> }',
1550             'factory <name> <attributes> { <block> }',
1551             'factory <name> { <block> }',
1552             'factory <name> via <methodname>',
1553             'factory <name>',
1554             $ref,
1555             );
1556            
1557 0         0 my ($pos, $name, $via) = ($+[0], $+{name}, $+{via});
1558 0   0     0 $via ||= 'new';
1559 0         0 substr($$ref, 0, $pos) = $me->_handle_factory_keyword($name, $via, undef, undef, undef, []);
1560 26         574 };
1561            
1562             Keyword::Simple::define coerce => sub {
1563 1     1   4 my $ref = shift;
1564            
1565 1 50       3 $$ref =~ _fetch_re('MxpCoerceSyntax', anchor => 'start') or $me->_syntax_error(
1566             'coercion declaration',
1567             'coerce from <type> via <method_name> { <block> }',
1568             'coerce from <type> via <method_name>',
1569             $ref,
1570             );
1571            
1572 1         923 my ($pos, $from, $via, $code) = ($+[0], $+{from}, $+{via}, $+{code});
1573 1 50       12 if ($from =~ /^\{/) {
    50          
1574 0         0 $from = "scalar(do $from)"
1575             }
1576             elsif ($from !~ /^(q\b)|(qq\b)|"|'/) {
1577 1         7 $from = B::perlstring($from);
1578             }
1579 1 50       8 if ($via =~ /^\{/) {
    50          
1580 0         0 $via = "scalar(do $via)"
1581             }
1582             elsif ($via !~ /^(q\b)|(qq\b)|"|'/) {
1583 1         4 $via = B::perlstring($via);
1584             }
1585            
1586 1 50       146 substr($$ref, 0, $pos) = sprintf('q[%s]->_coerce(%s, %s, %s);', $me, $from, $via, $code ? "sub { my \$class; local \$_; (\$class, \$_) = \@_; do $code }" : '');
1587 26         536 };
1588            
1589             # Go!
1590             #
1591             on_scope_end {
1592 20 100   20   136 eval "package $caller; use MooX::Pression::_Gather -go; 1"
  20     26   36  
  20         83  
  26         2383  
1593             or Carp::croak($@);
1594 26         605 };
1595            
1596             # Need this to export `authority` and `version`...
1597 26         498 @_ = ($me);
1598 26         107 goto \&Exporter::Tiny::import;
1599             }
1600              
1601             our %OPTS;
1602              
1603             # `version` keyword
1604             #
1605             sub version {
1606 0     0 1 0 $OPTS{version} = shift;
1607             }
1608              
1609             # `authority` keyword
1610             #
1611             sub authority {
1612 0     0 1 0 $OPTS{authority} = shift;
1613             }
1614              
1615             # `overload` keyword
1616             #
1617             sub overload {
1618 1 50 33 1 1 12 if (@_ == 1 and ref($_[0]) eq 'HASH') {
    50 33        
1619 0   0     0 push @{ $OPTS{overload} ||= [] }, %{+shift};
  0         0  
  0         0  
1620             }
1621             elsif (@_ == 1 and ref($_[0]) eq 'ARRAY') {
1622 0   0     0 push @{ $OPTS{overload} ||= [] }, @{+shift};
  0         0  
  0         0  
1623             }
1624             else {
1625 1   50     2 push @{ $OPTS{overload} ||= [] }, @_;
  1         9  
1626             }
1627             }
1628              
1629             # `MooX::Pression::PACKAGE_SPEC` keyword
1630             #
1631 1     1 1 9 sub PACKAGE_SPEC { \%OPTS }
1632              
1633              
1634             #
1635             # CALLBACKS
1636             #
1637              
1638             sub _package_callback {
1639 67     67   192072 shift;
1640 67         159 my $cb = shift;
1641 67         187 local %OPTS = ();
1642 67         239 &$cb;
1643             # use Data::Dumper;
1644             # $Data::Dumper::Deparse = 1;
1645             # print "OPTS:".Dumper $cb, +{ %OPTS };
1646 67         504 return +{ %OPTS };
1647             }
1648             sub _has {
1649 31     31   205 shift;
1650 31         100 my ($attr, %spec) = @_;
1651 31         113 $OPTS{has}{$attr} = \%spec;
1652             }
1653             sub _extends {
1654 8     8   65 shift;
1655 8   50     22 @{ $OPTS{extends}||=[] } = @_;
  8         71  
1656             }
1657             sub _type_name {
1658 1     1   4 shift;
1659 1         3 $OPTS{type_name} = shift;
1660             }
1661             sub _begin {
1662 0     0   0 shift;
1663 0         0 $OPTS{begin} = shift;
1664             }
1665             sub _end {
1666 0     0   0 shift;
1667 0         0 $OPTS{end} = shift;
1668             }
1669             sub _interface {
1670 0     0   0 shift;
1671 0         0 $OPTS{interface} = shift;
1672             }
1673             sub _abstract {
1674 1     1   3 shift;
1675 1         2 $OPTS{abstract} = shift;
1676             }
1677             sub _with {
1678 7     7   42 shift;
1679 7   50     14 push @{ $OPTS{with}||=[] }, @_;
  7         52  
1680             }
1681             sub _toolkit {
1682 0     0   0 shift;
1683 0         0 my ($toolkit, @imports) = @_;
1684 0         0 $OPTS{toolkit} = $toolkit;
1685 0 0 0     0 push @{ $OPTS{import}||=[] }, @imports if @imports;
  0         0  
1686             }
1687             sub _requires {
1688 3     3   14 shift;
1689 3   100     5 push @{ $OPTS{requires}||=[] }, @_;
  3         24  
1690             }
1691             sub _coerce {
1692 1     1   7 shift;
1693 1   50     2 push @{ $OPTS{coerce}||=[] }, @_;
  1         5  
1694             }
1695             sub _factory {
1696 2     2   21 shift;
1697 2   100     3 push @{ $OPTS{factory}||=[] }, @_;
  2         12  
1698             }
1699             sub _constant {
1700 10     10   66 shift;
1701 10         24 my ($name, $value) = @_;
1702 10         31 $OPTS{constant}{$name} = $value;
1703             }
1704             sub _can {
1705 12     12   574 shift;
1706 12         33 my ($name, $code) = @_;
1707 12         38 $OPTS{can}{$name} = $code;
1708             }
1709             sub _multimethod {
1710 0     0   0 shift;
1711 0         0 my ($name, $spec) = @_;
1712 0   0     0 push @{ $OPTS{multimethod} ||= [] }, $name => $spec;
  0         0  
1713             }
1714             sub _modifier {
1715 4     4   50 shift;
1716 4         14 my ($kind, @args) = @_;
1717 4   50     7 push @{ $OPTS{$kind} ||= [] }, @args;
  4         29  
1718             }
1719             sub _include {
1720 2     2   14 shift;
1721            
1722 2         500 require Path::ScanINC;
1723 2         13081 my @chunks = split /::/, $_[0];
1724 2         5 $chunks[-1] .= '.pl';
1725 2         16 my $file = Path::ScanINC->new->first_file(@chunks);
1726            
1727 2 50       457 ref $file eq 'ARRAY' and die "not supported yet";
1728 2         32 my $code = $file->slurp_utf8;
1729            
1730 2         1071 sprintf(
1731             "do {\n# line 1 %s\n%s\n};\n1;\n",
1732             B::perlstring($file),
1733             $code,
1734             );
1735             }
1736              
1737             #{
1738             # package MooX::Pression::Anonymous::Package;
1739             # our $AUTHORITY = 'cpan:TOBYINK';
1740             # our $VERSION = '0.301';
1741             # use overload q[""] => sub { ${$_[0]} }, fallback => 1;
1742             # sub DESTROY {}
1743             # sub AUTOLOAD {
1744             # my $me = shift;
1745             # (my $method = our $AUTOLOAD) =~ s/.*:://;
1746             # $$me->$method(@_);
1747             # }
1748             #
1749             # package MooX::Pression::Anonymous::Class;
1750             # our $AUTHORITY = 'cpan:TOBYINK';
1751             # our $VERSION = '0.301';
1752             # our @ISA = qw(MooX::Pression::Anonymous::Package);
1753             # sub new {
1754             # my $me = shift;
1755             # $$me->new(@_);
1756             # }
1757             # use overload q[&{}] => sub {
1758             # my $me = shift;
1759             # sub { $me->new(@_) }
1760             # };
1761             #
1762             # package MooX::Pression::Anonymous::Role;
1763             # our $AUTHORITY = 'cpan:TOBYINK';
1764             # our $VERSION = '0.301';
1765             # our @ISA = qw(MooX::Pression::Anonymous::Package);
1766             #
1767             # package MooX::Pression::Anonymous::ParameterizableClass;
1768             # our $AUTHORITY = 'cpan:TOBYINK';
1769             # our $VERSION = '0.301';
1770             # our @ISA = qw(MooX::Pression::Anonymous::Package);
1771             # sub generate_package {
1772             # my $me = shift;
1773             # my $gen = $$me->generate_package(@_);
1774             # bless \$gen, 'MooX::Pression::Anonymous::Class';
1775             # }
1776             # use overload q[&{}] => sub {
1777             # my $me = shift;
1778             # sub { $me->new_class(@_) }
1779             # };
1780             #
1781             # package MooX::Pression::Anonymous::ParameterizableRole;
1782             # our $AUTHORITY = 'cpan:TOBYINK';
1783             # our $VERSION = '0.301';
1784             # our @ISA = qw(MooX::Pression::Anonymous::Package);
1785             # sub generate_package {
1786             # my $me = shift;
1787             # my $gen = $$me->generate_package(@_);
1788             # bless \$gen, 'MooX::Pression::Anonymous::Class';
1789             # }
1790             # use overload q[&{}] => sub {
1791             # my $me = shift;
1792             # sub { $me->new_role(@_) }
1793             # };
1794             #}
1795              
1796             my $i = 0;
1797             sub anonymous_package {
1798 4     4 0 35689 my $me = shift;
1799 4         25 my ($kind, $callback, %opts) = @_;
1800 4         13 my $package_dfn = $me->_package_callback($callback);
1801            
1802 4         10 for my $forbidden (qw/ factory type_name coerce /) {
1803 12 50       28 die if exists $package_dfn->{$forbidden};
1804             }
1805 4         11 $package_dfn->{type_name} = undef;
1806 4         7 $package_dfn->{factory} = undef;
1807            
1808 4         21 my $qname = sprintf('%s::__ANON_%06d__', __PACKAGE__, ++$i);
1809            
1810 4         20 require MooX::Press;
1811 4         10 my $method = "make_$kind";
1812 4         36 MooX::Press->$method("::$qname", %opts, %$package_dfn);
1813            
1814 4         17710 require Module::Runtime;
1815 4         17 $INC{Module::Runtime::module_notional_filename($qname)} = __FILE__;
1816             #return bless(\$qname, "MooX::Pression::Anonymous::".ucfirst($kind));
1817 4         94 return $qname;
1818             }
1819              
1820             sub anonymous_generator {
1821 1     1 0 19 my $me = shift;
1822 1         6 my ($kind, $callback, %opts) = @_;
1823 1         5 my $qname = sprintf('%s::__ANON_%06d__', __PACKAGE__, ++$i);
1824            
1825 1         4 require MooX::Press;
1826 1         3 my $method = "make_$kind\_generator";
1827 1         8 MooX::Press->$method("::$qname", %opts, generator => $callback);
1828            
1829 1         480 require Module::Runtime;
1830 1         5 $INC{Module::Runtime::module_notional_filename($qname)} = __FILE__;
1831             #return bless(\$qname, "MooX::Pression::Anonymous::Parameterizable".ucfirst($kind));
1832 1         25 return $qname;
1833             }
1834              
1835             1;
1836              
1837             __END__
1838              
1839             =pod
1840              
1841             =encoding utf-8
1842              
1843             =head1 NAME
1844              
1845             MooX::Pression - express yourself through moo
1846              
1847             =head1 SYNOPSIS
1848              
1849             MyApp.pm
1850              
1851             use v5.18;
1852             use strict;
1853             use warnings;
1854            
1855             package MyApp {
1856             use MooX::Pression;
1857            
1858             class Person {
1859             has name ( type => Str, required => true );
1860             has gender ( type => Str );
1861            
1862             factory new_man (Str $name) {
1863             return $class->new(name => $name, gender => 'male');
1864             }
1865            
1866             factory new_woman (Str $name) {
1867             return $class->new(name => $name, gender => 'female');
1868             }
1869            
1870             method greet (Person *friend, Str *greeting = "Hello") {
1871             printf("%s, %s!\n", $arg->greeting, $arg->friend->name);
1872             }
1873            
1874             coerce from Str via from_string {
1875             return $class->new(name => $_);
1876             }
1877             }
1878             }
1879              
1880             my_script.pl
1881              
1882             use v5.18;
1883             use strict;
1884             use warnings;
1885             use MyApp;
1886             use MyApp::Types qw( is_Person );
1887            
1888             # Create a new MyApp::Person object.
1889             #
1890             my $alice = MyApp->new_woman("Alice");
1891             is_Person($alice) or die;
1892            
1893             # The string "Bob" will be coerced to a MyApp::Person.
1894             #
1895             $alice->greet(friend => "Bob", greeting => 'Hi');
1896              
1897             =head1 DESCRIPTION
1898              
1899             L<MooX::Pression> is kind of like L<Moops>; a marrying together of L<Moo>
1900             with L<Type::Tiny> and some keyword declaration magic. Instead of being
1901             built on L<Kavorka>, L<Parse::Keyword>, L<Keyword::Simple> and a whole
1902             heap of crack, it is built on L<MooX::Press>, L<Keyword::Simple>, and L<PPR>.
1903             I'm not saying there isn't some crazy stuff going on under the hood, but
1904             it ought to be a little more maintainable.
1905              
1906             Some of the insane features of Moops have been dialled back, and others
1907             have been amped up.
1908              
1909             It's more opinionated about API design and usage than Moops is, but in
1910             most cases, it should be fairly easy to port Moops code to MooX::Pression.
1911              
1912             MooX::Pression requires Perl 5.18.0 or above. It may work on Perl 5.14.x
1913             and Perl 5.16.x partly, but there are likely to be issues.
1914              
1915             L<MooX::Press> is a less magic version of MooX::Pression and only requires
1916             Perl 5.8.8 or above.
1917              
1918             =head2 Important Concepts
1919              
1920             =head3 The Factory Package and Prefix
1921              
1922             MooX::Pression assumes that all the classes and roles you are building
1923             with it will be defined under the same namespace B<prefix>. For example
1924             "MyApp::Person" and "MyApp::Company" are both defined under the common
1925             prefix of "MyApp".
1926              
1927             It also assumes there will be a B<< factory package >> that can be used
1928             to build new instances of your class. Rather than creating a new person
1929             object with C<< MyApp::Person->new() >>, you should create a new person
1930             object with C<< MyApp->new_person() >>. Calling C<< MyApp::Person->new() >>
1931             directly is only encouraged from within the "MyApp::Person" class itself,
1932             and from within the factory. Everywhere else, you should call
1933             C<< MyApp->new_person() >> instead.
1934              
1935             By default, the factory package and the prefix are the same: they are
1936             the caller that you imported MooX::Pression into. But they can be set
1937             to whatever:
1938              
1939             use MooX::Pression (
1940             prefix => 'MyApp::Objects',
1941             factory_package => 'MyApp::Makers',
1942             );
1943              
1944             MooX::Pression assumes that you are defining all the classes and roles
1945             within this namespace prefix in a single Perl module file. This Perl
1946             module file would normally be named based on the prefix, so in the
1947             example above, it would be "MyApp/Objects.pm" and in the example from
1948             the SYNOPSIS, it would be "MyApp.pm".
1949              
1950             But see also the documentation for C<include>.
1951              
1952             Of course, there is nothing to stop you from having multiple prefixes
1953             for different logical parts of a larger codebase, but MooX::Pression
1954             assumes that if it's been set up for a prefix, it owns that prefix and
1955             everything under it, and it's all defined in the same Perl module.
1956              
1957             Each object defined by MooX::Pression will have a C<FACTORY> method,
1958             so you can do:
1959              
1960             $person_object->FACTORY
1961              
1962             And it will return the string "MyApp". This allows for stuff like:
1963              
1964             class Person {
1965             method give_birth {
1966             return $self->FACTORY->new_person();
1967             }
1968             }
1969              
1970             =head3 The Type Library
1971              
1972             While building your classes and objects, MooX::Pression will also build
1973             type constraints for each of them. So for the "MyApp::Person" class
1974             above, it also builds a B<Person> type constraint. This can be used
1975             in Moo/Moose attribute definitions like:
1976              
1977             use MyApp;
1978             use MyApp::Types qw( Person );
1979            
1980             use Moose;
1981             has boss => (is => 'rw', isa => Person);
1982              
1983             And just anywhere a type constraint may be used generally. You should
1984             know this stuff by now.
1985              
1986             Note that we had to C<use MyApp> before we could C<use MyApp::Types>.
1987             This is because there isn't a physical "MyApp/Types.pm" file on disk;
1988             it is defined entirely by "MyApp.pm".
1989              
1990             Your type library will be the same as your namespace prefix, with
1991             "::Types" added at the end. But you can change that:
1992              
1993             use MooX::Pression (
1994             prefix => 'MyApp::Objects',
1995             factory_package => 'MyApp::Makers',
1996             type_library => 'MyApp::TypeLibrary',
1997             );
1998              
1999             It can sometimes be helpful to pre-warn MooX::Pression about the
2000             types you're going to define before you define them, just so it
2001             is able to allow them as barewords in some places...
2002              
2003             use MooX::Pression (
2004             prefix => 'MyApp::Objects',
2005             factory_package => 'MyApp::Makers',
2006             type_library => 'MyApp::TypeLibrary',
2007             declare => [qw( Person Company )],
2008             );
2009              
2010             See also L<Type::Tiny::Manual>.
2011              
2012             =head2 Keywords
2013              
2014             =head3 C<< class >>
2015              
2016             Define a very basic class:
2017              
2018             class Person;
2019              
2020             Define a more complicated class:
2021              
2022             class Person {
2023             ...;
2024             }
2025              
2026             Note that for the C<class> keyword without a block, it does I<not> act like
2027             the C<package> keyword by changing the "ambient" package. It just defines a
2028             totally empty class with no methods or attributes.
2029              
2030             The prefix will automatically be added to the class name, so if the prefix
2031             is MyApp, the above will create a class called MyApp::Person. It will also
2032             create a factory method C<< MyApp->new_person >>. (The name is generated by
2033             stripping the prefix from the class name, replacing any "::" with an
2034             underscore, lowercasing, and prefixing it with "new_".) And it will create
2035             a type called B<Person> in the type library. (Same rules to generate the
2036             name apart from lowercasing and adding "new_".)
2037              
2038             Classes can be given more complex names:
2039              
2040             class Person::Neanderthal {
2041             ...;
2042             }
2043              
2044             Will create "MyApp::Person::Neanderthal" class, a factory method called
2045             C<< MyApp->new_person_neanderthal >>, and a B<Person_Neanderthal> type.
2046              
2047             It is possible to create a class without the prefix:
2048              
2049             class ::Person {
2050             ...;
2051             }
2052              
2053             The class name will now be "Person" instead of "MyApp::Person"!
2054              
2055             =head4 Nested classes
2056              
2057             C<class> blocks can be nested. This establishes an inheritance heirarchy.
2058              
2059             class Animal {
2060             has name;
2061             class Mammal {
2062             class Primate {
2063             class Monkey;
2064             class Gorilla;
2065             class Human {
2066             class Superhuman;
2067             }
2068             }
2069             }
2070             class Bird;
2071             class Fish {
2072             class Shark;
2073             }
2074             }
2075            
2076             my $superman = MyApp->new_superhuman( name => 'Kal El' );
2077              
2078             See also C<extends> as an alternative way of declaring inheritance.
2079              
2080             It is possible to prefix a class name with a plus sign:
2081              
2082             package MyApp {
2083             use MooX::Pression;
2084             class Person {
2085             has name;
2086             class +Employee {
2087             has job_title;
2088             }
2089             }
2090             }
2091              
2092             Now the employee class will be named C<MyApp::Person::Employee> instead of
2093             the usual C<MyApp::Employee>.
2094              
2095             Classes can be declared as abstract:
2096              
2097             package MyApp {
2098             use MooX::Pression;
2099             abstract class Animal {
2100             class Cat;
2101             class Dog;
2102             }
2103             }
2104              
2105             For abstract classes, there is no constructor or factory, so you cannot create
2106             an Animal instance directly; but you can create instances of the subclasses.
2107             It is usually better to use roles than abstract classes, but sometimes the
2108             abstract class makes more intuitive sense.
2109              
2110             =head3 C<< role >>
2111              
2112             Define a very basic role:
2113              
2114             role Person;
2115              
2116             Define a more complicated role:
2117              
2118             role Person {
2119             ...;
2120             }
2121              
2122             This is just the same as C<class> but defines a role instead of a class.
2123              
2124             Roles cannot be nested within each other, nor can roles be nested in classes,
2125             nor classes in roles.
2126              
2127             =head3 C<< interface >>
2128              
2129             An interface is a lightweight role. It cannot define attributes, methods,
2130             multimethods, or method modifiers, but otherwise functions as a role.
2131             (It may have C<requires> statements and define constants.)
2132              
2133             package MyApp;
2134             use MooX::Pression;
2135            
2136             interface Serializer {
2137             requires serialize;
2138             }
2139            
2140             interface Deserializer {
2141             requires deserialize;
2142             }
2143            
2144             class MyJSON {
2145             with Serializer, Deserialize;
2146             method serialize ($value) { ... }
2147             method deserialize ($value) { ... }
2148             }
2149            
2150             my $obj = MyApp->new_myjson;
2151             $obj->does('MyApp::Serializer'); # true
2152              
2153             =head3 C<< toolkit >>
2154              
2155             Use a different toolkit instead of Moo.
2156              
2157             # use Mouse
2158             class Foo {
2159             toolkit Mouse;
2160             }
2161            
2162             # use Moose
2163             # use MooseX::Aliases
2164             # use MooseX::StrictConstructor
2165             class Bar {
2166             toolkit Moose ( Aliases, StrictConstructor );
2167             }
2168              
2169             You can of course specify you want to use Moo:
2170              
2171             class Baz {
2172             toolkit Moo;
2173             }
2174              
2175             Not all MooseX/MouseX/MooX packages will work, but *X::StrictConstructor will.
2176              
2177             It is possible to set a default toolkit when you import MooX::Pression.
2178              
2179             use MooX::Pression (
2180             ...,
2181             toolkit => 'Moose',
2182             );
2183              
2184             use MooX::Pression (
2185             ...,
2186             toolkit => 'Mouse',
2187             );
2188              
2189             =head3 C<< extends >>
2190              
2191             Defines a parent class. Only for use within C<class> blocks.
2192              
2193             class Person {
2194             extends Animal;
2195             }
2196              
2197             This works:
2198              
2199             class Person {
2200             extends ::Animal; # no prefix
2201             }
2202              
2203             =head3 C<< with >>
2204              
2205             Composes roles.
2206              
2207             class Person {
2208             with Employable, Consumer;
2209             }
2210            
2211             role Consumer;
2212            
2213             role Worker;
2214            
2215             role Payable;
2216            
2217             role Employable {
2218             with Worker, Payable;
2219             }
2220              
2221             Because roles are processed before classes, you can compose roles into classes
2222             where the role is defined later in the file. But if you compose one role into
2223             another, you must define them in a sensible order.
2224              
2225             It is possible to compose a role that does not exist by adding a question mark
2226             to the end of it:
2227              
2228             class Person {
2229             with Employable, Consumer?;
2230             }
2231            
2232             role Employable {
2233             with Worker?, Payable?;
2234             }
2235              
2236             This is equivalent to declaring an empty role.
2237              
2238             =head3 C<< begin >>
2239              
2240             This code gets run early on in the definition of a class or role.
2241              
2242             class Person {
2243             begin {
2244             say "Defining $package";
2245             }
2246             }
2247              
2248             At the time the code gets run, none of the class's attributes or methods will
2249             be defined yet.
2250              
2251             The lexical variables C<< $package >> and C<< $kind >> are defined within the
2252             block. C<< $kind >> will be either 'class' or 'role'.
2253              
2254             It is possible to define a global chunk of code to run too:
2255              
2256             use MooX::Pression (
2257             ...,
2258             begin => sub {
2259             my ($package, $kind) = @_;
2260             ...;
2261             },
2262             );
2263              
2264             Per-package C<begin> overrides the global C<begin>.
2265              
2266             Unlike Perl's C<BEGIN> keyword, a package can only have one C<begin>.
2267              
2268             If C<class> definitions are nested, C<begin> blocks will be inherited by
2269             child classes. If a parent class is specified via C<extends>, C<begin>
2270             blocks will not be inherited.
2271              
2272             =head3 C<< end >>
2273              
2274             This code gets run late in the definition of a class or role.
2275              
2276             class Person {
2277             end {
2278             say "Finished defining $package";
2279             }
2280             }
2281              
2282             The lexical variables C<< $package >> and C<< $kind >> are defined within the
2283             block. C<< $kind >> will be either 'class' or 'role'.
2284              
2285             It is possible to define a global chunk of code to run too:
2286              
2287             use MooX::Pression (
2288             ...,
2289             end => sub {
2290             my ($package, $kind) = @_;
2291             ...;
2292             },
2293             );
2294              
2295             Per-package C<end> overrides the global C<end>.
2296              
2297             Unlike Perl's C<END> keyword, a package can only have one C<end>.
2298              
2299             If C<class> definitions are nested, C<end> blocks will be inherited by
2300             child classes. If a parent class is specified via C<extends>, C<end>
2301             blocks will not be inherited.
2302              
2303             =head3 C<< has >>
2304              
2305             class Person {
2306             has name;
2307             has age;
2308             }
2309            
2310             my $bob = MyApp->new_person(name => "Bob", age => 21);
2311              
2312             Moo-style attribute specifications may be given:
2313              
2314             class Person {
2315             has name ( is => rw, type => Str, required => true );
2316             has age ( is => rw, type => Int );
2317             }
2318              
2319             Note there is no fat comma after the attribute name! It is a bareword.
2320              
2321             Use a plus sign before an attribute name to modify an attribute defined
2322             in a parent class.
2323              
2324             class Animal {
2325             has name ( type => Str, required => false );
2326            
2327             class Person {
2328             has +name ( required => true );
2329             }
2330             }
2331              
2332             C<rw>, C<rwp>, C<ro>, C<lazy>, C<true>, and C<false> are allowed as
2333             barewords for readability, but C<is> is optional, and defaults to C<rw>.
2334              
2335             Note C<type> instead of C<isa>. Any type constraints from L<Types::Standard>,
2336             L<Types::Common::Numeric>, and L<Types::Common::String> will be avaiable as
2337             barewords. Also, any pre-declared types can be used as barewords. It's
2338             possible to quote types as strings, in which case you don't need to have
2339             pre-declared them.
2340              
2341             class Person {
2342             has name ( type => Str, required => true );
2343             has age ( type => Int );
2344             has spouse ( type => 'Person' );
2345             has kids (
2346             is => lazy,
2347             type => 'ArrayRef[Person]',
2348             builder => sub { [] },
2349             );
2350             }
2351              
2352             Note that when C<type> is a string, MooX::Pression will consult your
2353             type library to figure out what it means.
2354              
2355             It is also possible to use C<< isa => 'SomeClass' >> or
2356             C<< does => 'SomeRole' >> to force strings to be treated as class names
2357             or role names instead of type names.
2358              
2359             class Person {
2360             has name ( type => Str, required => true );
2361             has age ( type => Int );
2362             has spouse ( isa => 'Person' );
2363             has pet ( isa => '::Animal' ); # no prefix
2364             }
2365              
2366             For enumerations, you can define them like this:
2367              
2368             class Person {
2369             ...;
2370             has status ( enum => ['alive', 'dead', 'undead'] );
2371             }
2372              
2373             MooX::Pression integrates support for L<MooX::Enumeration> (and
2374             L<MooseX::Enumeration>, but MouseX::Enumeration doesn't exist).
2375              
2376             class Person {
2377             ...;
2378             has status (
2379             enum => ['alive', 'dead', 'undead'],
2380             default => 'alive',
2381             handles => 1,
2382             );
2383             }
2384            
2385             my $bob = MyApp->new_person;
2386             if ( $bob->is_alive ) {
2387             ...;
2388             }
2389              
2390             C<< handles => 1 >> creates methods named C<is_alive>, C<is_dead>, and
2391             C<is_undead>, and C<< handles => 2 >> creates methods named
2392             C<status_is_alive>, C<status_is_dead>, and C<status_is_undead>.
2393              
2394             Checking C<< $bob->status eq 'alvie' >> is prone to typos, but
2395             C<< $bob->status_is_alvie >> will cause a runtime error because the
2396             method is not defined.
2397              
2398             MooX::Pression also integrates support for L<Sub::HandlesVia> allowing
2399             you to delegate certain methods to unblessed references and non-reference
2400             values. For example:
2401              
2402             class Person {
2403             has age (
2404             type => 'Int',
2405             default => 0,
2406             handles_via => 'Counter',
2407             handles => {
2408             birthday => 'inc', # increment age
2409             },
2410             );
2411             after birthday {
2412             if ($self->age < 30) {
2413             say "yay!";
2414             }
2415             else {
2416             say "urgh!";
2417             }
2418             }
2419             }
2420              
2421             A trailing C<< ! >> indicates a required attribute.
2422              
2423             class Person {
2424             has name!;
2425             }
2426              
2427             It is possible to give a default using an equals sign.
2428              
2429             class WidgetCollection {
2430             has name = "Widgets";
2431             has count (type => Num) = 0;
2432             }
2433              
2434             Note that the default comes after the spec, so in cases where the spec is
2435             long, it may be clearer to express the default inside the spec:
2436              
2437             class WidgetCollection {
2438             has name = "Widgets";
2439             has count (
2440             type => Num,
2441             lazy => true,
2442             required => false,
2443             default => 0,
2444             );
2445             }
2446              
2447             Defaults given this way will be eager (non-lazy), but can be made lazy using
2448             the spec:
2449              
2450             class WidgetCollection {
2451             has name = "Widgets";
2452             has count (is => lazy) = 0;
2453             }
2454              
2455             Defaults I<can> use the C<< $self >> object:
2456              
2457             class WidgetCollection {
2458             has name = "Widgets";
2459             has display_name = $self->name;
2460             }
2461              
2462             Any default that includes C<< $self >> will automatically be lazy, but can be
2463             made eager using the spec. (It is almost certainly a bad idea to do so though.)
2464              
2465             class WidgetCollection {
2466             has name = "Widgets";
2467             has display_name ( lazy => false ) = $self->name;
2468             }
2469              
2470             Commas may be used to separate multiple attributes:
2471              
2472             class WidgetCollection {
2473             has name, display_name ( type => Str );
2474             }
2475              
2476             The specification and defaults are applied to every attribute in the list.
2477              
2478             If you need to decide an attribute name on-the-fly, you can replace the
2479             name with a block that returns the name as a string.
2480              
2481             class Employee {
2482             extends Person;
2483             has {
2484             $ENV{LOCALE} eq 'GB'
2485             ? 'national_insurance_no'
2486             : 'social_security_no'
2487             } (type => Str)
2488             }
2489            
2490             my $bob = Employee->new(
2491             name => 'Bob',
2492             social_security_no => 1234,
2493             );
2494              
2495             You can think of the syntax as being kind of like C<print>.
2496              
2497             print BAREWORD_FILEHANDLE @strings;
2498             print { block_returning_filehandle(); } @strings;
2499              
2500             The block is called in scalar context, so you'll need a loop to define a list
2501             like this:
2502              
2503             class Person {
2504             my @attrs = qw( name age );
2505            
2506             # this does not work
2507             has {@attrs} ( required => true );
2508            
2509             # this works
2510             for my $attr (@attrs) {
2511             has {$attr} ( required => true );
2512             }
2513             }
2514              
2515             The names of attributes can start with an asterisk:
2516              
2517             has *foo;
2518              
2519             This adds no extra meaning, but is supported for consistency with the syntax
2520             of named parameters in method signatures. (Depending on your text editor, it
2521             may also improve syntax highlighting.)
2522              
2523             =head3 C<< constant >>
2524              
2525             class Person {
2526             extends Animal;
2527             constant latin_name = 'Homo sapiens';
2528             }
2529              
2530             C<< MyApp::Person->latin_name >>, C<< MyApp::Person::latin_name >>, and
2531             C<< $person_object->latin_name >> will return 'Homo sapiens'.
2532              
2533             =head3 C<< method >>
2534              
2535             class Person {
2536             has spouse;
2537            
2538             method marry {
2539             my ($self, $partner) = @_;
2540             $self->spouse($partner);
2541             $partner->spouse($self);
2542             return $self;
2543             }
2544             }
2545              
2546             C<< sub { ... } >> will not work as a way to define methods within the
2547             class. Use C<< method { ... } >> instead.
2548              
2549             The variables C<< $self >> and C<< $class >> will be automatically defined
2550             within all methods. C<< $self >> is set to C<< $_[0] >> (though the invocant
2551             is not shifted off C<< @_ >>). C<< $class >> is set to C<< ref($self)||$self >>.
2552             If the method is called as a class method, both C<< $self >> and C<< $class >>
2553             will be the same thing: the full class name as a string. If the method is
2554             called as an object method, C<< $self >> is the object and C<< $class >> is
2555             its class.
2556              
2557             Like with C<has>, you may use a block that returns a string instead of a
2558             bareword name for the method.
2559              
2560             method {"ma"."rry"} {
2561             ...;
2562             }
2563              
2564             MooX::Pression supports method signatures for named arguments and
2565             positional arguments. A mixture of named and positional arguments
2566             is allowed, with some limitations. For anything more complicates,
2567             you should define the method with no signature at all, and unpack
2568             C<< @_ >> within the body of the method.
2569              
2570             =head4 Signatures for Named Arguments
2571              
2572             class Person {
2573             has spouse;
2574            
2575             method marry ( Person *partner, Object *date = DateTime->now ) {
2576             $self->spouse( $arg->partner );
2577             $arg->partner->spouse( $self );
2578             return $self;
2579             }
2580             }
2581              
2582             The syntax for each named argument is:
2583              
2584             Type *name = default
2585              
2586             The type is a type name, which will be parsed using L<Type::Parser>.
2587             (So it can include the C<< ~ >>, C<< | >>, and C<< & >>, operators,
2588             and can include parameters in C<< [ ] >> brackets. Type::Parser can
2589             handle whitespace in the type, but not comments.
2590              
2591             Alternatively, you can provide a block which returns a type name as a string
2592             or returns a blessed Type::Tiny object. For very complex types, where you're
2593             expressing additional coercions or value constraints, this is probably what
2594             you want.
2595              
2596             The asterisk indicates that the argument is named, not positional.
2597              
2598             The name may be followed by a question mark to indicate an optional
2599             argument.
2600              
2601             method marry ( Person *partner, Object *date? ) {
2602             ...;
2603             }
2604              
2605             Or it may be followed by an equals sign to set a default value.
2606              
2607             Comments may be included in the signature, but not in the middle of
2608             a type constraint.
2609              
2610             method marry (
2611             # comment here is okay
2612             Person
2613             # comment here is fine too
2614             *partner
2615             # and here
2616             ) { ... }
2617              
2618             method marry (
2619             Person # comment here is not okay!
2620             | Horse
2621             *partner
2622             ) { ... }
2623              
2624             As with signature-free methods, C<< $self >> and C<< $class >> wll be
2625             defined for you in the body of the method. However, when a signature
2626             has been used C<< $self >> I<is> shifted off C<< @_ >>.
2627              
2628             Also within the body of the method, a variable called C<< $arg >>
2629             is provided. This is a hashref of the named arguments. So you can
2630             access the partner argument in the above example like this:
2631              
2632             $arg->{partner}
2633              
2634             But because C<< $arg >> is blessed, you can also do:
2635              
2636             $arg->partner
2637              
2638             The latter style is encouraged as it looks neater, plus it helps
2639             catch typos. (C<< $ars->{pratner} >> for example!) However, accessing
2640             it as a plain hashref is supported and shouldn't be considered to be
2641             breaking encapsulation.
2642              
2643             For optional arguments you can check:
2644              
2645             exists($arg->{date})
2646              
2647             Or:
2648              
2649             $arg->has_date
2650              
2651             For types which have a coercion defined, the value will be automatically
2652             coerced.
2653              
2654             Methods with named arguments can be called with a hash or hashref.
2655              
2656             $alice->marry( partner => $bob ); # okay
2657             $alice->marry({ partner => $bob }); # also okay
2658              
2659             =head4 Signatures for Positional Arguments
2660              
2661             method marry ( Person $partner, Object $date? ) {
2662             $self->spouse( $partner );
2663             $partner->spouse( $self );
2664             return $self;
2665             }
2666              
2667             The dollar sign is used instead of an asterisk to indicate a positional
2668             argument.
2669              
2670             As with named arguments, C<< $self >> is automatically shifted off C<< @_ >>
2671             and C<< $class >> exists. Unlike named arguments, there is no C<< $arg >>
2672             variable, and instead a scalar variable is defined for each named argument.
2673              
2674             Optional arguments and defaults are supported in the same way as named
2675             arguments.
2676              
2677             It is possible to include a slurpy hash or array at the end of the list
2678             of positional arguments.
2679              
2680             method marry ( $partner, $date, @vows ) {
2681             ...;
2682             }
2683              
2684             If you need to perform a type check on the slurpy parameter, you should
2685             pretend it is a hashref or arrayref.
2686              
2687             method marry ( $partner, $date, ArrayRef[Str] @vows ) {
2688             ...;
2689             }
2690              
2691             =head4 Signatures with Mixed Arguments
2692              
2693             Since MooX::Pression 0.200, you may mix named and positional arguments
2694             with the following limitations:
2695              
2696             =over
2697              
2698             =item *
2699              
2700             Positional arguments must appear at the beginning and/or end of the list.
2701             They cannot be surrounded by named arguments.
2702              
2703             =item *
2704              
2705             Positional arguments cannot be optional and cannot have a default. They
2706             must be required. (Named arguments can be optional and have defaults.)
2707              
2708             =item *
2709              
2710             No slurpies!
2711              
2712             =back
2713              
2714             method print_html ($tag, Str $text, *htmlver?, *xml?, $fh) {
2715            
2716             confess "update your HTML" if $arg->htmlver < 5;
2717            
2718             if (length $text) {
2719             print $fh "<tag>$text</tag>";
2720             }
2721             elsif ($arg->xml) {
2722             print $fh "<tag />";
2723             }
2724             else {
2725             print $fh "<tag></tag>";
2726             }
2727             }
2728            
2729             $obj->print_html('h1', 'Hello World', { xml => true }, \*STDOUT);
2730             $obj->print_html('h1', 'Hello World', xml => true , \*STDOUT);
2731             $obj->print_html('h1', 'Hello World', \*STDOUT);
2732              
2733             Mixed signatures are basically implemented like named signatures, but
2734             prior to interpreting C<< @_ >> as a hash, some parameters are spliced
2735             off the head and tail. We need to know how many elements to splice off
2736             each end, so that is why there are restrictions on slurpies and optional
2737             parameters.
2738              
2739             =head4 Empty Signatures
2740              
2741             There is a difference between the following two methods:
2742              
2743             method foo {
2744             ...;
2745             }
2746            
2747             method foo () {
2748             ...;
2749             }
2750              
2751             In the first, you have not provided a signature and are expected to
2752             deal with C<< @_ >> in the body of the method. In the second, there
2753             is a signature, but it is a signature showing that the method expects
2754             no arguments (other than the invocant of course).
2755              
2756             =head4 Optimizing Methods
2757              
2758             For a slight compiled-time penalty, you can improve the speed which
2759             methods run at using the C<< :optimize >> attribute:
2760              
2761             method foo :optimize (...) {
2762             ...;
2763             }
2764              
2765             Optimized methods must not close over any lexical (C<my> or C<our>)
2766             variables; they can only access the variables declared in their,
2767             signature, C<< $self >>, C<< $class >>, C<< @_ >>, and globals.
2768              
2769             =head4 Anonymous Methods
2770              
2771             It I<is> possible to use C<method> without a name to return an
2772             anonymous method (coderef):
2773              
2774             use MooX::Pression prefix => 'MyApp';
2775            
2776             class MyClass {
2777             method get_method ($foo) {
2778             method ($bar) {
2779             return $foo . $bar;
2780             }
2781             }
2782             }
2783            
2784             my $obj = MyApp->new_myclass;
2785             my $anon = $obj->get_method("FOO");
2786             say ref($anon); # CODE
2787             say $obj->$anon("BAR"); # FOOBAR
2788              
2789             Note that while C<< $anon >> is a coderef, it is still a method, and
2790             still expects to be passed an object as C<< $self >>.
2791              
2792             Due to limitations with L<Keyword::Simple>, keywords are always
2793             complete statements, so C<< method ... >> has an implicit semicolon
2794             before and after it. This means that this won't work:
2795              
2796             my $x = method { ... };
2797              
2798             Because it gets treated as:
2799              
2800             my $x = ;
2801             method { ... };
2802              
2803             A workaround is to wrap it in a C<< do { ... } >> block.
2804              
2805             my $x = do { method { ... } };
2806              
2807             =head4 Multimethods
2808              
2809             Multi methods should I<< Just Work [tm] >> if you prefix them with the
2810             keyword C<multi>
2811              
2812             use MooX::Pression prefix => 'MyApp';
2813            
2814             class Widget {
2815             multi method foo :alias(quux) (Any $x) {
2816             say "Buzz";
2817             }
2818             multi method foo (HashRef $h) {
2819             say "Fizz";
2820             }
2821             }
2822            
2823             my $thing = MyApp->new_widget;
2824             $thing->foo( {} ); # Fizz
2825             $thing->foo( 42 ); # Buzz
2826            
2827             $thing->quux( {} ); # Buzz
2828              
2829             This feature requires L<MooX::Press> 0.035 and L<Sub::MultiMethod> to be
2830             installed.
2831              
2832             =head3 C<< requires >>
2833              
2834             Indicates that a role requires classes to fulfil certain methods.
2835              
2836             role Payable {
2837             requires account;
2838             requires deposit (Num $amount);
2839             }
2840            
2841             class Employee {
2842             extends Person;
2843             with Payable;
2844             has account!;
2845             method deposit (Num $amount) {
2846             ...;
2847             }
2848             }
2849              
2850             Required methods have an optional signature; this is usually ignored, but
2851             if L<Devel::StrictMode> determines that strict behaviour is being used,
2852             the signature will be applied to the method via an C<around> modifier.
2853              
2854             Or to put it another way, this:
2855              
2856             role Payable {
2857             requires account;
2858             requires deposit (Num $amount);
2859             }
2860              
2861             Is a shorthand for this:
2862              
2863             role Payable {
2864             requires account;
2865             requires deposit;
2866            
2867             use Devel::StrictMode 'STRICT';
2868             if (STRICT) {
2869             around deposit (Num $amount) {
2870             $self->$next(@_);
2871             }
2872             }
2873             }
2874              
2875             =head3 C<< before >>
2876              
2877             before marry {
2878             say "Speak now or forever hold your peace!";
2879             }
2880              
2881             As with C<method>, C<< $self >> and C<< $class >> are defined.
2882              
2883             As with C<method>, you can provide a signature:
2884              
2885             before marry ( Person $partner, Object $date? ) {
2886             say "Speak now or forever hold your peace!";
2887             }
2888              
2889             Note that this will result in the argument types being checked/coerced twice;
2890             once by the before method modifier and once by the method itself. Sometimes
2891             this may be desirable, but at other times your before method modifier might
2892             not care about the types of the arguments, so can omit checking them.
2893              
2894             before marry ( $partner, $date? ) {
2895             say "Speak now or forever hold your peace!";
2896             }
2897              
2898             Commas may be used to modify multiple methods:
2899              
2900             before marry, sky_dive (@args) {
2901             say "wish me luck!";
2902             }
2903              
2904             The C<< :optimize >> attribute is supported for C<before>.
2905              
2906             =head3 C<< after >>
2907              
2908             There's not much to say about C<after>. It's just like C<before>.
2909              
2910             after marry {
2911             say "You may kiss the bride!";
2912             }
2913            
2914             after marry ( Person $partner, Object $date? ) {
2915             say "You may kiss the bride!";
2916             }
2917            
2918             after marry ( $partner, $date? ) {
2919             say "You may kiss the bride!";
2920             }
2921              
2922             Commas may be used to modify multiple methods:
2923              
2924             after marry, finished_school_year (@args) {
2925             $self->go_on_holiday();
2926             }
2927              
2928             The C<< :optimize >> attribute is supported for C<after>.
2929              
2930             =head3 C<< around >>
2931              
2932             The C<around> method modifier is somewhat more interesting.
2933              
2934             around marry ( Person $partner, Object $date? ) {
2935             say "Speak now or forever hold your peace!";
2936             my $return = $self->$next(@_);
2937             say "You may kiss the bride!";
2938             return $return;
2939             }
2940              
2941             The C<< $next >> variable holds a coderef pointing to the "original" method
2942             that is being modified. This gives your method modifier the ability to munge
2943             the arguments seen by the "original" method, and munge any return values.
2944             (I say "original" in quote marks because it may not really be the original
2945             method but another wrapper!)
2946              
2947             C<< $next >> and C<< $self >> are both shifted off C<< @_ >>.
2948              
2949             If you use the signature-free version then C<< $next >> and C<< $self >>
2950             are not shifted off C<< @_ >> for you, but the variables are still defined.
2951              
2952             around marry {
2953             say "Speak now or forever hold your peace!";
2954             my $return = $self->$next($_[2], $_[3]);
2955             say "You may kiss the bride!";
2956             return $return;
2957             }
2958              
2959             Commas may be used to modify multiple methods:
2960              
2961             around insert, update ($dbh, @args) {
2962             $dbh->begin_transaction;
2963             my $return = $self->$next(@_);
2964             $dbh->commit_transaction;
2965             return $return;
2966             }
2967              
2968             The C<< :optimize >> attribute is supported for C<around>.
2969              
2970             Note that C<< SUPER:: >> won't work as expected in MooX::Pression, so
2971             C<around> should be used instead.
2972              
2973             =head3 C<< factory >>
2974              
2975             The C<factory> keyword is used to define alternative constructors for
2976             your class.
2977              
2978             class Person {
2979             has name ( type => Str, required => true );
2980             has gender ( type => Str );
2981            
2982             factory new_man (Str $name) {
2983             return $class->new(name => $name, gender => 'male');
2984             }
2985            
2986             factory new_woman (Str $name) {
2987             return $class->new(name => $name, gender => 'female');
2988             }
2989             }
2990              
2991             But here's the twist. These methods are defined within the factory
2992             package, not within the class.
2993              
2994             So you can call:
2995              
2996             MyApp->new_man("Bob") # yes
2997              
2998             But not:
2999              
3000             MyApp::Person->new_man("Bob") # no
3001              
3002             Note that if your class defines I<any> factory methods like this, then the
3003             default factory method (in this case C<< MyApp->new_person >> will no longer
3004             be automatically created. But you can create the default one easily:
3005              
3006             class Person {
3007             has name ( type => Str, required => true );
3008             has gender ( type => Str );
3009            
3010             factory new_man (Str $name) { ... }
3011             factory new_woman (Str $name) { ... }
3012             factory new_person; # no method signature or body!
3013             }
3014              
3015             Within a factory method body, the variable C<< $class >> is defined, just
3016             like normal methods, but C<< $self >> is not defined. There is also a
3017             variable C<< $factory >> which is a string containing the factory
3018             package name. This is because you sometimes need to create more than
3019             just one object in a factory method.
3020              
3021             class Wheel;
3022            
3023             class Car {
3024             has wheels = [];
3025            
3026             factory new_three_wheeler () {
3027             return $class->new(
3028             wheels => [
3029             $factory->new_wheel,
3030             $factory->new_wheel,
3031             $factory->new_wheel,
3032             ]
3033             );
3034             }
3035            
3036             factory new_four_wheeler () {
3037             return $class->new(
3038             wheels => [
3039             $factory->new_wheel,
3040             $factory->new_wheel,
3041             $factory->new_wheel,
3042             $factory->new_wheel,
3043             ]
3044             );
3045             }
3046             }
3047              
3048             As with C<method> and the method modifiers, if you provide a signature,
3049             C<< $factory >> and C<< $class >> will be shifted off C<< @_ >>. If you
3050             don't provide a signature, the variables will be defined, but not shifted
3051             off C<< @_ >>.
3052              
3053             An alternative way to provide additional constructors is with C<method>
3054             and then use C<factory> to proxy them.
3055              
3056             class Person {
3057             has name ( type => Str, required => true );
3058             has gender ( type => Str );
3059            
3060             method new_guy (Str $name) { ... }
3061             method new_gal (Str $name) { ... }
3062            
3063             factory new_person;
3064             factory new_man via new_guy;
3065             factory new_woman via new_gal;
3066             }
3067              
3068             Now C<< MyApp->new_man >> will call C<< MyApp::Person->new_guy >>.
3069              
3070             C<< factory new_person >> with no C<via> or method body is basically
3071             like saying C<< via new >>.
3072              
3073             The C<< :optimize >> attribute is supported for C<factory>.
3074              
3075             =head4 Implementing a singleton
3076              
3077             Factories make it pretty easy to implement a singleton.
3078              
3079             class AppConfig {
3080             ...;
3081            
3082             factory get_appconfig () {
3083             state $config = $class->new();
3084             }
3085             }
3086              
3087             Now C<< MyApp->get_appconfig >> will always return the same AppConfig object.
3088             Because any explicit use of the C<factory> keyword in a class definition
3089             suppresses the automatic creation of a factory method for the class, there
3090             will be no C<< MyApp->new_appconfig >> method for creating new objects
3091             of that class.
3092              
3093             (People can still manually call C<< MyApp::AppConfig->new >> to get a new
3094             AppConfig object, but remember MooX::Pression discourages calling constructors
3095             directly, and encourages you to use the factory package for instantiating
3096             objects!)
3097              
3098             =head3 C<< type_name >>
3099              
3100             class Homo::Sapiens {
3101             type_name Human;
3102             }
3103              
3104             The class will still be called L<MyApp::Homo::Sapiens> but the type in the
3105             type library will be called B<Human> instead of B<Homo_Sapiens>.
3106              
3107             =head3 C<< coerce >>
3108              
3109             class Person {
3110             has name ( type => Str, required => true );
3111             has gender ( type => Str );
3112            
3113             coerce from Str via from_string {
3114             $class->new(name => $_);
3115             }
3116             }
3117            
3118             class Company {
3119             has owner ( type => 'Person', required => true );
3120             }
3121            
3122             my $acme = MyApp->new_company( owner => "Bob" );
3123              
3124             Note that the company owner is supposed to be a person object, not a string,
3125             but the Person class knows how create a person object from a string.
3126              
3127             Coercions are automatically enabled in a lot of places for types that have
3128             a coercion. For example, types in signatures, and types in attribute
3129             definitions.
3130              
3131             Note that the coercion body doesn't allow signatures, and the value being
3132             coerced will be found in C<< $_ >>. If you want to have signatures, you
3133             can define a coercion as a normal method first:
3134              
3135             class Person {
3136             has name ( type => Str, required => true );
3137             has gender ( type => Str );
3138            
3139             method from_string ( Str $name ) {
3140             $class->new(name => $name);
3141             }
3142            
3143             coerce from Str via from_string;
3144             }
3145              
3146             In both cases, a C<< MyApp::Person->from_string >> method is generated
3147             which can be called to manually coerce a string into a person object.
3148              
3149             They keyword C<< from >> is technically optional, but does make the
3150             statement more readable.
3151              
3152             coerce Str via from_string { # this works
3153             $class->new(name => $_);
3154             }
3155              
3156             The C<< :optimize >> attribute is not currently supported for C<coerce>.
3157              
3158             =head3 C<< overload >>
3159              
3160             class Collection {
3161             has items = [];
3162             overload '@{}' => sub { shift->list };
3163             }
3164              
3165             The list passed to C<overload> is passed to L<overload> with no other
3166             processing.
3167              
3168             =head3 C<< version >>
3169              
3170             class Person {
3171             version 1.0;
3172             }
3173              
3174             This just sets C<< $MyApp::Person::VERSION >>.
3175              
3176             You can set a default version for all packages like this:
3177              
3178             use MooX::Pression (
3179             ...,
3180             version => 1.0,
3181             );
3182              
3183             If C<class> definitions are nested, C<version> will be inherited by
3184             child classes. If a parent class is specified via C<extends>, C<version>
3185             will not be inherited.
3186              
3187             =head3 C<< authority >>
3188              
3189             class Person {
3190             authority 'cpan:TOBYINK';
3191             }
3192              
3193             This just sets C<< $MyApp::Person::AUTHORITY >>.
3194              
3195             It is used to indicate who is the maintainer of the package.
3196              
3197             use MooX::Pression (
3198             ...,
3199             version => 1.0,
3200             authority => 'cpan:TOBYINK',
3201             );
3202              
3203             If C<class> definitions are nested, C<authority> will be inherited by
3204             child classes. If a parent class is specified via C<extends>, C<authority>
3205             will not be inherited.
3206              
3207             =head3 C<< include >>
3208              
3209             C<include> is the MooX::Pression equivalent of Perl's C<require>.
3210              
3211             package MyApp {
3212             use MooX::Pression;
3213             include Database;
3214             include Classes;
3215             include Roles;
3216             }
3217              
3218             It works somewhat more crudely than C<require> and C<use>, evaluating
3219             the included file pretty much as if it had been copy and pasted into the
3220             file that included it.
3221              
3222             The names of the files to load are processsed using the same rules for
3223             prefixes as classes and roles (so MyApp::Database, etc in the example),
3224             and C<< @INC >> is searched just like C<require> and C<use> do, but
3225             instead of looking for a file called "MyApp/Database.pm", MooX::Pression
3226             will look for "MyApp/Database.pl" (yes, ".pl"). This naming convention
3227             ensures people won't accidentally load MyApp::Database using C<use>
3228             or C<require> because it isn't intended to be loaded outside the context
3229             of the MyApp package.
3230              
3231             The file "MyApp/Database.pl" might look something like this:
3232              
3233             class Database {
3234             has dbh = DBI->connect(...);
3235            
3236             factory get_db {
3237             state $instance = $class->new;
3238             }
3239             }
3240              
3241             Note that it doesn't start with a C<package> statement, nor
3242             C<use MooX::Pression>. It's just straight on to the definitions.
3243             There's no C<< 1; >> needed at the end.
3244              
3245             C<< use strict >> and C<< use warnings >> are safe to put in the
3246             file if you need them to satisfy linters, but they're not necessary
3247             because the contents of the file are evaluated as if they had been
3248             copied and pasted into the main MyApp module.
3249              
3250             There are I<no> checks to prevent a file from being included more than
3251             once, and there are I<no> checks to deal with cyclical inclusions.
3252              
3253             Inclusions are currently only supported at the top level, and not within
3254             class and role definitions.
3255              
3256             =head3 C<< MooX::Pression::PACKAGE_SPEC() >>
3257              
3258             This function can be used while a class or role is being compiled to
3259             tweak the specification for the class/role.
3260              
3261             class Foo {
3262             has foo;
3263             MooX::Pression::PACKAGE_SPEC->{has}{foo}{type} = Int;
3264             }
3265              
3266             It returns a hashref of attributes, methods, etc. L<MooX::Press> should
3267             give you an idea about how the hashref is structured, but MooX::Pression
3268             only supports a subset of what MooX::Press supports. For example, MooX::Press
3269             allows C<has> to be an arrayref or a hashref, but MooX::Pression only supports
3270             a hashref. The exact subset that MooX::Pression supports is subject to change
3271             without notice.
3272              
3273             This can be used to access MooX::Press features that MooX::Pression doesn't
3274             expose.
3275              
3276             =head2 Helper Subs
3277              
3278             Earlier it was stated that C<sub> cannot be used to define methods in
3279             classes and roles. This is true, but that doesn't mean that it has no
3280             use.
3281              
3282             package MyApp {
3283             use MooX::Pression;
3284            
3285             sub helper_function { ... }
3286            
3287             class Foo {
3288             method foo {
3289             ...;
3290             helper_function(...);
3291             ...;
3292             }
3293             }
3294            
3295             class Bar {
3296             sub other_helper { ... }
3297             method bar {
3298             ...;
3299             helper_function(...);
3300             other_helper(...);
3301             ...;
3302             }
3303             }
3304             }
3305              
3306             The subs defined by C<sub> end up in the "MyApp" package, not
3307             "MyApp::Foo" or "MyApp::Bar". They can be called by any of the classes
3308             and roles defined in MyApp. This makes them suitable for helper subs
3309             like logging, L<List::Util>/L<Scalar::Util> sorts of functions, and
3310             so on.
3311              
3312             package MyApp {
3313             use MooX::Pression;
3314            
3315             use List::Util qw( any all first reduce );
3316             # the above functions are now available within
3317             # all of MyApp's classes and roles, but won't
3318             # pollute any of their namespaces.
3319            
3320             use namespace::clean;
3321             # And now they won't even pollute MyApp's namespace.
3322             # Though I'm pretty sure this will also stop them
3323             # from working in any methods that used ":optimize".
3324            
3325             class Foo { ... }
3326             role Bar { ... }
3327             role Baz { ... }
3328             }
3329              
3330             C<sub> is also usually your best option for those tiny little
3331             coderefs that need to be defined here and there:
3332              
3333             has foo (
3334             is => lazy,
3335             type => ArrayRef[Str],
3336             builder => sub { [] },
3337             );
3338              
3339             Though consider using L<Sub::Quote> if you're using Moo.
3340              
3341             =head2 Utilities
3342              
3343             MooX::Pression also exports constants C<true> and C<false> into your
3344             namespace. These show clearer boolean intent in code than using 1 and 0.
3345              
3346             MooX::Pression exports C<rw>, C<ro>, C<rwp>, and C<lazy> constants
3347             which make your attribute specs a little cleaner looking.
3348              
3349             MooX::Pression exports C<blessed> from L<Scalar::Util> because that can
3350             be handy to have, and C<confess> from L<Carp>. MooX::Pression's copy
3351             of C<confess> is super-powered and runs its arguments through C<sprintf>.
3352              
3353             before vote {
3354             if ($self->age < 18) {
3355             confess("Can't vote, only %d", $self->age);
3356             }
3357             }
3358              
3359             MooX::Pression turns on strict, warnings, and the following modern Perl
3360             features:
3361              
3362             # Perl 5.14 and Perl 5.16
3363             say state unicode_strings
3364            
3365             # Perl 5.18 or above
3366             say state unicode_strings unicode_eval evalbytes current_sub fc
3367              
3368             If you're wondering why not other features, it's because I didn't want to
3369             enable any that are currently classed as experimental, nor any that require
3370             a version of Perl above 5.18. The C<switch> feature is mostly seen as a
3371             failed experiment these days, and C<lexical_subs> cannot be called as methods
3372             so are less useful in object-oriented code.
3373              
3374             You can, of course, turn on extra features yourself.
3375              
3376             package MyApp {
3377             use MooX::Pression;
3378             use feature qw( lexical_subs postderef );
3379            
3380             ...;
3381             }
3382              
3383             (The C<current_sub> feature is unlikely to work fully unless you
3384             have C<:optimize> switched on for that method, or the method does not
3385             include a signature. For non-optimized methods with a signature, a
3386             wrapper is installed that handles checks, coercions, and defaults.
3387             C<< __SUB__ >> will point to the "inner" sub, minus the wrapper.)
3388              
3389             MooX::Pression exports L<Syntax::Keyword::Try> for you. Useful to have.
3390              
3391             And last but not least, it exports all the types, C<< is_* >> functions,
3392             and C<< assert_* >> functions from L<Types::Standard>,
3393             L<Types::Common::String>, and L<Types::Common::Numeric>.
3394              
3395             =head2 Anonymous Classes and Roles
3396              
3397             =head3 Anonymous classes
3398              
3399             It is possible to make anonymous classes:
3400              
3401             my $class = do { class; };
3402             my $object = $class->new;
3403              
3404             The C<< do { ... } >> block is necessary because of a limitation in
3405             L<Keyword::Simple>, where any keywords it defines must be complete
3406             statements.
3407              
3408             Anonymous classes can have methods and attributes and so on:
3409              
3410             my $class = do { class {
3411             has foo (type => Int);
3412             has bar (type => Int);
3413             }};
3414            
3415             my $object = $class->new(foo => 1, bar => 2);
3416              
3417             Anonymous classes I<do not> implicitly inherit from their parent like
3418             named nested classes do. Named classes nested inside anonymous classes
3419             I<do not> implicitly inherit from the anonymous class.
3420              
3421             Having one anonymous class inherit from another can be done though:
3422              
3423             my $base = do { class; }
3424             my $derived = do { class {
3425             extends {"::$k1"};
3426             }};
3427              
3428             This works because C<extends> accepts a block which returns a string for
3429             the package name, and the string needs to begin with "::" to avoid the
3430             auto prefix mechanism.
3431              
3432             =head3 Anonymous roles
3433              
3434             Anonymous roles work in much the same way.
3435              
3436             =head2 Parameterizable Classes and Roles
3437              
3438             =head3 Parameterizable classes
3439              
3440             package MyApp {
3441             use MooX::Pression;
3442            
3443             class Animal {
3444             has name;
3445             }
3446            
3447             class Species ( Str $common_name, Str $binomial ) {
3448             extends Animal;
3449             constant common_name = $common_name;
3450             constant binomial = $binomial;
3451             }
3452            
3453             class Dog {
3454             extends Species('dog', 'Canis familiaris');
3455             method bark () {
3456             say "woof!";
3457             }
3458             }
3459             }
3460              
3461             Here, "MyApp::Species" isn't a class in the usual sense; you cannot create
3462             instances of it. It's like a template for generating classes. Then
3463             "MyApp::Dog" generates a class from the template and inherits from that.
3464              
3465             my $Cat = MyApp->generate_species('cat', 'Felis catus');
3466             my $mog = $Cat->new(name => 'Mog');
3467            
3468             $mog->isa('MyApp::Animal'); # true
3469             $mog->isa('MyApp::Species'); # false!!!
3470             $mog->isa($Cat); # true
3471              
3472             Because there are never any instances of "MyApp::Species", it doesn't
3473             make sense to have a B<Species> type constraint. Instead there are
3474             B<SpeciesClass> and B<SpeciesInstance> type constraints.
3475              
3476             use MyApp::Types -is;
3477            
3478             my $lassie = MyApp->new_dog;
3479            
3480             is_Animal( $lassie ); # true
3481             is_Dog( $lassie ); # true
3482             is_SpeciesInstance( $lassie ); # true
3483             is_SpeciesClass( ref($lassie) ); # true
3484              
3485             Subclasses cannot be nested inside parameterizable classes, but
3486             parameterizable classes can be nested inside regular classes, in
3487             which case the classes they generate will inherit from the outer
3488             class.
3489              
3490             package MyApp {
3491             use MooX::Pression;
3492            
3493             class Animal {
3494             has name;
3495             class Species ( Str $common_name, Str $binomial ) {
3496             constant common_name = $common_name;
3497             constant binomial = $binomial;
3498             }
3499             }
3500            
3501             class Dog {
3502             extends Species('dog', 'Canis familiaris');
3503             method bark () {
3504             say "woof!";
3505             }
3506             }
3507             }
3508              
3509             Anonymous parameterizable classes are possible:
3510              
3511             my $generator = do { class ($footype, $bartype) {
3512             has foo (type => $footype);
3513             has bar (type => $bartype);
3514             };
3515            
3516             my $class = $generator->generate_package(Int, Num);
3517            
3518             my $object = $class->new(foo => 42, bar => 4.2);
3519              
3520             =head3 Parameterizable roles
3521              
3522             Often it makes more sense to parameterize roles than classes.
3523              
3524             package MyApp {
3525             use MooX::Pression;
3526            
3527             class Animal {
3528             has name;
3529             }
3530            
3531             role Species ( Str $common_name, Str $binomial ) {
3532             constant common_name = $common_name;
3533             constant binomial = $binomial;
3534             }
3535            
3536             class Dog {
3537             extends Animal;
3538             with Species('dog', 'Canis familiaris'), GoodBoi?;
3539             method bark () {
3540             say "woof!";
3541             }
3542             }
3543             }
3544              
3545             Anonymous parameterizable roles are possible.
3546              
3547             =head2 MooX::Pression vs Moops
3548              
3549             MooX::Pression has fewer dependencies than Moops, and crucially doesn't
3550             rely on L<Package::Keyword> and L<Devel::CallParser> which have... issues.
3551             MooX::Pression uses Damian Conway's excellent L<PPR> to handle most parsing
3552             needs, so parsing should be more predictable.
3553              
3554             Moops is faster though.
3555              
3556             Here are a few key syntax and feature differences.
3557              
3558             =head3 Declaring a class
3559              
3560             Moops:
3561              
3562             class Foo::Bar 1.0 extends Foo with Bar {
3563             ...;
3564             }
3565              
3566             MooX::Pression:
3567              
3568             class Foo::Bar {
3569             version 1.0;
3570             extends Foo;
3571             with Bar;
3572             }
3573              
3574             Moops and MooX::Pression use different logic for determining whether a class
3575             name is "absolute" or "relative". In Moops, classes containing a "::" are seen
3576             as absolute class names; in MooX::Pression, only classes I<starting with> "::"
3577             are taken to be absolute; all others are given the prefix.
3578              
3579             Moops:
3580              
3581             package MyApp {
3582             use Moops;
3583             class Foo {
3584             class Bar {
3585             class Baz {
3586             # Nesting class blocks establishes a naming
3587             # heirarchy so this is MyApp::Foo::Bar::Baz!
3588             }
3589             }
3590             }
3591             }
3592              
3593             MooX::Pression:
3594              
3595             package MyApp {
3596             use MooX::Pression;
3597             class Foo {
3598             class Bar {
3599             class Baz {
3600             # This is only MyApp::Baz, but nesting
3601             # establishes an @ISA chain instead.
3602             }
3603             }
3604             }
3605             }
3606              
3607             =head3 How namespacing works
3608              
3609             Moops:
3610              
3611             use feature 'say';
3612             package MyApp {
3613             use Moops;
3614             use List::Util qw(uniq);
3615             class Foo {
3616             say __PACKAGE__; # MyApp::Foo
3617             say for uniq(1,2,1,3); # ERROR!
3618             sub foo { ... } # MyApp::Foo::foo()
3619             }
3620             }
3621              
3622             MooX::Pression:
3623              
3624             use feature 'say';
3625             package MyApp {
3626             use MooX::Pression;
3627             use List::Util qw(uniq);
3628             class Foo {
3629             say __PACKAGE__; # MyApp
3630             say for uniq(1,2,1,3); # this works fine
3631             sub foo { ... } # MyApp::foo()
3632             }
3633             }
3634              
3635             This is why you can't use C<sub> to define methods in MooX::Pression.
3636             You need to use the C<method> keyword. In MooX::Pression, all the code
3637             in the class definition block is still executing in the parent
3638             package's namespace!
3639              
3640             =head3 Multimethods
3641              
3642             Moops/Kavorka multimethods are faster, but MooX::Pression is smarter at
3643             picking the best candidate to dispatch to, and intelligently selecting
3644             candidates across inheritance hierarchies and role compositions.
3645              
3646             =head3 Other crazy Kavorka features
3647              
3648             Kavorka allows you to mark certain parameters as read-only or aliases,
3649             allows you to specify multiple names for named parameters, allows you
3650             to rename the invocant, allows you to give methods and parameters
3651             attributes, allows you to specify a method's return type, etc, etc.
3652              
3653             MooX::Pression's C<method> keyword is unlikely to ever offer as many
3654             features as that. It is unlikely to offer many more features than it
3655             currently offers.
3656              
3657             If you need fine-grained control over how C<< @_ >> is handled, just
3658             don't use a signature and unpack C<< @_ >> inside your method body
3659             however you need to.
3660              
3661             =head3 Lexical accessors
3662              
3663             Moops automatically imported C<lexical_has> from L<Lexical::Accessor>
3664             into each class. MooX::Pression does not, but thanks to how namespacing
3665             works, it only needs to be imported once if you want to use it.
3666              
3667             package MyApp {
3668             use MooX::Pression;
3669             use Lexical::Accessor;
3670            
3671             class Foo {
3672             my $identifier = lexical_has identifier => (
3673             is => rw,
3674             isa => Int,
3675             default => sub { 0 },
3676             );
3677            
3678             method some_method () {
3679             $self->$identifier( 123 ); # set identifier
3680             ...;
3681             return $self->$identifier; # get identifier
3682             }
3683             }
3684             }
3685              
3686             Lexical accessors give you true private object attributes.
3687              
3688             =head3 Factories
3689              
3690             MooX::Pression puts an emphasis on having a factory package for instantiating
3691             objects. Moops didn't have anything similar.
3692              
3693             =head3 C<augment> and C<override>
3694              
3695             These are L<Moose> method modifiers that are not implemented by L<Moo>.
3696             Moops allows you to use these in Moose and Mouse classes, but not Moo
3697             classes. MooX::Pression simply doesn't support them.
3698              
3699             =head3 Type Libraries
3700              
3701             Moops allowed you to declare multiple type libraries, define type
3702             constraints in each, and specify for each class and role which type
3703             libraries you want it to use.
3704              
3705             MooX::Pression automatically creates a single type library for all
3706             your classes and roles within a module to use, and automatically
3707             populates it with the types it thinks you might want.
3708              
3709             If you need to use other type constraints:
3710              
3711             package MyApp {
3712             use MooX::Pression;
3713             # Just import types into the factory package!
3714             use Types::Path::Tiny qw( Path );
3715            
3716             class DataSource {
3717             has file => ( type => Path );
3718            
3719             method set_file ( Path $file ) {
3720             $self->file( $file );
3721             }
3722             }
3723             }
3724            
3725             my $ds = MyApp->new_datasource;
3726             $ds->set_file('blah.txt'); # coerce Str to Path
3727             print $ds->file->slurp_utf8;
3728              
3729             =head3 Constants
3730              
3731             Moops:
3732              
3733             class Foo {
3734             define PI = 3.2;
3735             }
3736              
3737             MooX::Pression:
3738              
3739             class Foo {
3740             constant PI = 3.2;
3741             }
3742              
3743             =head3 Parameterizable classes and roles
3744              
3745             These were always on my todo list for Moops; I doubt they'll ever be done.
3746             They work nicely in MooX::Pression though.
3747              
3748             =head1 BUGS
3749              
3750             Please report any bugs to
3751             L<http://rt.cpan.org/Dist/Display.html?Queue=MooX-Pression>.
3752              
3753             =head1 TODO
3754              
3755             =head2 Plugin system
3756              
3757             MooX::Pression can often load MooX/MouseX/MooseX plugins and work
3758             fine with them, but some things won't work, like plugins that rely on
3759             being able to wrap C<has>. So it would be nice to have a plugin system
3760             that extensions can hook into.
3761              
3762             If you're interested in extending MooX::Pression, file a bug report about
3763             it and let's have a conversation about the best way for that to happen.
3764              
3765             =head1 SEE ALSO
3766              
3767             Less magic version:
3768             L<MooX::Press>, L<portable::loader>.
3769              
3770             Important underlying technologies:
3771             L<Moo>, L<Type::Tiny::Manual>.
3772              
3773             Similar modules:
3774             L<Moops>, L<Kavorka>, L<Dios>, L<MooseX::Declare>.
3775              
3776             =head1 AUTHOR
3777              
3778             Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
3779              
3780             =head1 COPYRIGHT AND LICENCE
3781              
3782             This software is copyright (c) 2020 by Toby Inkster.
3783              
3784             This is free software; you can redistribute it and/or modify it under
3785             the same terms as the Perl 5 programming language system itself.
3786              
3787             =head1 DISCLAIMER OF WARRANTIES
3788              
3789             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
3790             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
3791             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
3792