File Coverage

blib/lib/MooX/Press.pm
Criterion Covered Total %
statement 1391 1589 87.5
branch 491 712 68.9
condition 223 406 54.9
subroutine 204 212 96.2
pod 10 53 18.8
total 2319 2972 78.0


line stmt bran cond sub pod time code
1 40     40   4015256 use 5.008008;
  40         333  
2 40     40   198 use strict;
  40         66  
  40         803  
3 40     40   188 use warnings;
  40         66  
  40         2655  
4              
5              
6             our $AUTHORITY = 'cpan:TOBYINK';
7             our $VERSION = '0.086';
8              
9             use Types::Standard 1.010000 -is, -types;
10 40     40   13649 use Types::TypeTiny qw(ArrayLike HashLike);
  40         2298994  
  40         321  
11 40     40   311530 use Type::Registry ();
  40         85  
  40         285  
12 40     40   93576 use Exporter::Tiny qw(mkopt);
  40         247073  
  40         1014  
13 40     40   240 use Import::Into;
  40         86  
  40         491  
14 40     40   21651 use match::simple qw(match);
  40         79612  
  40         1157  
15 40     40   14401 use Module::Runtime qw(use_module);
  40         64419  
  40         298  
16 40     40   6962 use namespace::autoclean;
  40         87  
  40         194  
17 40     40   15644  
  40         425336  
  40         157  
18             my $p = shift;
19             $] lt '5.018' ? "main::$p" : "::$p";
20 311     311 0 473 }
21 311 50       1160  
22             if ( $] lt '5.010' ) {
23             require UNIVERSAL::DOES;
24             }
25              
26             # Options not to carry up into subclasses;
27             # mostly because subclasses inherit behaviour anyway.
28             my @delete_keys = qw(
29             subclass
30             has
31             with
32             extends
33             overload
34             factory
35             coerce
36             around
37             before
38             after
39             type_name
40             can
41             type_library_can
42             factory_package_can
43             abstract
44             multimethod
45             symmethod
46             multifactory
47             );
48              
49             my $_handle_list = sub {
50             my ($thing) = @_;
51             return ()
52             unless defined $thing;
53             return $thing
54             if is_Str $thing;
55             return %$thing
56             if is_HashRef $thing;
57             return @$thing
58             if is_ArrayRef $thing;
59             goto $thing
60             if is_CodeRef $thing;
61             die "Unexepcted thing; got $thing";
62             };
63              
64             my $_handle_list_add_nulls = sub {
65             my ($thing) = @_;
66             return map @$_, @{mkopt $thing}
67             if is_ArrayRef $thing;
68             goto $_handle_list;
69             };
70              
71             my %_cached_moo_helper;
72              
73             my $builder = shift;
74             my $opts = $_[0];
75            
76 49     49   124 $opts->{default_is} ||= 'ro';
77 49         90
78             $opts->{toolkit} ||= $ENV{'PERL_MOOX_PRESS_TOOLKIT'} || 'Moo';
79 49   50     260
80             $opts->{version} = $opts->{caller}->VERSION
81 49   50     270 unless exists $opts->{version};
      66        
82            
83             $opts->{authority} = do { no strict 'refs'; no warnings 'once'; ${$opts->{caller}."::AUTHORITY"} }
84 49 100       783 unless exists $opts->{authority};
85            
86 40     40   12453 unless (exists $opts->{prefix}) {
  40     40   93  
  40         1229  
  40         231  
  40         84  
  40         27047  
  42         1200  
  42         291  
87 49 100       172 $opts->{prefix} = $opts->{caller};
88             if ($opts->{prefix} eq 'main') {
89 49 100       302 $opts->{prefix} = undef;
90 10         31 }
91 10 100       34 }
92 2         4
93             my $no_warn = exists($opts->{factory_package});
94            
95             $opts->{factory_package} = defined($opts->{prefix}) ? $opts->{prefix} : 'Local'
96 49         120 unless exists $opts->{factory_package};
97            
98             if (!$no_warn and defined($opts->{factory_package}) and $opts->{factory_package} eq 'Local') {
99 49 50       1298 require FindBin;
    100          
100             if ($FindBin::Script ne '-e') {
101 49 50 66     278 require Carp;
      66        
102 0         0 Carp::carp('Using "Local" as factory; please set prefix or factory_package');
103 0 0       0 }
104 0         0 }
105 0         0
106             unless (exists $opts->{type_library}) {
107             $opts->{type_library} = $builder->qualify_name('Types', $opts->{prefix});
108             }
109 49 50       141 }
110 49         155  
111             my $builder = shift;
112             my $caller = caller;
113             my %opts = @_==1 ? shift->$_handle_list_add_nulls : @_;
114             $opts{caller} ||= $caller;
115 49     49   48504 $opts{caller_file} ||= [caller]->[1];
116 49         112
117 49 50       315 $builder->_apply_default_options(\%opts);
118 49   66     304 $builder->munge_options(\%opts);
119 49   33     367
120             $builder->_mark_package_as_loaded('factory package' => $opts{factory_package}, \%opts);
121 49         218
122 49         190 my @role_generators = @{ mkopt $opts{role_generator} };
123             my @class_generators = @{ mkopt $opts{class_generator} };
124 49         207 my @roles = @{ mkopt $opts{role} };
125             my @classes = @{ mkopt $opts{class} };
126 49         83
  49         247  
127 49         359 # Canonicalize these now, saves repeatedly doing it later!
  49         153  
128 49         282 for my $pkg (@role_generators) {
  49         125  
129 49         749 if (is_CodeRef($pkg->[1])
  49         149  
130             or is_HashRef($pkg->[1]) && is_CodeRef($pkg->[1]{code})) {
131             $pkg->[1] = { generator => $pkg->[1] };
132 49         959 }
133 2 50 33     27 $pkg->[1] = { $pkg->[1]->$_handle_list };
      66        
134             $builder->munge_role_generator_options($pkg->[1], \%opts);
135 2         6 }
136             for my $pkg (@class_generators) {
137 2         11 if (is_CodeRef($pkg->[1])
138 2         9 or is_HashRef($pkg->[1]) && is_CodeRef($pkg->[1]{code})) {
139             $pkg->[1] = { generator => $pkg->[1] };
140 49         124 }
141 2 50 33     14 $pkg->[1] = { $pkg->[1]->$_handle_list };
      66        
142             $builder->munge_class_generator_options($pkg->[1], \%opts);
143 2         6 }
144             for my $pkg (@roles) {
145 2         5 $pkg->[1] = { $pkg->[1]->$_handle_list };
146 2         7 # qualify names in role list early
147             $pkg->[0] = make_absolute_package_name(
148 49         106 $builder->qualify_name($pkg->[0], exists($pkg->[1]{prefix})?$pkg->[1]{prefix}:$opts{prefix})
149 57         130 );
150             $builder->munge_role_options($pkg->[1], \%opts);
151             }
152             for my $pkg (@classes) {
153 57 50       203 $pkg->[1] = { $pkg->[1]->$_handle_list };
154 57         179 if (defined $pkg->[1]{extends} and not ref $pkg->[1]{extends}) {
155             $pkg->[1]{extends} = [$pkg->[1]{extends}];
156 49         125 }
157 69         182 $builder->munge_class_options($pkg->[1], \%opts);
158 69 100 100     309 }
159 9         17  
160             if ($opts{type_library}) {
161 69         216 $builder->prepare_type_library($opts{type_library}, %opts);
162             # no type for role generators
163             for my $pkg (@class_generators) {
164 49 50       186 $builder->make_type_for_class_generator($pkg->[0], %opts, %{$pkg->[1]});
165 49         319 }
166             for my $pkg (@roles) {
167 49         183 $builder->make_type_for_role($pkg->[0], %opts, %{$pkg->[1]});
168 2         7 }
  2         11  
169             for my $pkg (@classes) {
170 49         199 $builder->make_type_for_class($pkg->[0], %opts, %{$pkg->[1]});
171 57         218 }
  57         301  
172             }
173 49         149
174 69         224 my $reg;
  69         356  
175             if ($opts{factory_package}) {
176             require Type::Registry;
177             $reg = 'Type::Registry'->for_class($opts{factory_package});
178 49         97 $reg->add_types($_) for (
179 49 100       185 $opts{type_library},
180 47         231 qw( Types::Standard Types::Common::Numeric Types::Common::String Types::TypeTiny ),
181 47         170 );
182 47         441 }
183            
184             if (defined $opts{'factory_package'}) {
185             no strict 'refs';
186            
187             my %methods;
188 49 100       2390422 my $method_installer = $opts{toolkit_install_methods} || ("install_methods");
189 40     40   280
  40         74  
  40         8481  
190             %methods = delete($opts{factory_package_can})->$_handle_list_add_nulls;
191 47         123 if ( my $p = $opts{'prefix'} ) {
192 47   50     307 $methods{qualify} ||= sub { $builder->qualify_name($_[1], $p) }
193             unless exists &{$opts{'factory_package'}.'::qualify'};
194 47         204 $methods{get_class} ||= sub { shift; $builder->_get_class($p, @_) }
195 47 50       229 unless exists &{$opts{'factory_package'}.'::get_class'};
196 0     0   0 $methods{get_role} ||= sub { shift; $builder->_get_role($p, @_) }
197 47 100 50     78 unless exists &{$opts{'factory_package'}.'::get_role'};
  47         676  
198 2     2   9 }
  2         19  
199 47 100 50     80 $builder->$method_installer($opts{'factory_package'}, \%methods) if keys %methods;
  47         495  
200 1     1   3
  1         6  
201 47 100 50     77 %methods = delete($opts{type_library_can})->$_handle_list_add_nulls;
  47         434  
202             $builder->$method_installer($opts{type_library}, \%methods) if keys %methods;
203 47 100       481
204             no strict 'refs';
205 47         190 push @{ $opts{'factory_package'} . '::ISA' }, 'Exporter::Tiny';
206 47 50       182 }
207            
208 40     40   266 my %modifiers;
  40         74  
  40         16833  
209 47         92 $opts{$_} && ($modifiers{$_} = delete $opts{$_})
  47         598  
210             for qw/ before after around can with constant symmethod multimethod extends /;
211            
212 49         106 for my $pkg (@roles) {
213             $builder->do_coercions_for_role($pkg->[0], %opts, reg => $reg, %{$pkg->[1]});
214 49   66     470 }
215             for my $pkg (@classes) {
216 49         142 $builder->do_coercions_for_class($pkg->[0], %opts, reg => $reg, %{$pkg->[1]});
217 57         180 }
  57         240  
218            
219 49         137 for my $pkg (@role_generators) {
220 69         228 $builder->make_role_generator($pkg->[0], %opts, %{$pkg->[1]});
  69         326  
221             }
222             for my $pkg (@class_generators) {
223 49         169 $builder->make_class_generator($pkg->[0], %opts, %{$pkg->[1]});
224 2         5 }
  2         14  
225             for my $pkg (@roles) {
226 49         119 $builder->make_role($pkg->[0], _parent_opts => \%opts, _roles => \@roles, %opts, %{$pkg->[1]});
227 2         7 }
  2         9  
228             for my $pkg (@classes) {
229 49         109 $builder->make_class($pkg->[0], _parent_opts => \%opts, _classes => \@classes, _roles => \@roles, %opts, %{$pkg->[1]});
230 57         184 }
  57         206  
231            
232 49         136 if (keys %modifiers) {
233 69         314 $builder->patch_package( $opts{'factory_package'}, prefix => $opts{'prefix'}, %modifiers );
  69         340  
234             }
235            
236 49 100       219 %_cached_moo_helper = (); # cleanups
237 2         11 }
238              
239             my $builder = shift;
240 49         3889 my ($kind, $pkg, $opts) = @_;
241             defined $pkg or return;
242             $INC{Module::Runtime::module_notional_filename($pkg)} = $opts->{caller_file} || 1;
243             if (defined $opts->{factory_package}) {
244 304     304   472 no strict 'refs';
245 304         583 my $idx = \%{ $opts->{factory_package} . '::PACKAGES' };
246 304 100       619 $idx->{$pkg} = $kind;
247 302   100     1243 }
248 302 100       7130 }
249 40     40   284  
  40         103  
  40         33208  
250 291         366 my $builder = shift;
  291         1011  
251 291         1570 my ($opts) = @_;
252             for my $key (sort keys %$opts) {
253             if ($key =~ /^(class|role|class_generator|role_generator):((?:::)?[^:].*)$/) {
254             my ($kind, $pkg) = ($1, $2);
255             my $val = delete $opts->{$key};
256 49     49 0 83 if (ref $val) {
257 49         101 push @{ $opts->{$kind} ||= [] }, $pkg, $val;
258 49         355 }
259 548 100       1101 elsif ($val eq 1 or not defined $val) {
260 55         206 push @{ $opts->{$kind} ||= [] }, $pkg;
261 55         99 }
262 55 100 33     118 else {
    50          
263 53   100     72 $builder->croak("$kind\:$pkg shortcut should be '1' or reference");
  53         267  
264             }
265             }
266 2   100     2 }
  2         8  
267             return;
268             }
269 0         0  
270             shift;
271             my ($roleopts, $opts) = @_;
272             return;
273 49         128 }
274              
275             shift;
276             my ($classopts, $opts) = @_;
277 57     57 0 73 return;
278 57         92 }
279 57         107  
280             shift;
281             my ($cgenopts, $opts) = @_;
282             return;
283 69     69 0 101 }
284 69         121  
285 69         135 shift;
286             my ($rgenopts, $opts) = @_;
287             return;
288             }
289 2     2 0 3  
290 2         3 my $me = shift;
291 2         5 my ($name, $prefix, $parent) = @_;
292             my $sigil = "";
293             if ($name =~ /^[@%\$]/) {
294             $sigil = substr $name, 0, 1;
295 2     2 0 2 $name = substr $name, 1;
296 2         11 }
297 2         13 $name = join("::", '', $parent->$_handle_list, $1) if (defined $parent and $name =~ /^\+(.+)/);
298             return $sigil.$2 if $name =~ /^(main)?::(.+)$/;
299             $prefix ? $sigil.join("::", $prefix, $name) : $sigil.$name;
300             }
301 909     909 1 1171  
302 909         1607 shift;
303 909         1126 my ($name, $prefix) = @_;
304 909 50       2349 $name =~ s/^(main)?::// while $name =~ /^(main)?::/;
305 0         0 $prefix = '' unless defined $prefix;
306 0         0 my $stub = $name;
307             if (length $prefix and lc substr($name, 0, length $prefix) eq lc $prefix) {
308 909 100 100     2229 $stub = substr($name, 2 + length $prefix);
309 909 100       3235 }
310 619 100       2260 $stub =~ s/^(main)?::// while $stub =~ /^(main)?::/;
311             $stub =~ s/::/_/g;
312             $stub;
313             }
314 402     402 1 530  
315 402         679 my $me = shift;
316 402         957 my $pfx = shift;
317 402 100       768
318 402         521 my @packages;
319 402 100 100     1799 while ( @_ ) {
320 380         1906 my $qname = $me->qualify_name( shift, $pfx );
321             push @packages, (
322 402         913 ref($_[0]) ? $qname->generate_package( shift->$_handle_list ) : $qname
323 402         742 );
324 402         863 }
325            
326             return @packages;
327             }
328 3     3   4  
329 3         5 my %_anony_counter;
330             my $me = shift;
331 3         4 my ($pfx) = @_;
332 3         8 my ($class, @roles) = $me->_helper_for_get_class( @_ );
333 5         11
334 5 100       19 return make_absolute_package_name($class) unless @roles;
335            
336             no warnings qw( uninitialized numeric );
337            
338             my $new_class = $class->can('with_traits')
339 3         9 ? $class->with_traits( @roles )
340             : $me->make_class(
341             make_absolute_package_name(
342             sprintf('%s::__WITH_TRAITS__::__GEN%06d__', $class, ++$_anony_counter{$class})
343             ),
344 2     2   3 extends => make_absolute_package_name($class),
345 2         7 with => [ map make_absolute_package_name($_), @roles ],
346 2         6 prefix => do { no strict 'refs'; ${"$class\::PREFIX"} } || $pfx,
347             factory => $class->FACTORY,
348 2 100       11 toolkit => do { no strict 'refs'; ${"$class\::TOOLKIT"} } || 'Moo',
349             );
350 40     40   319
  40         85  
  40         3695  
351             return make_absolute_package_name($new_class);
352             }
353              
354             my $me = shift;
355             my ($pfx) = @_;
356             my (@roles) = $me->_helper_for_get_class( @_ );
357            
358             return make_absolute_package_name($roles[0]) if @roles==1;
359            
360 40     40   254 no warnings qw( uninitialized numeric );
  40         104  
  40         2666  
361            
362 40 50 33 40   397 my $new_role = $me->make_role(
  40   50     198  
  40         4862  
  1         18  
363             make_absolute_package_name(
364             sprintf('%s::__WITH_TRAITS__::__GEN%06d__', $roles[0], ++$_anony_counter{$roles[0]})
365 1         6 ),
366             with => [ map make_absolute_package_name($_), @roles ],
367             prefix => do { no strict 'refs'; ${$roles[0]."::PREFIX"} } || $pfx,
368             toolkit => do { no strict 'refs'; ${$roles[0]."::TOOLKIT"} } || 'Moo',
369 1     1   3 );
370 1         4
371 1         3 return make_absolute_package_name($new_role);
372             }
373 1 50       13  
374             shift;
375 40     40   266 require Carp;
  40         79  
  40         3134  
376             goto \&Carp::croak;
377             }
378              
379             my $none;
380             no strict 'refs';
381             no warnings 'once';
382 40     40   268 my $builder = shift;
  40         110  
  40         1789  
383 40   0 40   231 my ($lib, %opts) = @_;
  40   0     338  
  40         5056  
  0         0  
384             return if exists &{"$lib\::_mooxpress_add_type"};
385             my ($version, $authority) = ($opts{version}, $opts{authority});
386 0         0 my %types_hash;
387             require Type::Tiny::Role;
388             require Type::Tiny::Class;
389             require Type::Registry;
390 0     0 1 0 use_module('Type::Library')->import::into($lib, -base);
391 0         0 $builder->_mark_package_as_loaded('type library' => $lib, \%opts);
392 0         0 my $adder = sub {
393             my $me = shift;
394             my ($name, $kind, $target, $coercions) = @_;
395             return if $types_hash{$kind}{$target};
396             my $tc_class = 'Type::Tiny::' . ucfirst($kind);
397 40     40   265 my $tc_obj = $tc_class->new(
  40         81  
  40         1132  
398 40     40   221 name => $name,
  40         90  
  40         88997  
399 49     49 1 99 library => $me,
400 49         267 $kind => $target,
401 49 100       82 );
  49         244  
402 47         155 $types_hash{$kind}{$target} = $tc_obj;
403 47         76 $types_hash{'any'}{$target} = $tc_obj;
404 47         14623 $me->add_type($tc_obj);
405 47         85755 Type::Registry->for_class($opts{factory_package})->add_type($tc_obj)
406 47         61193 if defined $opts{factory_package};
407 47         204 if ($coercions) {
408 47         22101 $none ||= ~Any;
409             $tc_obj->coercion->add_type_coercions($none, 'die()');
410 191     191   270 }
411 191         401 };
412 191 100       1506 my $getter = sub {
413 190         472 my $me = shift;
414 190         889 my ($kind, $target) = @_;
415             if ($target =~ /^([@%])(.+)$/) {
416             my $sigil = $1;
417             $target = $2;
418             if ($sigil eq '@') {
419 190         25966 return ArrayRef->of($types_hash{$kind}{$target})
420 190         429 if $types_hash{$kind}{$target};
421 190         1940 }
422             elsif ($sigil eq '%') {
423 190 100       187514 return HashRef->of($types_hash{$kind}{$target})
424 190 100       7011 if $types_hash{$kind}{$target};
425 7   33     44 }
426 7         858 }
427             $types_hash{$kind}{$target};
428 47         293 };
429             if (defined $opts{'factory_package'} or not exists $opts{'factory_package'}) {
430 224     224   123483 require B;
431 224         371 eval(
432 224 100       570 sprintf '
433 6         20 package %s;
434 6         18 sub type_library { %s };
435 6 50       25 sub get_type_for_package { shift->type_library->get_type_for_package(@_) };
    0          
436             1;
437 6 50       99 ',
438             $opts{'factory_package'},
439             B::perlstring($lib),
440             ) or $builder->croak("Could not install type library methods into factory package: $@");
441 0 0       0 }
442             *{"$lib\::_mooxpress_add_type"} = $adder;
443             *{"$lib\::get_type_for_package"} = $getter;
444 218         604 ${"$lib\::VERSION"} = $version if defined $version;
445 47         193 ${"$lib\::AUTHORITY"} = $authority if defined $authority;
446 47 100 66     224 }
447 45         225  
448             my $builder = shift;
449             my ($name, %opts) = @_;
450             return unless $opts{'type_library'};
451             $builder->croak("Roles ($name) cannnot extend things") if $opts{extends};
452             $builder->_make_type($name, %opts, is_role => 1);
453             }
454              
455 45 50   3 0 4031 my $builder = shift;
  3     16 0 18  
  16       0 83  
          0    
456             my ($name, %opts) = @_;
457             return unless $opts{'type_library'};
458             $builder->_make_type($name, %opts, is_role => 0);
459 47         152 }
  47         276  
460 47         93  
  47         174  
461 47 100       152 my $builder = shift;
  7         25  
462 47 100       162 my ($name, %opts) = @_;
  7         29  
463             my $qname = $builder->qualify_name($name, $opts{prefix});
464              
465             if ($opts{'type_library'}) {
466 61     61 1 150 my $class_type_name = $opts{'class_type_name'}
467 59         328 || sprintf('%sClass', $builder->type_name($qname, $opts{'prefix'}));
468 59 50       176 my $class_type = $opts{'type_library'}->add_type({
469 59 50       159 name => $class_type_name,
470 59         326 parent => ClassName,
471             constraint => sprintf('$_->can("GENERATOR") && ($_->GENERATOR eq %s)', B::perlstring($qname)),
472             });
473            
474 132     132 1 216 my $instance_type_name = $opts{'instance_type_name'}
475 132         615 || sprintf('%sInstance', $builder->type_name($qname, $opts{'prefix'}));
476 132 50       311 my $instance_type = $opts{'type_library'}->add_type({
477 132         557 name => $instance_type_name,
478             parent => Object,
479             constraint => sprintf('$_->can("GENERATOR") && ($_->GENERATOR eq %s)', B::perlstring($qname)),
480             });
481 2     2 0 4
482 2         12 if ($opts{'factory_package'}) {
483 2         7 my $reg = Type::Registry->for_class($opts{'factory_package'});
484             $reg->add_type($_) for $class_type, $instance_type;
485 2 50       8 }
486             }
487 2   33     10 }
488 2         10  
489             my $builder = shift;
490             my ($name, %opts) = @_;
491             my $qname = $builder->qualify_name($name, $opts{prefix}, $opts{extends});
492            
493             my $type_name = $opts{'type_name'} || $builder->type_name($qname, $opts{'prefix'});
494            
495 2   33     3566 if ($opts{'type_library'}->can('_mooxpress_add_type')) {
496 2         10 $opts{'type_library'}->_mooxpress_add_type(
497             $type_name,
498             $opts{is_role} ? 'role' : 'class',
499             $qname,
500             !!$opts{coerce},
501             );
502 2 50       2901 }
503 2         12  
504 2         31 if (defined $opts{'with'}) {
505             my @tag_roles = grep /\?$/, $opts{'with'}->$_handle_list;
506             for my $role (@tag_roles) {
507             $role =~ s/\?$//;
508             my %opts_clone = %opts;
509             delete $opts_clone{$_} for @delete_keys;
510 191     191   317 $builder->make_type_for_role($role, %opts_clone);
511 191         804 }
512 191         618 }
513              
514 191   66     772 if (defined $opts{'subclass'} and not $opts{'is_role'}) {
515             my @subclasses = $opts{'subclass'}->$_handle_list_add_nulls;
516 191 50       1168 while (@subclasses) {
517             my ($sc_name, $sc_opts) = splice @subclasses, 0, 2;
518             my %opts_clone = %opts;
519             delete $opts_clone{$_} for @delete_keys;
520             $builder->make_type_for_class($sc_name, %opts_clone, extends => make_absolute_package_name($qname), $sc_opts->$_handle_list);
521             }
522 191 100       759 }
523             }
524              
525 191 100       4801 my $builder = shift;
526 75         220 my ($name, %opts) = @_;
527 75         180 $builder->_do_coercions($name, %opts, is_role => 1);
528 2         5 }
529 2         13  
530 2         15 my $builder = shift;
531 2         9 my ($name, %opts) = @_;
532             $builder->_do_coercions($name, %opts, is_role => 0);
533             }
534              
535 191 100 66     2403 my $builder = shift;
536 15         108 my ($name, %opts) = @_;
537 15         603
538 63         150 my $qname = $builder->qualify_name($name, $opts{prefix}, $opts{extends});
539 63         424 my $mytype;
540 63         432 if ($opts{type_library}) {
541 63         205 $mytype = $opts{type_library}->get_type_for_package($opts{'is_role'} ? 'role' : 'class', $qname);
542             }
543            
544             if ($opts{coerce}) {
545             if ($opts{abstract}) {
546             require Carp;
547 57     57 0 87 Carp::croak("abstract class $qname cannot have coercions")
548 57         332 }
549 57         242 my $method_installer = $opts{toolkit_install_methods} || ("install_methods");
550             my @coercions = @{$opts{'coerce'} || []};
551            
552             while (@coercions) {
553 132     132 0 203 my $type = shift @coercions;
554 132         618 if (!ref $type) {
555 132         554 my $tc = $opts{reg}->lookup($type);
556             $type = $tc if $tc;
557             }
558             my $method_name = shift @coercions;
559 189     189   250 defined($method_name) && !ref($method_name)
560 189         750 or $builder->croak("No method name found for coercion to $qname from $type");
561            
562 189         577 my $coderef;
563 189         313 $coderef = shift @coercions if is_CodeRef $coercions[0];
564 189 50       1493
565 189 100       655 if ($coderef) {
566             $builder->$method_installer(
567             $qname,
568 189 100       420 { $method_name => sub { local $_ = $_[1]; &$coderef } },
569 7 50       23 );
570 0         0 }
571 0         0
572             if ($mytype) {
573 7   50     35 require B;
574 7 50       10 $mytype->coercion->add_type_coercions($type, sprintf('%s->%s($_)', B::perlstring($qname), $method_name));
  7         37  
575             }
576 7         21 }
577 7         18 }
578 7 100       23
579 3         19 if (defined $opts{'subclass'} and not $opts{'is_role'}) {
580 3 50       67 my @subclasses = $opts{'subclass'}->$_handle_list_add_nulls;
581             while (@subclasses) {
582 7         26 my ($sc_name, $sc_opts) = splice @subclasses, 0, 2;
583 7 50 33     35 my %opts_clone = %opts;
584             delete $opts_clone{$_} for @delete_keys;
585             $builder->do_coercions_for_class($sc_name, %opts_clone, extends => make_absolute_package_name($qname), $sc_opts->$_handle_list);
586 7         16 }
587 7 50       37 }
588             }
589 7 50       25  
590             my $builder = shift;
591             my ($name, %opts) = @_;
592 14     14   52
  14         55  
593 7         53 if ($opts{interface}) {
594             for my $key (qw/ can before after around has multimethod /) {
595             if ($opts{$key}) {
596 7 50       42 require Carp;
597 7         75 my $qname = $builder->qualify_name($name, $opts{prefix});
598 7         35 Carp::croak("interface $qname cannot have $key");
599             }
600             }
601             }
602              
603 189 100 66     1936 for my $key (qw/ abstract extends subclass factory overload multifactory /) {
604 15         52 if ($opts{$key}) {
605 15         602 require Carp;
606 63         119 my $qname = $builder->qualify_name($name, $opts{prefix});
607 63         338 my $kind = $opts{interface} ? 'interface' : 'role';
608 63         415 Carp::croak("$kind $qname cannot have $key");
609 63         202 }
610             }
611            
612             $builder->_make_package($name, %opts, is_role => 1);
613             }
614              
615 71     71 1 118 my $builder = shift;
616 71         406 my ($name, %opts) = @_;
617            
618 71 50       188 if ($opts{abstract}) {
619 0         0 for my $key (qw/ factory /) {
620 0 0       0 if ($opts{$key}) {
621 0         0 require Carp;
622 0         0 my @isa = $opts{extends} ? $builder->_expand_isa($opts{prefix}, $opts{extends}) : ();
623 0         0 my $qname = $builder->qualify_name($name, $opts{prefix}, @isa);
624             Carp::croak("abstract class $qname cannot have $key");
625             }
626             }
627             }
628 71         141
629 426 50       720 for my $key (qw/ interface before_apply after_apply requires /) {
630 0         0 if ($opts{$key}) {
631 0         0 require Carp;
632 0 0       0 my @isa = $opts{extends} ? $builder->_expand_isa($opts{prefix}, $opts{extends}) : ();
633 0         0 my $qname = $builder->qualify_name($name, $opts{prefix}, @isa);
634             my $kind = $opts{abstract} ? 'abstract class' : 'class';
635             Carp::croak("$kind $qname cannot have $key");
636             }
637 71         431 }
638            
639             $builder->_make_package($name, %opts, is_role => 0);
640             }
641 140     140 1 240  
642 140         1181 my $builder = shift;
643             my ($name, %opts) = @_;
644 140 100       391 $builder->_make_package_generator($name, %opts, is_role => 1);
645 1         3 }
646 1 50       3  
647 0         0 my $builder = shift;
648 0 0       0 my ($name, %opts) = @_;
649 0         0 $builder->_make_package_generator($name, %opts, is_role => 0);
650 0         0 }
651              
652             my ($builder, $pfx, $ext) = @_;
653             my @raw = $ext->$_handle_list;
654             my @isa;
655 140         287 my $changed;
656 560 50       1013 while (@raw) {
657 0         0 if (@raw > 1 and ref($raw[1])) {
658 0 0       0 my $gen = $builder->qualify_name(shift(@raw), $pfx);
659 0         0 my @args = shift(@raw)->$_handle_list;
660 0 0       0 push @isa, make_absolute_package_name($gen->generate_package(@args));
661 0         0 $changed++;
662             }
663             else {
664             push @isa, shift(@raw);
665 140         936 }
666             }
667             @$ext = @isa if $changed;;
668             map $builder->qualify_name($_, $pfx), @isa;
669 2     2 0 4 }
670 2         12  
671 2         11 my $nondeep;
672             my $builder = shift;
673             my ($name, %opts) = @_;
674            
675 2     2 0 4 my @isa = $opts{extends} ? $builder->_expand_isa($opts{prefix}, $opts{extends}) : ();
676 2         11 my $qname = $builder->qualify_name($name, $opts{prefix}, @isa);
677 2         12 my $tn = $builder->type_name($qname, $opts{prefix});
678              
679             no strict 'refs';
680             no warnings 'once';
681 84     84   175 return if ${"$qname\::BUILT"};
682 84         165
683 84         144 $builder->_mark_package_as_loaded(($opts{is_role} ? 'role' : 'class') => $qname, \%opts);
684            
685 84         187 if (!exists $opts{factory} and !exists $opts{multifactory}) {
686 84 100 66     259 $opts{factory} = $opts{abstract} ? undef : sprintf('new_%s', lc $tn);
687 2         17 }
688 2         6
689 2         60 my $toolkit = {
690 2         10 moo => 'Moo',
691             moose => 'Moose',
692             mouse => 'Mouse',
693 82         215 }->{lc $opts{toolkit}} || $opts{toolkit};
694            
695             if ($opts{is_role}) {
696 84 100       169 use_module("$toolkit\::Role")->import::into($qname);
697 84         228 use_module("namespace::autoclean")->import::into($qname);
698             }
699             else {
700             use_module($toolkit)->import::into($qname);
701             use_module("MooX::TypeTiny")->import::into($qname) if $toolkit eq 'Moo' && eval { require MooX::TypeTiny; 'MooX::TypeTiny'->VERSION('0.002001') };
702 211     211   354 use_module("MooseX::XSAccessor")->import::into($qname) if $toolkit eq 'Moose' && eval { require MooseX::XSAccessor };
703 211         942 use_module("namespace::autoclean")->import::into($qname);
704            
705 211 100       1713 my $method = "extend_class_" . lc $toolkit;
706 211         603 if (@isa) {
707 211         724
708             # Check that each parent class exists
709 40     40   288 PARENT: for my $parent_qname ( @isa ) {
  40         92  
  40         1189  
710 40     40   201 no strict 'refs';
  40         75  
  40         9898  
711 211 100       281 no warnings 'once';
  211         1375  
712             next if ${"$parent_qname\::BUILT"};
713 204 100       860 next if eval { use_module($parent_qname); 1 };
714            
715 204 100 100     861 # Parent class is not already built by MooX::Press.
716 186 100       861 # Parent class is not loadable.
717             # This is going to be an issue when we try to extend it.
718            
719             my @dfns = @{ $opts{_classes} || [] } or last PARENT;
720            
721             DFN: for my $dfn ( @dfns ) {
722             my ( $dfn_shortname, $dfn_spec ) = @$dfn;
723 204   33     981 my %dfn_spec = %opts;
724             delete $dfn_spec{$_} for @delete_keys;
725 204 100       590 %dfn_spec = ( %dfn_spec, %$dfn_spec );
726 65         244 my @dfn_isa = $dfn_spec{extends} ? $builder->_expand_isa($dfn_spec{prefix}, $dfn_spec{extends}) : ();
727 65         237029 my $dfn_qname = $builder->qualify_name($dfn_shortname, $dfn_spec{prefix}, @dfn_isa);
728            
729             # We have found a saviour!
730 139         445 if ($parent_qname eq $dfn_qname) {
731 139 100 66     333924 $builder->make_class(
  88         10789  
  88         8935  
732 139 50 66     231474 make_absolute_package_name($parent_qname),
  26         3202  
733 139         575 %dfn_spec,
734             );
735 139         29873 last DFN;
736 139 100       475 }
737             }
738             }
739 81         202
740 40     40   251 $builder->$method($qname, \@isa);
  40         83  
  40         1207  
741 40     40   205 }
  40         95  
  40         8812  
742 81 100       109 }
  81         377  
743 1 50       2
  1         3  
  0         0  
744             my $reg;
745             if ($opts{factory_package}) {
746             require Type::Registry;
747             'Type::Registry'->for_class($qname)->set_parent(
748             'Type::Registry'->for_class($opts{factory_package})
749 1 50       194 );
  1 50       16  
750             $reg = 'Type::Registry'->for_class($qname);
751 1         4 }
752 3         6
753 3         22 {
754 3         23 no strict 'refs';
755 3         22 no warnings 'once';
756 3 100       13 ${"$qname\::TOOLKIT"} = $toolkit;
757 3         7 ${"$qname\::PREFIX"} = $opts{prefix};
758             ${"$qname\::FACTORY"} = $opts{factory_package};
759             ${"$qname\::TYPES"} = $opts{type_library};
760 3 100       31 ${"$qname\::BUILT"} = 1;
761 1         5 &Internals::SvREADONLY(\${"$qname\::$_"}, 1)
762             for qw/TOOLKIT PREFIX FACTORY TYPES BUILT/;
763             for my $var (qw/VERSION AUTHORITY/) {
764             if (defined $opts{lc $var}) {
765 1         6 ${"$qname\::$var"} = $opts{lc $var};
766             &Internals::SvREADONLY(\${"$qname\::$var"}, 1);
767             }
768             }
769             if ( $opts{factory_package} ) {
770 81         321 eval "sub $qname\::FACTORY { q[".$opts{factory_package}."] }; 1"
771             or $builder->croak("Couldn't create link back to factory $qname\::FACTORY: $@");
772             }
773             }
774 204         35582
775 204 100       612 if (defined $opts{'import'}) {
776 195         929 my @imports = $opts{'import'}->$_handle_list;
777             while (@imports) {
778             my $import = shift @imports;
779 195         968 my @params;
780 195         4066 if (is_HashRef($imports[0])) {
781             @params = %{ shift @imports };
782             }
783             elsif (is_ArrayRef($imports[0])) {
784 40     40   283 @params = @{ shift @imports };
  40         93  
  40         1185  
  204         1031  
785 40     40   205 }
  40         72  
  40         27194  
786 204         287 use_module($import)->import::into($qname, @params);
  204         1044  
787 204         327 }
  204         590  
788 204         290 }
  204         634  
789 204         281
  204         664  
790 204         284 if (my $hook = $opts{'begin'}) {
  204         428  
791 1020         2463 my @coderefs = map {
792 204         454 is_HashRef($_) ? $builder->wrap_coderef(package => $qname, %$_) : $_
793 204         355 } is_ArrayRef($hook) ? @$hook : $hook;
794 408 100       1018 for my $cb (@coderefs) {
795 140         168 $cb->($qname, $opts{is_role} ? 'role' : 'class');
  140         418  
796 140         170 }
  140         329  
797             }
798            
799 204 100       572 if ($opts{overload}) {
800 195 50     0 11269 my @overloads = $opts{overload}->$_handle_list;
          0    
          0    
801             require overload;
802             require Import::Into;
803             'overload'->import::into($qname, @overloads);
804             }
805 204 100       751
806 51         126 if (defined $opts{can}) {
807 51         134 my %methods = $opts{can}->$_handle_list_add_nulls;
808 0         0 $builder->install_methods($qname, \%methods) if keys %methods;
809 0         0 }
810 0 0       0
    0          
811 0         0 if (defined $opts{factory_package_can} and defined $opts{factory_package}) {
  0         0  
812             my %methods = $opts{factory_package_can}->$_handle_list_add_nulls;
813             $builder->install_methods($opts{factory_package}, \%methods) if keys %methods;
814 0         0 }
  0         0  
815            
816 0         0 if (defined $opts{type_library_can} and defined $opts{type_library}) {
817             my %methods = $opts{type_library_can}->$_handle_list_add_nulls;
818             $builder->install_methods($opts{type_library}, \%methods) if keys %methods;
819             }
820 204 100       603
821             if (defined $opts{constant}) {
822 1 50       7 my %constants = $opts{constant}->$_handle_list_add_nulls;
  1 50       6  
823             $builder->install_constants($qname, \%constants) if keys %constants;
824 1         2 }
825 1 50       6
826             if (defined $opts{has}) {
827             $builder->install_attributes($qname, $opts{has}, \%opts);
828             }
829 204 100       2288
830 1         7 if (defined $opts{symmethod}) {
831 1         6 $builder->install_symmethods($qname, $opts{symmethod});
832 1         5 }
833 1         15
834             if (defined $opts{multimethod}) {
835             my @mm = $opts{multimethod}->$_handle_list_add_nulls;
836 204 100       613 while (@mm) {
837 30         130 my ($method_name, $method_spec) = splice(@mm, 0, 2);
838 30 50       349 $builder->install_multimethod($qname, $opts{is_role}?'role':'class', $method_name, $method_spec);
839             }
840             }
841 204 50 33     576
842 0         0 if (defined $opts{with}) {
843 0 0       0 my @roles = $opts{with}->$_handle_list;
844             if (@roles) {
845             my @processed;
846 204 50 33     490 while (@roles) {
847 0         0 if (@roles > 1 and ref($roles[1])) {
848 0 0       0 my $gen = $builder->qualify_name(shift(@roles), $opts{prefix});
849             my @args = shift(@roles)->$_handle_list;
850             push @processed, $gen->generate_package(@args);
851 204 100       461 }
852 5         19 else {
853 5 50       30 my $role_qname = $builder->qualify_name(shift(@roles), $opts{prefix});
854             push @processed, $role_qname;
855             no strict 'refs';
856 204 100       471 no warnings 'once';
857 36         215 if ( $role_qname !~ /\?$/ and not ${"$role_qname\::BUILT"} ) {
858             my ($role_dfn) = grep { $_->[0] eq make_absolute_package_name($role_qname) } @{$opts{_roles}};
859             $builder->make_role(
860 204 100       438 make_absolute_package_name($role_qname),
861 10         61 _parent_opts => $opts{_parent_opts},
862             _roles => $opts{_roles},
863             %{ $opts{_parent_opts} },
864 204 100       2286 %{ $role_dfn->[1] },
865 4         11 ) if $role_dfn;
866 4         91 }
867 4         11 }
868 4 100       20 }
869            
870             my $installer = "apply_roles_" . lc $toolkit;
871             $builder->$installer($qname, $opts{is_role}?'role':'class', \@processed);
872 204 100       1870 }
873 76         271 }
874 76 50       200
875 76         100 if ($opts{is_role} and defined $opts{requires}) {
876 76         157 my $installer = "require_methods_" . lc $toolkit;
877 103 100 100     337 my %requires = $opts{requires}->$_handle_list_add_nulls;
878 1         5 $builder->$installer($qname, \%requires) if keys %requires;
879 1         3 }
880 1         21
881             if (defined $opts{'factory_package'}) {
882             my $fpackage = $opts{'factory_package'};
883 102         287 if ($opts{'factory'}) {
884 102         198 if ($opts{abstract} and $opts{'factory'}->$_handle_list) {
885 40     40   266 require Carp;
  40         64  
  40         1151  
886 40     40   195 Carp::croak("abstract class $qname cannot have factory");
  40         82  
  40         24582  
887 102 100 100     330 }
  100         529  
888 6         9 $builder->install_factories($fpackage, $qname, $opts{'factory'});
  24         41  
  6         13  
889             }
890             if ($opts{multifactory}) {
891             my @mm = $opts{multifactory}->$_handle_list_add_nulls;
892             while (@mm) {
893 6         20 my ($method_name, $method_spec) = splice(@mm, 0, 2);
894 6 50       17 my $old_coderef = $method_spec->{code} or die;
  6         25  
895             my $new_coderef = sub { splice(@_, 1, 0, "$qname"); goto $old_coderef };
896             $builder->install_multimethod($fpackage, 'class', $method_name, { %$method_spec, code => $new_coderef });
897             }
898             }
899             }
900 76         195  
901 76 100       367 for my $modifier (qw(before after around)) {
902             if (defined $opts{$modifier}) {
903             my @methods = $opts{$modifier}->$_handle_list;
904             my $installer = "modify_method_" . lc $toolkit;
905 204 100 100     737 while (@methods) {
906 1         3 my @method_names;
907 1         14 push(@method_names, shift @methods)
908 1 50       27 while (@methods and not ref $methods[0]);
909             my $coderef = $builder->_prepare_method_modifier($qname, $modifier, \@method_names, shift(@methods));
910             $builder->$installer($qname, $modifier, \@method_names, $coderef);
911 204 100       539 }
912 195         386 }
913 195 100       413 }
914 182 50 33     458
915 0         0 if ($opts{is_role}) {
916 0         0 for my $event (qw/ before_apply after_apply /) {
917             if (my $hook = $opts{$event}) {
918 182         644 require Role::Hooks;
919             my @coderefs = map {
920 195 100       616 is_HashRef($_) ? $builder->wrap_coderef(package => $qname, %$_) : $_
921 4         18 } is_ArrayRef($hook) ? @$hook : $hook;
922 4         91 'Role::Hooks'->$event($qname, @coderefs);
923 4         11 }
924 4 50       15 }
925 4     6   19 }
  4         88321  
  4         15  
926 4         32
927             # not role
928             else {
929             if ($toolkit eq 'Moose' && !$opts{'mutable'}) {
930             require Moose::Util;
931 204         1036 my %args = %{ $opts{'definition_context'} or {} };
932 612 100       1679 delete $args{'package'};
933 20         53 Moose::Util::find_meta($qname)->make_immutable(%args);
934 20         55 }
935 20         48
936 20         26 if ($toolkit eq 'Moo' && eval { require MooX::XSConstructor }) {
937 20   66     132 'MooX::XSConstructor'->setup_for($qname);
938             }
939 20         68
940 20         65 if ($opts{abstract}) {
941             my $orig_can = $qname->can('can');
942             my $orig_BUILD = do { no strict 'refs'; exists(&{"$qname\::BUILD"}) ? \&{"$qname\::BUILD"} : sub {} };
943             'namespace::clean'->clean_subroutines($qname, 'new', 'BUILD');
944             $builder->install_methods($qname, {
945 204 100       1247 can => sub {
946 65         144 if ((ref($_[0])||$_[0]) eq $qname and $_[1] eq 'new') { return; };
947 130 100       1546 goto $orig_can;
948 9         441 },
949             BUILD => sub {
950 9 50       4693 if (ref($_[0]) eq $qname) { require Carp; Carp::croak('abstract class'); };
  9 100       49  
951             goto $orig_BUILD;
952 9         48 },
953             });
954             }
955            
956             if (defined $opts{'subclass'}) {
957             my @subclasses = $opts{'subclass'}->$_handle_list_add_nulls;
958             while (@subclasses) {
959 139 100 66     577 my ($sc_name, $sc_opts) = splice @subclasses, 0, 2;
960 26         130 my %opts_clone = %opts;
961 26 100       42 delete $opts_clone{$_} for @delete_keys;
  26         149  
962 26         52 $builder->make_class($sc_name, %opts_clone, extends => make_absolute_package_name($qname), $sc_opts->$_handle_list);
963 26         106 }
964             }
965             }
966 139 50 66     111845
  88         10385  
967 0         0 if (my $hook = $opts{'end'}) {
968             my @coderefs = map {
969             is_HashRef($_) ? $builder->wrap_coderef(package => $qname, %$_) : $_
970 139 100       573 } is_ArrayRef($hook) ? @$hook : $hook;
971 1         6 for my $cb (@coderefs) {
972 40 50   40   266 $cb->($qname, $opts{is_role} ? 'role' : 'class');
  40     4   87  
  40         28281  
  1         3  
  1         4  
  1         10  
  0         0  
973 1         15 }
974             }
975            
976 8 100 33 9   44 if ($opts{type_library} and $opts{type_name}) {
  1   100     4  
977 7         55 my $mytype = $opts{type_library}->get_type_for_package($opts{'is_role'} ? 'role' : 'class', $qname);
978             $mytype->coercion->freeze if $mytype;
979             }
980 2 100   2   9
  1         6  
  1         175  
981 1         9 return $qname;
982             }
983 1         99  
984             my ( $me, $package, %spec ) = ( shift, @_ );
985            
986 139 100       377 my $kind = ( $spec{is_role} or do { require Role::Hooks; 'Role::Hooks'->is_role($package) } )
987 15         55 ? 'role'
988 15         651 : 'class';
989 63         164 delete $spec{is_role};
990 63         566
991 63         531 my $fp =
992 63         288 exists($spec{'factory_package'}) ? delete($spec{'factory_package'}) :
993             $package->can('FACTORY') ? $package->FACTORY :
994             do { no strict 'refs'; no warnings; ${"$package\::FACTORY"} };
995            
996             my $prefix =
997 204 50       1902 exists($spec{'prefix'}) ? delete($spec{'prefix'}) :
998             do { no strict 'refs'; no warnings; ${"$package\::PREFIX"} || $fp };
999 0 0       0
  0 0       0  
1000             my $toolkit =
1001 0         0 exists($spec{'toolkit'}) ? delete($spec{'toolkit'}) :
1002 0 0       0 do { no strict 'refs'; no warnings; ${"$package\::TOOLKIT"} || 'Moo' };
1003            
1004             if ( my $version = delete $spec{version} ) {
1005             no strict 'refs';
1006 204 100 100     808 ${"$package\::VERSION"} = $version;
1007 8 50       83 }
1008 8 50       124
1009             if ( my $auth = delete $spec{authority} ) {
1010             no strict 'refs';
1011 204         2014 ${"$package\::AUTHORITY"} = $auth;
1012             }
1013            
1014             if ( $kind eq 'class' and my $extends = delete $spec{extends} ) {
1015 10     11 0 71 my @isa = $me->_expand_isa( $prefix, $extends );
1016             if ( $package->isa("$toolkit\::Object") ) {
1017 11 100 66     63 my $method = "extend_class_" . lc $toolkit;
1018             $me->$method( $package, \@isa );
1019             }
1020 9         227 else {
1021             no strict 'refs';
1022             no warnings 'once';
1023             @{"$package\::ISA"} = @isa;
1024             }
1025 40 100   40   282 }
  40 50   40   86  
  40         1316  
  40         206  
  40         70  
  40         2601  
  8         167  
  6         6068  
  3         10  
1026            
1027             if ( $kind eq 'class' and my $overload = delete $spec{overload} ) {
1028             require overload;
1029 40 100   40   259 require Import::Into;
  40 100   40   88  
  40         1072  
  40         194  
  40         89  
  40         2943  
  11         615  
  6         8  
  12         9238  
1030             'overload'->import::into( $package, $overload->$_handle_list );
1031             }
1032            
1033 40 100   40   236 if ( my @coercions = @ { delete $spec{coerce} or [] } ) {
  40 50   40   89  
  40         1042  
  40         196  
  40         91  
  40         2347  
  11         6430  
  8         19  
  11         625  
1034             my $to_type = $fp->type_library->get_type_for_package( any => $package );
1035 8 50       30 while ( @coercions ) {
1036 40     40   216 my $from_type = 'Type::Registry'->for_class( $package )->lookup( shift @coercions );
  40         75  
  40         2090  
1037 0         0 my $via_method = shift @coercions;
  0         0  
1038             if ( is_CodeRef $coercions[0] or is_HashRef $coercions[0] ) {
1039             my $coderef = shift @coercions;
1040 11 50       618 'MooX::Press'->install_methods( $package, { $via_method => sub { local $_ = $_[1]; &$coderef } } );
1041 40     40   238 }
  40         78  
  40         4434  
1042 0         0 $to_type->coercion->add_type_coercions(
  0         0  
1043             $from_type,
1044             sprintf( '%s->%s($_)', B::perlstring($package), $via_method ),
1045 8 100 100     45 );
1046 1         5 }
1047 1 50       8 }
1048 1         4
1049 1         4 if ( my $methods = delete $spec{can} ) {
1050             $me->install_methods( $package, $methods );
1051             }
1052 40     40   250
  40         66  
  40         1103  
1053 40     40   261 if ( my $constants = delete $spec{constant} ) {
  40         91  
  40         32648  
1054 0         0 $me->install_constants( $package, $constants );
  0         0  
1055             }
1056            
1057             if ( my $atts = delete $spec{has} ) {
1058 8 50 66     119 $me->install_attributes( $package, $atts );
1059 0         0 }
1060 0         0
1061 0         0 if ( my $symm = delete $spec{symmethod} ) {
1062             $me->install_symmethods($package, $symm);
1063             }
1064 8 50       14
  8 50       58  
1065 0         0 if ( my $multimethods = delete $spec{multimethod} ) {
1066 0         0 my @mm = $multimethods->$_handle_list_add_nulls;
1067 0         0 while ( my ( $name, $code ) = splice( @mm, 0, 2 ) ) {
1068 0         0 'MooX::Press'->install_multimethod( $package, $kind, $name, $code );
1069 0 0 0     0 }
1070 0         0 }
1071 0     0   0
  0         0  
  0         0  
1072             if (defined $spec{with}) {
1073             my @roles = $spec{with}->$_handle_list;
1074 0         0 if (@roles) {
1075             my @processed;
1076             while (@roles) {
1077             if (@roles > 1 and ref($roles[1])) {
1078             my $gen = $me->qualify_name(shift(@roles), $prefix);
1079             my @args = shift(@roles)->$_handle_list;
1080 8 100       27 push @processed, $gen->generate_package(@args);
1081 4         12 }
1082             else {
1083             my $role_qname = $me->qualify_name(shift(@roles), $prefix);
1084 8 100       27 push @processed, $role_qname;
1085 1         5 }
1086             }
1087             my $installer = "apply_roles_" . lc $toolkit;
1088 8 100       21 $me->$installer($package, $kind, \@processed);
1089 1         5 }
1090             }
1091            
1092 8 50       22 if ( $kind eq 'class' ) {
1093 0         0
1094             if ( $fp and my $factory = delete $spec{factory} ) {
1095             $me->install_factories( $fp, $package, $factory );
1096 8 100       22 }
1097 1         4
1098 1         29 if ( $fp and my $factory = delete $spec{multifactory} ) {
1099 2         92 my @mm = $factory->$_handle_list_add_nulls;
1100             while (@mm) {
1101             my ($method_name, $method_spec) = splice(@mm, 0, 2);
1102             my $old_coderef = $method_spec->{code} or die;
1103 8 100       95 my $new_coderef = sub { splice(@_, 1, 0, "$package"); goto $old_coderef };
1104 2         7 $me->install_multimethod( $fp , 'class', $method_name, { %$method_spec, code => $new_coderef });
1105 2 50       7 }
1106 2         33 }
1107 2         6
1108 2 50 33     9 #TODO: subclass???
1109 0         0 }
1110 0         0
1111 0         0 for my $modifier ( qw/ before after around / ) {
1112             my @mm = delete($spec{$modifier})->$_handle_list or next;
1113             require Class::Method::Modifiers;
1114 2         12 my @names;
1115 2         7 while ( @mm ) {
1116             if ( is_ArrayRef $mm[0] ) {
1117             push @names, @{ shift @mm };
1118 2         9 }
1119 2         12 elsif ( is_Str $mm[0] ) {
1120             push @names, shift @mm;
1121             }
1122             else {
1123 8 100       34 my $coderef = $me->_prepare_method_modifier( $package, $modifier, [@names], shift(@mm) );
1124             Class::Method::Modifiers::install_modifier( $package, $modifier, @names, $coderef );
1125 7 50 66     36 @names = ();
1126 0         0 }
1127             }
1128             }
1129 7 50 66     28
1130 0         0 return %spec;
1131 0         0 }
1132 0         0  
1133 0 0       0 my ($builder, $fpackage, $qname, $factories) = @_;
1134 0     3   0 my $to_type;
  0         0  
  0         0  
1135 0         0 my @methods = $factories->$_handle_list;
1136             while (@methods) {
1137             my @method_names;
1138             push(@method_names, shift @methods)
1139             while (@methods and not ref $methods[0]);
1140             my $coderef = shift(@methods) || \1;
1141             NAME: for my $name (@method_names) {
1142 8         26 no warnings 'closure';
1143 24 100       49 if (is_CodeRef $coderef) {
1144 4         21 eval "package $fpackage; sub $name :method { splice(\@_, 1, 0, '$qname'); goto \$coderef }; 1"
1145 4         7 or $builder->croak("Could not create factory $name in $fpackage: $@");
1146 4         11 }
1147 8 50       32 elsif (is_ScalarRef $coderef) {
    100          
1148 0         0 my $target = $$coderef;
  0         0  
1149             if ($target eq 1) {
1150             # default factory shouldn't overwrite manually created one
1151 4         22 next NAME if $fpackage->can($name);
1152             $target = 'new';
1153             }
1154 4         24 eval "package $fpackage; sub $name :method { shift; '$qname'->$target\(\@_) }; 1"
1155 4         19 or $builder->croak("Couldn't create factory $name in $fpackage: $@");
1156 4         1055 }
1157             elsif (is_HashRef $coderef) {
1158             my %meta = %$coderef;
1159             $meta{curry} ||= [$qname];
1160            
1161 8         37 if ( match('coercion', $meta{attributes}) or match('coerce', $meta{attributes}) ) {
1162             my @sigtypes = grep !is_HashRef($_), @{$meta{signature}};
1163            
1164             $to_type ||= $fpackage->type_library->get_type_for_package( any => $qname );
1165 182     182 0 510
1166 182         230 $builder->croak('Factories used as coercions must take exactly one positional argument')
1167 182         395 unless is_ArrayRef( $meta{signature} ) && 1==@sigtypes && !$meta{named};
1168 182         467
1169 191         253 $builder->croak("Too late to add coercion to $to_type")
1170 191   100     1053 if $to_type->coercion->frozen;
1171            
1172 191   100     592 my $from_type = 'Type::Registry'->for_class($qname)->lookup( $sigtypes[0] );
1173 191         344
1174 40     40   289 $to_type->coercion->add_type_coercions(
  40         91  
  40         18474  
1175 207 100       817 $from_type, sprintf('%s->%s($_)', B::perlstring($fpackage), $name),
    100          
    50          
1176 3 50       255 );
1177            
1178             my @new_attrs = grep !/^coerc/, @{$meta{attributes}};
1179             $meta{attributes} = \@new_attrs;
1180 194         292 }
1181 194 100       474
1182             $builder->install_methods($fpackage, { $name => \%meta });
1183 179 50       1582 }
1184 179         358 else {
1185             die "lolwut?";
1186 194 50       14643 }
1187             }
1188             $builder->_make_exportable_factories($fpackage, @method_names);
1189             }
1190 10         38 }
1191 10   50     53  
1192             my $builder = shift;
1193 10 50 33     123 my ($factory, @methods) = @_;
1194 0         0 foreach my $method ( @methods ) {
  0         0  
1195             eval qq{
1196 0   0     0 package ${factory};
1197             no warnings 'redefine';
1198             sub _generate_${method} :method {
1199 0 0 0     0 sub { q[${factory}]->${method}( \@_ ) };
      0        
1200             }
1201 0 0       0 1;
1202             } or die "Yikes: $@";
1203             }
1204 0         0 no strict 'refs';
1205             push @{ $factory . '::EXPORT_OK' }, @methods;
1206 0         0 push @{ ${ $factory . '::EXPORT_TAGS' }{'factories'} ||= [] }, @methods;
1207             }
1208              
1209             my $builder = shift;
1210 0         0 my ($name, %opts) = @_;
  0         0  
1211 0         0 my $gen = $opts{generator} or die 'no generator code given!';
1212              
1213             my $kind = $opts{is_role} ? 'role' : 'class';
1214 10         53
1215             my $qname = $builder->qualify_name($name, $opts{prefix});
1216            
1217 0         0 $builder->_mark_package_as_loaded("$kind generator" => $qname, \%opts);
1218            
1219             $builder->install_methods(
1220 191         729 $qname,
1221             {
1222             '_generate_package_spec' => $gen,
1223             'generate_package' => sub {
1224             my ($generator_package, @args) = @_;
1225 191     197   331 $builder->generate_package(
1226 191         416 $kind,
1227 198         4839 $generator_package,
1228 214 50   53   12169 \%opts,
  53     33   25956  
  50     21   342  
  40     14   52222  
  32     13   202  
  28     10   953  
  28     7   1552  
  25     7   3722  
  25     7   81  
  18     7   1081  
  14     6   90  
  14     6   27  
  14     6   834  
  13     6   85  
  13     6   33  
  13     6   845  
  10     6   59  
  10     4   19  
  10     4   636  
  7     4   45  
  7     4   13  
  7     4   453  
  7     4   42  
  7         21  
  7         463  
  7         47  
  7         17  
  7         507  
  7         46  
  7         10  
  7         431  
  6         33  
  6         18  
  6         361  
  6         38  
  6         27  
  6         348  
  6         44  
  6         11  
  6         321  
  6         44  
  6         13  
  6         359  
  6         33  
  6         10  
  6         370  
  6         37  
  6         12  
  6         397  
  6         34  
  6         14  
  6         343  
  4         23  
  4         8  
  4         232  
  4         25  
  4         15  
  4         256  
  4         82  
  4         9  
  4         228  
  4         26  
  4         8  
  4         287  
  4         24  
  4         6  
  4         236  
  4         26  
  4         10  
  4         267  
1229             $generator_package->_generate_package_spec(@args),
1230             );
1231             },
1232             },
1233             );
1234            
1235             if ($opts{factory_package}) {
1236             require Type::Registry;
1237 40     40   265 'Type::Registry'->for_class($qname)->set_parent(
  40         75  
  40         34297  
1238 198         11481 'Type::Registry'->for_class($opts{factory_package})
  198         956  
1239 198   100     15882 );
  198         373  
  198         8982  
1240            
1241             my $tn = $builder->type_name($qname, $opts{prefix});
1242             if (!exists $opts{factory}) {
1243 11     14   139 $opts{factory} = 'generate_' . lc $tn;
1244 11         17302 }
1245 11 50       168 my $fp = $opts{factory_package};
1246             my $f = $opts{factory};
1247 11 100       17999 eval qq{
1248             package $fp;
1249 11         162 sub $f :method {
1250             shift;
1251 4         30 q($qname)->generate_package(\@_);
1252             }
1253             };
1254             }
1255            
1256             return $qname;
1257             }
1258 6     13   27  
1259 6         133 my %_generate_counter;
1260             my $builder = shift;
1261             my $kind = shift;
1262             my $generator_package = shift;
1263             my $global_opts = shift;
1264             my %local_opts = ( @_ == 1 ? $_[0] : \@_ )->$_handle_list;
1265            
1266             $generator_package =~ s/^(main)?::// while $generator_package =~ /^(main)?::/;
1267 4         40
1268             my %opts;
1269 4 50       22 for my $key (qw/ extends with has can constant around before after
1270 4         26 toolkit version authority mutable begin end requires import overload
1271             before_apply after_apply symmethod multimethod definition_context /) {
1272             if (exists $local_opts{$key}) {
1273 6         1358 $opts{$key} = delete $local_opts{$key};
1274             }
1275 6         148 }
1276 11 50       14037
1277 11         154 if (keys %local_opts) {
1278             die "bad keys from generator: ".join(", ", sort keys %local_opts);
1279 4         8 }
1280 4         9
1281 11         19466 # must not generate types or factory methods
1282             $opts{factory} = undef;
1283             $opts{multifactory} = undef;
1284             $opts{type_name} = undef;
1285            
1286             $_generate_counter{$generator_package} = 0 unless exists $_generate_counter{$generator_package};
1287             my $qname = sprintf('%s::__GEN%06d__', $generator_package, ++$_generate_counter{$generator_package});
1288            
1289             require Type::Registry;
1290 11         169 'Type::Registry'->for_class($qname)->set_parent(
1291             'Type::Registry'->for_class($generator_package)
1292             );
1293            
1294             if ($kind eq 'class') {
1295 8     18 0 280 my $method = $opts{toolkit_install_constants} || ("install_constants");
1296 8         48 $builder->$method($qname, { GENERATOR => $generator_package });
1297 6         10 }
1298 6         10
1299 12 50       5683 if ($kind eq 'role') {
1300             return $builder->make_role(make_absolute_package_name($qname), %$global_opts, %opts);
1301 12         165 }
1302             else {
1303 12         5606 return $builder->make_class(make_absolute_package_name($qname), %$global_opts, %opts);
1304 12         104 }
1305             }
1306              
1307 138 100       5829 my $builder = shift;
1308 16         115 my ($package, $helpername) = @_;
1309             return $_cached_moo_helper{"$package\::$helpername"}
1310             if $_cached_moo_helper{"$package\::$helpername"};
1311             die "lolwut?" unless $helpername =~ /^(has|with|extends|around|before|after|requires)$/;
1312 12 50       6173 my $is_role = ($INC{'Moo/Role.pm'} && 'Moo::Role'->is_role($package));
1313 6         87 my $tracker = $is_role ? $Moo::Role::INFO{$package}{exports} : $Moo::MAKERS{$package}{exports};
1314             if (ref $tracker) {
1315             $_cached_moo_helper{"$package\::$helpername"} ||= $tracker->{$helpername};
1316             }
1317 6         16 # I hate this...
1318 6         26 $_cached_moo_helper{"$package\::$helpername"} ||= eval sprintf(
1319 6         11 'do { package %s; use Moo%s; my $coderef = \&%s; no Moo%s; $coderef };',
1320             $package,
1321 6 100       30 $is_role ? '::Role' : '',
1322 6         34 $helpername,
1323             $is_role ? '::Role' : '',
1324 6         29 );
1325 6         32 die "BADNESS: couldn't get helper '$helpername' for package '$package'" unless $_cached_moo_helper{"$package\::$helpername"};
1326             $_cached_moo_helper{"$package\::$helpername"};
1327             }
1328              
1329 6 100       160 my ($builder, $qname) = @_;
1330 4   50     42 {
1331 4         25 no strict 'refs';
1332             return ${"$qname\::TOOLKIT"} if ${"$qname\::TOOLKIT"};
1333             }
1334 6 100       21 for my $tk (qw/ Moo Moose Mouse /) {
1335 2         7 return $tk if $qname->isa("$tk\::Object");
1336             }
1337            
1338 4         16 require Role::Hooks;
1339             if (my $detected = 'Role::Hooks'->is_role($qname)) {
1340             return 'Moo' if $detected eq 'Role::Tiny';
1341             return 'Moo' if $detected eq 'Moo::Role';
1342             return 'Moose' if $detected eq 'Moose::Role';
1343 134     141   226 return 'Mouse' if $detected eq 'Mouse::Role';
1344 134         231 }
1345            
1346 134 100       402 'Moo'; # guess
1347 125 50       607 }
1348 125   66     685  
1349 125 100       3031 my ($builder, $qname) = @_;
1350 125 50       351 {
1351 0   0     0 no strict 'refs';
1352             return ${"$qname\::PREFIX"} if ${"$qname\::PREFIX"};
1353             }
1354 125 100 33 40   8165 return undef;
  33 100   33   1106  
  33     20   4386  
  33     20   172  
  33     14   10443  
  33     14   61  
  33     10   142  
  20     10   118  
  20     7   44  
  20     7   78  
  20     4   6226  
  20     4   44  
  20     3   100  
  14     3   92  
  14     3   30  
  14     3   52  
  14     3   3665  
  14     3   30  
  14     3   46  
  10     3   74  
  10     3   23  
  10     3   41  
  10     2   2476  
  10     2   19  
  10     2   39  
  7     2   40  
  7     2   13  
  7     2   27  
  7     2   1808  
  7     2   24  
  7     2   32  
  4     2   22  
  4     2   7  
  4     2   15  
  4     2   905  
  4     2   8  
  4     2   14  
  3     2   18  
  3     2   5  
  3     2   25  
  3     2   776  
  3     2   6  
  3     2   11  
  3     2   18  
  3         71  
  3         15  
  3         680  
  3         7  
  3         10  
  3         18  
  3         6  
  3         11  
  3         757  
  3         6  
  3         10  
  3         20  
  3         14  
  3         14  
  3         636  
  3         5  
  3         10  
  3         19  
  3         3  
  3         17  
  3         750  
  3         5  
  3         10  
  2         10  
  2         3  
  2         8  
  2         1066  
  2         4  
  2         14  
  2         12  
  2         4  
  2         7  
  2         908  
  2         4  
  2         23  
  2         12  
  2         11  
  2         8  
  2         934  
  2         4  
  2         18  
  2         10  
  2         19  
  2         9  
  2         542  
  2         4  
  2         16  
  2         14  
  2         5  
  2         6  
  2         438  
  2         4  
  2         7  
  2         10  
  2         4  
  2         6  
  2         504  
  2         11  
  2         5  
  2         12  
  2         3  
  2         8  
  2         455  
  2         5  
  2         6  
  2         11  
  2         4  
  2         6  
  2         502  
  2         2  
  2         7  
  2         12  
  2         4  
  2         8  
  2         436  
  2         4  
  2         6  
  2         13  
  2         3  
  2         8  
  2         503  
  2         4  
  2         6  
  2         11  
  2         4  
  2         7  
  2         442  
  2         4  
  2         7  
1355             }
1356              
1357             my ($builder, $qname) = @_;
1358             {
1359             no strict 'refs';
1360             return ${"$qname\::TYPES"} if ${"$qname\::TYPES"};
1361 125 50       599 }
1362 125         371
1363             my $factory = $qname->can('FACTORY');
1364             $factory ||= do {
1365             no strict 'refs';
1366 1     8   3 ${"$qname\::FACTORY"} || ${"$qname\::FACTORY"};
1367             };
1368 40     40   316 return $factory->type_library
  40         103  
  40         7088  
  1         2  
1369 1 50       1 if $factory && $factory->can('type_library');
  1         4  
  1         4  
1370            
1371 0         0 return undef;
1372 0 0       0 }
1373              
1374             my ($builder, $qname, $has, $opts) = @_;
1375 0         0 $opts ||= {};
1376 0 0       0
1377 0 0       0 my $prefix = $opts->{prefix} || $builder->_detect_prefix($qname);
1378 0 0       0 my $toolkit = $opts->{toolkit} || $builder->_detect_toolkit($qname);
1379 0 0       0 my $types = $opts->{type_library} || $builder->_detect_type_library($qname);
1380 0 0       0 my $reg = $opts->{reg} || 'Type::Registry'->for_class($qname);
1381             my $installer = 'make_attribute_' . lc $toolkit;
1382            
1383 0         0 my @attrs = $has->$_handle_list_add_nulls;
1384            
1385             my $make_immutable = 0;
1386             my $meta =
1387 4     11   10 ( $toolkit eq 'Moose' ) ? Moose::Util::find_meta( $qname ) :
1388             ( $toolkit eq 'Mouse' ) ? Mouse::Util::find_meta( $qname ) :
1389 40     40   266 undef;
  40         104  
  40         3570  
  4         5  
1390 4 100       5 if ( $meta and $meta->is_immutable ) {
  1         5  
  4         15  
1391             $meta->make_mutable;
1392 3         8 $make_immutable = 1;
1393             }
1394            
1395             while (@attrs) {
1396 1     4   5 my ($attrname, $attrspec) = splice @attrs, 0, 2;
1397            
1398 40     40   260 my %spec_hints;
  40         78  
  40         2803  
  1         2  
1399 1 50       2 if ($attrname =~ /^(\+?)(\$|\%|\@)(.+)$/) {
  1         6  
  1         5  
1400             $spec_hints{isa} ||= {
1401             '$' => ($nondeep ||= ((~ArrayRef)&(~HashRef))),
1402 0         0 '@' => ArrayLike,
1403 0   0     0 '%' => HashLike,
1404 40     40   240 }->{$2};
  40         74  
  40         12857  
1405 0 0       0 no warnings 'uninitialized';
  0         0  
  0         0  
1406             $attrname = $1.$3; # allow plus before sigil
1407 0 0 0     0 }
1408             if ($attrname =~ /^(.+)\!$/) {
1409             $spec_hints{required} = 1;
1410 0         0 $attrname = $1;
1411             }
1412            
1413             (my $buildername = "_build_$attrname") =~ s/\+//;
1414 37     37 0 133 (my $clearername = ($attrname =~ /^_/ ? "_clear$attrname" : "clear_$attrname")) =~ s/\+//;
1415 37   100     127
1416             my %spec =
1417 37   100     157 is_CodeRef($attrspec) ? (is => $opts->{default_is}, lazy => 1, builder => $attrspec, clearer => $clearername) :
1418 37   66     178 is_Object($attrspec) && $attrspec->can('check') ? (is => $opts->{default_is}, isa => $attrspec) :
1419 37   66     110 $attrspec->$_handle_list;
1420 37   33     224
1421 37         342 if (is_CodeRef $spec{builder}) {
1422             my $code = delete $spec{builder};
1423 37         129 $spec{builder} = $buildername;
1424             $builder->install_methods($qname, { $buildername => $code });
1425 37         787 }
1426 37 100       187
    100          
1427             if (defined $spec{clearer} and !ref $spec{clearer} and $spec{clearer} eq 1) {
1428             $spec{clearer} = $clearername;
1429             }
1430 37 50 66     245
1431 0         0 %spec = (%spec_hints, %spec);
1432 0         0 $spec{is} ||= ($opts->{default_is} || 'ro');
1433            
1434             if ($spec{is} eq 'lazy') {
1435 37         120 $spec{is} = 'ro';
1436 58         159 $spec{lazy} = !!1;
1437             $spec{builder} ||= $buildername unless exists $spec{default};
1438 58         85 }
1439 58 100       303 elsif ($spec{is} eq 'private') {
1440             $spec{is} = 'rw';
1441             $spec{lazy} = !!1;
1442             $spec{init_arg} = undef;
1443             $spec{lexical} = !!1;
1444 8   66     139 }
      33        
1445 40     40   294
  40         78  
  40         53272  
1446 8         12521 if ($spec{does}) {
1447             my $target = $builder->qualify_name(delete($spec{does}), $prefix);
1448 58 100       182 $spec{isa} ||= $types->get_type_for_package(role => $target) if $types;
1449 9         26 $spec{isa} ||= ConsumerOf->of($target);
1450 9         27 }
1451            
1452             if ($spec{isa} && !ref $spec{isa}) {
1453 58         171 my $target = $builder->qualify_name(delete($spec{isa}), $prefix);
1454 58 50       202 $spec{isa} ||= $types->get_type_for_package(class => $target) if $types;
1455             $spec{isa} ||= InstanceOf->of($target);
1456             }
1457            
1458 58 100 66     362 if ($spec{enum}) {
    100          
1459             $spec{isa} = Enum->of(@{delete $spec{enum}});
1460             }
1461 58 100       397
1462 3         7 if (is_Object($spec{type}) and $spec{type}->can('check')) {
1463 3         7 $spec{isa} = delete $spec{type};
1464 3         13 }
1465             elsif ($spec{type}) {
1466             $reg ||= 'Type::Registry'->for_class($qname);
1467 58 50 100     219 $spec{isa} = $reg->lookup(delete $spec{type});
      66        
1468 0         0 }
1469            
1470             if (ref $spec{isa} && !exists $spec{coerce} && $spec{isa}->has_coercion) {
1471 58         201 $spec{coerce} = 1;
1472 58   100     312 }
      66        
1473            
1474 58 100       226 if ($toolkit ne 'Moo') {
    100          
1475 1         2 if (defined $spec{trigger} and !ref $spec{trigger} and $spec{trigger} eq 1) {
1476 1         3 $spec{trigger} = sprintf('_trigger_%s', $attrname);
1477 1 50 33     6 }
1478             if (defined $spec{trigger} and !ref $spec{trigger}) {
1479             my $trigger_method = delete $spec{trigger};
1480 2         5 $spec{trigger} = sub { shift->$trigger_method(@_) };
1481 2         3 }
1482 2         4 if ($spec{is} eq 'rwp') {
1483 2         9 $spec{is} = 'ro';
1484             $spec{writer} = '_set_'.$attrname unless exists $spec{writer};
1485             }
1486 58 50       155 }
1487 0         0
1488 0 0 0     0 if (is_CodeRef $spec{coerce}) {
1489 0   0     0 $spec{isa} = $spec{isa}->no_coercions->plus_coercions(Types::Standard::Any, $spec{coerce});
1490             $spec{coerce} = !!1;
1491             }
1492 58 100 100     204
1493 7         27 if ( is_ScalarRef $spec{default} ) {
1494 7 50 33     60 require Ask::Question;
1495 7   33     35 my $text = ${ $spec{default} };
1496             $spec{default} = 'Ask::Question'->new( { text => $text } );
1497             }
1498 58 100       361
1499 8         41 if ( is_Object $spec{default} and $spec{default}->isa('Ask::Question') ) {
  8         108  
1500             my %spec_copy = %spec;
1501             my $default = delete $spec_copy{default};
1502 58 100 66     155525
    100          
1503 3         41 if ( $spec{isa} and not $default->has_type ) {
1504             $default->_set_type( $spec{isa} );
1505             }
1506 9   33     27 if ( not $default->has_spec ) {
1507 9         46 $default->_set_spec( \%spec_copy );
1508             }
1509             if ( not $default->has_title ) {
1510 58 100 100     3990 $default->_set_title( "$qname\::$attrname" );
      100        
1511 7         105 }
1512             }
1513            
1514 58 100       851 my $default_codulate = 0;
1515 23 50 66     72 # Mouse doesn't support overloaded objects as defaults.
      66        
1516 1         4 if ( $toolkit eq 'Mouse' and is_Object $spec{default} ) {
1517             $default_codulate = 1;
1518 23 100 66     58 }
1519 1         3 # Moose doesn't usually either
1520 1     2   5 elsif ( $toolkit eq 'Moose' and is_Object $spec{default} and not $spec{default}->isa('Class::MOP::Method') ) {
  2         1908  
1521             $default_codulate = 1;
1522 23 50       53 }
1523 0         0
1524 0 0       0 if ( $default_codulate ) {
1525             my $deref = eval { \&{ $spec{default} } };
1526             if ( is_CodeRef $deref ) {
1527             $spec{default} = $deref;
1528 58 100       222 }
1529 1         5 }
1530 1         515  
1531             if ($spec{lexical}) {
1532             require Lexical::Accessor;
1533 58 50       240 if ($spec{traits} || $spec{handles_via}) {
1534 0         0 'Lexical::Accessor'->VERSION('0.010');
1535 0         0 }
  0         0  
1536 0         0 my $la = 'Lexical::Accessor'->new_from_has(
1537             $attrname,
1538             package => $qname,
1539 58 50 33     223 %spec,
1540 0         0 );
1541 0         0 $la->install_accessors;
1542             }
1543 0 0 0     0 else
1544 0         0 {
1545             my ($shv_toolkit, $shv_data);
1546 0 0       0 my $lex = $builder->_pre_attribute($qname, $attrname, \%spec);
1547 0         0 if ($spec{handles_via}) {
1548             $shv_toolkit = "Sub::HandlesVia::Toolkit::$toolkit";
1549 0 0       0 use_module($shv_toolkit);
1550 0         0 $shv_data = $shv_toolkit->clean_spec($qname, $attrname, \%spec);
1551             }
1552             $builder->$installer($qname, $attrname, \%spec);
1553             $shv_toolkit->install_delegations($shv_data) if $shv_data;
1554 58         115 $builder->_post_attribute($qname, $attrname, \%spec, $lex) if $lex;
1555             }
1556 58 50 66     347 }
    50 66        
      33        
1557 0         0
1558             $meta->make_immutable if $make_immutable;
1559             return;
1560             }
1561 0         0  
1562             my ($builder, $target, $attrname, $spec) = @_;
1563             my %lex;
1564 58 50       137
1565 0         0 for my $thing (qw/ reader writer accessor clearer predicate /) {
  0         0  
  0         0  
1566 0 0       0 if (is_ScalarRef $spec->{$thing}) {
1567 0         0 my $rand = sprintf('__lexical_%d', 10_000_000 + int rand(89_000_000));
1568             $lex{$rand} = $spec->{$thing};
1569             $spec->{$thing} = $rand;
1570             }
1571 58 100       131 }
1572 2         428
1573 2 100 66     6089 if (is_ArrayRef $spec->{handles}) {
1574 1         13 my %new_handles;
1575             my @handles = @{$spec->{handles}};
1576 2         16 while (@handles) {
1577             my ($src, $dst) = splice @handles, 0, 2;
1578             if (is_ScalarRef $src) {
1579             my $rand = sprintf('__lexical_%d', 10_000_000 + int rand(89_000_000));
1580             $new_handles{$rand} = $dst;
1581 2         173 $lex{$rand} = $src;
1582             }
1583             else {
1584             $new_handles{$src} = $dst;
1585 56         98 }
1586 56         222 }
1587 56 100       159 $spec->{handles} = \%new_handles;
1588 5         15 }
1589 5         16
1590 5         35737 return unless keys %lex;
1591             \%lex;
1592 56         459 }
1593 56 100       325313  
1594 56 100       144023 my ($builder, $target, $attrname, $spec) = @_;
1595             my %lex = %{ +pop };
1596            
1597             foreach my $tmp (sort keys %lex) {
1598 37 50       102619 my $coderef = do { no strict 'refs'; \&{"$target\::$tmp"} };
1599 37         106 ${ $lex{$tmp} } = $coderef;
1600             'namespace::clean'->clean_subroutines($target, $tmp);
1601             }
1602             }
1603 56     58   141  
1604 56         92 my $builder = shift;
1605             my ($class, $attribute, $spec) = @_;
1606 56         143 my $helper = $builder->_get_moo_helper($class, 'has');
1607 280 100       790 if (is_Object($spec->{isa}) and $spec->{isa}->isa('Type::Tiny::Enum') and $spec->{handles}) {
1608 3         35 $builder->_process_enum_moo(@_);
1609 3         8 }
1610 3         6 $helper->($attribute, %$spec);
1611             }
1612              
1613             my $builder = shift;
1614 56 100       261 my ($class, $attribute, $spec) = @_;
1615 1         1 require MooX::Enumeration;
1616 1         2 my %new_spec = 'MooX::Enumeration'->process_spec($class, $attribute, %$spec);
  1         3  
1617 1         4 if (delete $new_spec{moox_enumeration_process_handles}) {
1618 3         5 'MooX::Enumeration'->install_delegates($class, $attribute, \%new_spec);
1619 3 100       10 }
1620 2         6 %$spec = %new_spec;
1621 2         5 }
1622 2         5  
1623             my $builder = shift;
1624             my ($class, $attribute, $spec) = @_;
1625 1         3 if (is_Object($spec->{isa}) and $spec->{isa}->isa('Type::Tiny::Enum')||$spec->{isa}->isa('Moose::Meta::TypeConstraint::Enum') and $spec->{handles}) {
1626             $builder->_process_enum_moose(@_);
1627             }
1628 1         3 require Moose::Util;
1629             (Moose::Util::find_meta($class) or $class->meta)->add_attribute($attribute, %$spec);
1630             }
1631 56 100       232  
1632 1         3 my $builder = shift;
1633             my ($class, $attribute, $spec) = @_;
1634             require MooseX::Enumeration;
1635             push @{ $spec->{traits}||=[] }, 'Enumeration';
1636 1     8   3 }
1637 1         2  
  1         5  
1638             my $builder = shift;
1639 1         5 my ($class, $attribute, $spec) = @_;
1640 40     40   289 if (is_Object($spec->{isa}) and $spec->{isa}->isa('Type::Tiny::Enum') and $spec->{handles}) {
  40         83  
  40         78281  
  5         259  
  5         7  
  5         14  
1641 5         6 $builder->_process_enum_mouse(@_);
  5         6  
1642 5         13 }
1643             require Mouse::Util;
1644             my %spec = %$spec;
1645             delete $spec{definition_context};
1646             (Mouse::Util::find_meta($class) or $class->meta)->add_attribute($attribute, %spec);
1647 33     33 0 59 }
1648 33         95  
1649 33         115 die 'not implemented';
1650 33 100 100     246 }
      100        
1651 1         14  
1652             my $builder = shift;
1653 33         449 my ($class, $isa) = @_;
1654             my $helper = $builder->_get_moo_helper($class, 'extends');
1655             $helper->(@$isa);
1656             }
1657 1     8   2  
1658 1         3 my $builder = shift;
1659 1         403 my ($class, $isa) = @_;
1660 1         2018
1661 1 50       68 PARENT: for my $parent ( @$isa ) {
1662 1         4 next PARENT if $parent->isa('Moose::Object');
1663             next PARENT if $parent->isa('Moo::Object');
1664 1         14170 use_module("MooseX::NonMoose")->import::into($class);
1665             last PARENT;
1666             }
1667            
1668 12     12 0 23 require Moose::Util;
1669 12         29 (Moose::Util::find_meta($class) or $class->meta)->superclasses(@$isa);
1670 12 50 66     81 }
      100        
      66        
1671 0         0  
1672             my $builder = shift;
1673 12         19277 my ($class, $isa) = @_;
1674 12   33     40
1675             PARENT: for my $parent ( @$isa ) {
1676             next PARENT if $parent->isa('Mouse::Object');
1677             use_module("MouseX::NonMoose")->import::into($class);
1678 0     0   0 last PARENT;
1679 0         0 }
1680 0         0
1681 0   0     0 require Mouse::Util;
  0         0  
1682             (Mouse::Util::find_meta($class) or $class->meta)->superclasses(@$isa);
1683             }
1684              
1685 11     17 0 17 my $builder = shift;
1686 11         21 my ($target, $symm) = @_;
1687 11 50 100     58
      66        
1688 0         0 my @symm = $symm->$_handle_list or return;
1689            
1690 11         160 require Sub::SymMethod;
1691 11         38
1692 11         22 while ( @symm ) {
1693 11   33     27 my $name = shift(@symm);
1694             my $spec = is_CodeRef($symm[0]) ? { code => shift(@symm) } : shift(@symm);
1695            
1696             if ( $spec->{signature} ) {
1697 0     6   0 my $signature_style = CodeRef->check($spec->{signature})
1698             ? 'code'
1699             : ($spec->{named} ? 'named' : 'positional');
1700             my $new_sig = $builder->_build_method_signature_check(
1701 46     52 0 85 $target,
1702 46         88 $name,
1703 46         124 $signature_style,
1704 46         145 $spec->{signature},
1705             exists($spec->{signature}) ? $spec->{signature} : 1,
1706             1,
1707             );
1708 18     24 0 30 $spec->{signature} = $new_sig;
1709 18         33 }
1710            
1711 18         29 'Sub::SymMethod'->install_symmethod( $target, $name, %$spec );
1712 18 50       80 }
1713 0 0       0 }
1714 0         0  
1715 0         0 my $builder = shift;
1716             my ($target, $kind, $method_name, $method_spec) = @_;
1717            
1718 18         80 HashRef->($method_spec);
1719 18   33     72 Ref->($method_spec->{signature});
1720             CodeRef->($method_spec->{code});
1721            
1722             my $signature_style = CodeRef->check($method_spec->{signature})
1723 18     18 0 28 ? 'code'
1724 18         33 : ($method_spec->{named} ? 'named' : 'positional');
1725            
1726 18         28 my $new_sig = $builder->_build_method_signature_check(
1727 18 50       82 $target,
1728 0         0 $method_name,
1729 0         0 $signature_style,
1730             $method_spec->{signature},
1731             undef,
1732 18         73 1,
1733 18   33     49 );
1734             $method_spec->{signature} = $new_sig;
1735              
1736             if ( match('coercion', $method_spec->{'attributes'}) or match('coerce', $method_spec->{'attributes'}) ) {
1737 10     10 0 18 my $to_type = $target->FACTORY->type_library->get_type_for_package( any => $target );
1738 10         19
1739             my @sigtypes = grep Scalar::Util::blessed($_), @{$method_spec->{signature}};
1740 10 50       21
1741             $builder->croak('Multimethods used as coercions must take exactly one positional argument')
1742 10         845 unless is_ArrayRef( $method_spec->{signature} ) && 1==@sigtypes && $signature_style eq 'positional';
1743            
1744 10         17560 $builder->croak("Too late to add coercion to $to_type")
1745 14         345 if $to_type->coercion->frozen;
1746 14 100       48
1747             my $from_type = 'Type::Registry'->for_class($target)->lookup( $sigtypes[0] );
1748 14 100       38
1749             my $code = $method_spec->{code};
1750             $to_type->coercion->add_type_coercions( $from_type, sub { $code->($target, $_) } );
1751 2 50       11 }
    50          
1752              
1753             require Sub::MultiMethod;
1754             'Sub::MultiMethod'->install_candidate($target, $method_name, no_dispatcher=>($kind eq 'role'), %$method_spec);
1755             }
1756              
1757 2 50       40 {
1758             my $_process_roles = sub {
1759             my ($builder, $r, $tk, $opts) = @_;
1760 2         6 map {
1761             my $role = $_;
1762             if ($role =~ /\?$/) {
1763 14         76 $role =~ s/\?$//;
1764             eval "require $role; 1" or do {
1765             $builder->make_role(make_absolute_package_name($role), %$opts, toolkit => $tk);
1766             };
1767             }
1768 10     10 0 22 $role;
1769 10         25 } @$r;
1770             };
1771 10         37
1772 10         2190 my $_maybe_do_multimethods = sub {
1773 10         1995 my $tk = 'Sub::MultiMethod';
1774             if ($tk->can('copy_package_candidates') and $tk->VERSION lt '0.901') {
1775             my ($target, $kind, @sources) = @_;
1776             $tk->copy_package_candidates(@sources => $target);
1777 10 50       1913 $tk->install_missing_dispatchers($target) unless $kind eq 'role';
    50          
1778             }
1779             return;
1780             };
1781            
1782             my $builder = shift;
1783             my ($class, $kind, $roles, $opts) = @_;
1784             my $helper = $builder->_get_moo_helper($class, 'with');
1785 10         200 my @roles = $builder->$_process_roles($roles, 'Moo', $opts);
1786             $helper->(@roles);
1787 10         20 $class->$_maybe_do_multimethods($kind, @roles) if $INC{'Sub/MultiMethod.pm'};
1788             }
1789 10 50 33     72  
1790 0         0 my $builder = shift;
1791             my ($class, $kind, $roles, $opts) = @_;
1792 0         0 require Moose::Util;
  0         0  
1793             my @roles = $builder->$_process_roles($roles, 'Moose', $opts);
1794             Moose::Util::ensure_all_roles($class, @roles);
1795 0 0 0     0 $class->$_maybe_do_multimethods($kind, @roles) if $INC{'Sub/MultiMethod.pm'};
      0        
1796             }
1797 0 0       0  
1798             my $builder = shift;
1799             my ($class, $kind, $roles, $opts) = @_;
1800 0         0 require Mouse::Util;
1801             my @roles = $builder->$_process_roles($roles, 'Mouse', $opts);
1802 0         0 # this can double-apply roles? :(
1803 0     0   0 Mouse::Util::apply_all_roles($class, @roles);
  0         0  
1804             $class->$_maybe_do_multimethods($kind, @roles) if $INC{'Sub/MultiMethod.pm'};
1805             }
1806 10         1491 }
1807 10         86468  
1808             my $builder = shift;
1809             my ($role, $methods) = @_;
1810             my $helper = $builder->_get_moo_helper($role, 'requires');
1811             $helper->(sort keys %$methods);
1812             }
1813              
1814             my $builder = shift;
1815             my ($role, $methods) = @_;
1816             require Moose::Util;
1817             (Moose::Util::find_meta($role) or $role->meta)->add_required_methods(sort keys %$methods);
1818             }
1819              
1820             my $builder = shift;
1821             my ($role, $methods) = @_;
1822             require Mouse::Util;
1823             (Mouse::Util::find_meta($role) or $role->meta)->add_required_methods(sort keys %$methods);
1824             }
1825              
1826             my $builder = shift;
1827             my %method = (@_==1) ? %{$_[0]} : @_;
1828             my $qname = delete($method{package}) || caller;
1829             $method{lexical} = !!1;
1830             my $return = $builder->install_methods($qname, { '__ANON__' => \%method });
1831             $return->{'__ANON__'};
1832             }
1833              
1834             my $builder = shift;
1835             my ($class, $methods) = @_;
1836 46     46 0 85 my %return;
1837 46         109
1838 46         157 my $to_type;
1839 46         171
1840 46         145 for my $name (sort keys %$methods) {
1841 46 100       190914 no strict 'refs';
1842             my ($code, $signature, $signature_style, $invocant_count, $is_coderef, $caller, $attrs, @curry, $ctx);
1843             $caller = $class;
1844            
1845 16     16 0 31 if (is_CodeRef($methods->{$name})) {
1846 16         27 $code = $methods->{$name};
1847 16         69 $signature_style = 'none';
1848 16         42 }
1849 16         67 elsif (is_HashRef($methods->{$name})) {
1850 16 50       55650 $attrs = $methods->{$name}{attributes};
1851             $code = $methods->{$name}{code};
1852             $signature = $methods->{$name}{signature};
1853             @curry = @{ $methods->{$name}{curry} || [] };
1854 16     16 0 21 $invocant_count = exists($methods->{$name}{invocant_count}) ? $methods->{$name}{invocant_count} : 1;
1855 16         28 $signature_style = is_CodeRef($signature)
1856 16         59 ? 'code'
1857 16         35 : ($methods->{$name}{named} ? 'named' : 'positional');
1858             $is_coderef = !!$methods->{$name}{lexical};
1859 16         54 $caller = $methods->{$name}{caller};
1860 16 50       18700 $ctx = $methods->{$name}{'definition_context'};
1861             }
1862            
1863             if ($signature) {
1864             CodeRef->assert_valid($signature) if $signature_style eq 'code';
1865 1     1 0 2 ArrayRef->assert_valid($signature) if $signature_style eq 'named';
1866 1         3 ArrayRef->assert_valid($signature) if $signature_style eq 'positional';
1867 1         3 };
1868 1         4
1869             my $optimized = 0;
1870             my $checkcode = '&$check';
1871             if ($signature and $methods->{$name}{optimize}) {
1872 0     0 0 0 if (my $r = $builder->_optimize_signature($class, "$class\::$name", $signature_style, $signature)) {
1873 0         0 $checkcode = $r;
1874 0         0 ++$optimized;
1875 0   0     0 }
1876             }
1877            
1878             my $callcode;
1879 0     0 0 0 if (is_CodeRef($code)) {
1880 0         0 $callcode = 'goto $code';
1881 0         0 }
1882 0   0     0 else {
1883             ($callcode = $code) =~ s/\A \s* sub \s* \{ (.+) \} \s* \z/$1/xs;
1884             $callcode = "package $caller; $callcode" if defined $caller;
1885             }
1886 1     1 0 595
1887 1 50       5 my $attrs_string = $is_coderef ? "" : ":method";
  1         5  
1888 1   33     8 $attrs_string .= " :lvalue" if match("lvalue", $attrs);
1889 1         3
1890 1         5 my $magic_comment = '';
1891 1         8 if ($ctx) {
1892             $magic_comment = sprintf("#line %d \"%s\"\n", $ctx->{line}, $ctx->{file});
1893             }
1894            
1895 105     105 1 202 no warnings 'printf';
1896 105         203 my $subcode = sprintf(
1897 105         173 q{%s} . # magic comment
1898             q{package %-49s} . # package name
1899             q{%-49s} . # my $check variable to close over
1900             q{sub %-49s} . # method name
1901 105         379 q[{] .
1902 40     40   299 q{%-49s} . # strip @invocants from @_ if necessary
  40         84  
  40         13789  
1903 208         358 q{%-49s} . # build $check
1904 208         322 q{%-49s} . # reassemble @_ from @invocants, @curry, and &$check
1905             q{%-49s} . # run sub code
1906 208 100       678 q[};] .
    50          
1907 169         263 q[%s] # 1;
1908 169         245 ,
1909             $magic_comment,
1910             "$class;",
1911 39         69 (($signature && !$optimized)
1912 39         71 ? 'my $check;'
1913 39         69 : ''),
1914 39 100       58 ($is_coderef ? $attrs_string : "$name $attrs_string"),
  39         186  
1915 39 100       107 ($signature
1916             ? sprintf('my @invocants = splice(@_, 0, %d);', $invocant_count)
1917             : ''),
1918 39 100       132 (($signature && !$optimized)
    100          
1919 39         83 ? sprintf('$check ||= do { my $tmp = %s->_build_method_signature_check(%s, %s, %s, $signature, \\@invocants); ref($tmp) eq q(HASH) ? $tmp->{closure} : $tmp };', map(B::perlstring($_), $builder, $class, "$class\::$name", $signature_style))
1920 39         65 : ''),
1921 39         62 ($signature
1922             ? (@curry ? sprintf('@_ = (@invocants, @curry, %s);', $checkcode) : sprintf('@_ = (@invocants, %s);', $checkcode))
1923             : (@curry ? sprintf('splice(@_, %d, 0, @curry);', $invocant_count) : '')),
1924 208 100       384 $callcode,
1925 6 100       21 ($is_coderef ? '' : '1;'),
1926 6 100       29 );
1927 6 100       42
1928             no warnings 'closure';
1929             ($return{$name} = eval($subcode))
1930 208         344 or $builder->croak("Could not create method $name in package $class: $@");
1931 208         263
1932 208 100 100     418 if ( match('coercion', $attrs) or match('coerce', $attrs) ) {
1933 2 50       11 my @sigtypes = grep !is_HashRef($_), @$signature;
1934 2         6
1935 2         5 $to_type ||= $class->FACTORY->type_library->get_type_for_package( any => $class );
1936            
1937             $builder->croak('Methods used as coercions must take exactly one positional argument')
1938             unless is_ArrayRef( $signature ) && 1==@sigtypes && $signature_style eq 'positional';
1939 208         244
1940 208 100       434 $builder->croak("Too late to add coercion to $to_type")
1941 203         266 if $to_type->coercion->frozen;
1942            
1943             my $from_type = 'Type::Registry'->for_class($class)->lookup( $sigtypes[0] );
1944 5         38
1945 5 100       23 $to_type->coercion->add_type_coercions(
1946             $from_type, sprintf('%s->%s($_)', B::perlstring($class), $name),
1947             );
1948 208 100       377 }
1949 208 100       553 }
1950             \%return;
1951 208         285 }
1952 208 100       365  
1953 21         103 my $builder = shift;
1954             my ($method_class, $method_name, $signature_style, $signature) = @_;
1955            
1956 40     40   311 $signature_style ||= 'none' if !$signature;
  40         87  
  40         7485  
1957 208 100 100     2084
    100 100        
    100          
    100          
    100          
    100          
    100          
    100          
1958             return if $signature_style eq 'none';
1959             return if $signature_style eq 'code';
1960            
1961             my @sig = @$signature;
1962             require Type::Params;
1963             my $global_opts = {};
1964             $global_opts = shift(@sig) if is_HashRef($sig[0]);
1965             $global_opts->{want_details} = 1;
1966            
1967             my $details = $builder->_build_method_signature_check($method_class, $method_name, $signature_style, [$global_opts, @sig]);
1968             return if keys %{$details->{environment}};
1969             return if $details->{source} =~ /return/;
1970              
1971             $details->{source} =~ /^sub \{(.+)\};?$/s or return;
1972             return "do { $1 }";
1973             }
1974              
1975             # need to partially parse stuff for Type::Params to look up type names
1976             my $builder = shift;
1977             my ($method_class, $method_name, $signature_style, $signature, $invocants, $gimme_list) = @_;
1978             my $type_library;
1979            
1980             $signature_style ||= 'none' if !$signature;
1981            
1982             return sub { @_ } if $signature_style eq 'none';
1983             return $signature if $signature_style eq 'code';
1984             my @sig = @$signature;
1985            
1986             require Type::Params;
1987            
1988             my $global_opts = {};
1989 40     40   355 $global_opts = shift(@sig) if is_HashRef($sig[0]);
  40         115  
  40         41119  
1990 208 50   27 0 13300
  27     18 0 27718  
  14     1 0 4958  
  2         2099  
1991             $global_opts->{subname} ||= $method_name;
1992            
1993 208 50 33     1581 my $is_named = ($signature_style eq 'named');
1994 0         0 my @params;
1995            
1996 0   0     0 my $reg;
1997            
1998 0 0 0     0 while (@sig) {
      0        
1999             my ($name, $type, $opts) = (undef, undef, {});
2000             if ($is_named) {
2001 0 0       0 ($name, $type) = splice(@sig, 0, 2);
2002             }
2003             else {
2004 0         0 $type = shift(@sig);
2005             }
2006 0         0 if ( is_HashRef $sig[0] ) {
2007             $opts = shift(@sig);
2008             }
2009            
2010             # All that work, just to do this!!!
2011 105         342 if (is_Str($type) and not $type =~ /^[01]$/) {
2012             $reg ||= do {
2013             require Type::Registry;
2014             'Type::Registry'->for_class($method_class);
2015 20     19   43521 };
2016 24         8663
2017             if ($type =~ /^\%/) {
2018 14 50 100     22967 $type = HashRef->of(
2019             $reg->lookup(substr($type, 1))
2020 14 100       52 );
2021 7 50       3249 }
2022             elsif ($type =~ /^\@/) {
2023 7         30 $type = ArrayRef->of(
2024 4         1049 $reg->lookup(substr($type, 1))
2025 6         11771 );
2026 6 50       20 }
2027 6         26 else {
2028             $type = $reg->lookup($type);
2029 6         38 }
2030 6 100       75718 }
  6         21  
2031 5 100       19
2032             push(
2033 5 100       29 @params,
2034 4         78 $is_named
2035             ? ($name, $type, $opts)
2036             : ( $type, $opts)
2037             );
2038             }
2039 22     41   2194
2040 23         64 for my $position (qw( head tail )) {
2041 23         30 if (ref $global_opts->{$position}) {
2042             require Type::Params;
2043 23 100 33     64 'Type::Params'->VERSION(1.009002);
2044             $reg ||= do {
2045 23 50   5   71 require Type::Registry;
  2         6  
2046 22 100       70 'Type::Registry'->for_class($method_class);
2047 21         62 };
2048             $global_opts->{$position} = [map {
2049 21         2800 my $type = $_;
2050             if (ref $type) {
2051 21         34293 $type;
2052 21 100       85 }
2053             elsif ($type =~ /^\%/) {
2054 20   66     7320 HashRef->of(
2055             $reg->lookup(substr($type, 1))
2056 20         42 );
2057 20         41 }
2058             elsif ($type =~ /^\@/) {
2059             ArrayRef->of(
2060             $reg->lookup(substr($type, 1))
2061 20         91 );
2062 29         70 }
2063 29 100       94 else {
2064 6         22 $reg->lookup($type);
2065             }
2066             } @{$global_opts->{$position}} ];
2067 23         35 }
2068             }
2069 28 50       112
2070 0         0 my $next = $is_named ? \&Type::Params::compile_named_oo : \&Type::Params::compile;
2071             @_ = ($global_opts, @params);
2072             return [@_] if $gimme_list;
2073             goto $next;
2074 28 100 100     142 }
2075 15   100     57  
2076 12         46 my $builder = shift;
2077 12         67 my ($class, $methods) = @_;
2078             for my $name (sort keys %$methods) {
2079             no strict 'refs';
2080 15 50       146 my $value = $methods->{$name};
    50          
2081 0         0 if (defined $value && !ref $value) {
2082             require B;
2083             my $stringy = B::perlstring($value);
2084             eval "package $class; sub $name () { $stringy }; 1"
2085             or $builder->croak("Could not create constant $name in package $class: $@");
2086 0         0 }
2087             else {
2088             eval "package $class; sub $name () { \$value }; 1"
2089             or $builder->croak("Could not create constant $name in package $class: $@");
2090             }
2091 15         49 }
2092             }
2093              
2094             my ($builder, $class, $kind, $names, $method) = @_;
2095             return $method if is_CodeRef $method;
2096 28 100       1534
2097             my $coderef = $method->{code};
2098             my $signature = $method->{signature};
2099             my @curry = @{ $method->{curry} || [] };
2100             my $signature_style = $method->{named} ? 'named' : 'positional';
2101            
2102             return $coderef unless $signature || @curry;
2103 19         49 $signature ||= sub { @_ };
2104 38 50       117
2105 0         0 my $invocant_count = 1 + !!($kind eq 'around');
2106 0         0 $invocant_count = $method->{invocant_count} if exists $method->{invocant_count};
2107 0   66     0
2108 0         0 my $name = join('|', @$names)."($kind)";
2109 0         0
2110             no warnings 'closure';
2111             my $wrapped = eval qq{
2112 0         0 my \$check;
2113 0 0       0 sub {
    0          
    0          
2114 0         0 my \@invocants = splice(\@_, 0, $invocant_count);
2115             \$check ||= do{ my \$tmp = q($builder)->_build_method_signature_check(q($class), q($class\::$name), \$signature_style, \$signature, \\\@invocants); ref(\$tmp) eq q(HASH) ? \$tmp->{closure} : \$tmp };
2116             \@_ = (\@invocants, \@curry, \&\$check);
2117 0         0 goto \$coderef;
2118             };
2119             };
2120             $wrapped or die("YIKES: $@");
2121             }
2122 0         0  
2123             my $builder = shift;
2124             my ($class, $modifier, $method_names, $coderef) = @_;
2125             my $helper = $builder->_get_moo_helper($class, $modifier);
2126             $helper->(@$method_names, $coderef);
2127 0         0 }
2128              
2129 0         0 my $builder = shift;
  0         0  
2130             my ($class, $modifier, $method_names, $coderef) = @_;
2131             my $m = "add_$modifier\_method_modifier";
2132             require Moose::Util;
2133 19 100       53 my $meta = Moose::Util::find_meta($class) || $class->meta;
2134 19         60 for my $method_name (@$method_names) {
2135 19 100       72 $meta->$m($method_name, $coderef);
2136 7         42 }
2137             }
2138              
2139             my $builder = shift;
2140 10     10 1 17 my ($class, $modifier, $method_names, $coderef) = @_;
2141 10         23 my $m = "add_$modifier\_method_modifier";
2142 10         38 require Mouse::Util;
2143 40     40   295 my $meta = (Mouse::Util::find_meta($class) or $class->meta);
  40         101  
  40         11195  
2144 15         37 for my $method_name (@$method_names) {
2145 15 50 66     81 $meta->$m($method_name, $coderef);
2146 15         54 }
2147 15         53 }
2148 15 50       945  
2149             1;
2150              
2151              
2152 0 0       0 =pod
2153              
2154             =encoding utf-8
2155              
2156             =head1 NAME
2157              
2158             MooX::Press - quickly create a bunch of Moo/Moose/Mouse classes and roles
2159 24     24   61  
2160 24 100       77 =head1 SYNOPSIS
2161              
2162 2         3 package MyApp;
2163 2         3 use Types::Standard qw(Str Num);
2164 2 50       3 use MooX::Press (
  2         20  
2165 2 50       8 role => [
2166             'Livestock',
2167 2 50 33     6 'Pet',
2168 2   50 0   5 'Milkable' => {
  0         0  
2169             can => [
2170 2         6 'milk' => sub { print "giving milk\n"; },
2171 2 50       4 ],
2172             },
2173 2         8 ],
2174             class => [
2175 40     40   260 'Animal' => {
  40         83  
  40         14191  
2176 2         327 has => [
2177             'name' => Str,
2178             'colour',
2179             'age' => Num,
2180             'status' => { enum => ['alive', 'dead'], default => 'alive' },
2181             ],
2182             subclass => [
2183             'Panda',
2184             'Cat' => { with => ['Pet'] },
2185 2 50       12 'Dog' => { with => ['Pet'] },
2186             'Cow' => { with => ['Livestock', 'Milkable'] },
2187             'Pig' => { with => ['Livestock'] },
2188             ],
2189 8     8 0 14 },
2190 8         15 ],
2191 8         19 );
2192 8         22  
2193             Using your classes:
2194              
2195             use MyApp;
2196 6     6 0 8
2197 6         12 my $kitty = MyApp->new_cat(name => "Grey", status => "alive");
2198 6         12 # or: MyApp::Cat->new(name => "Grey", status => "alive");
2199 6         25
2200 6   33     19 MyApp->new_cow(name => "Daisy")->milk();
2201 6         58  
2202 8         237 I realize this is a longer synopsis than most CPAN modules give, but
2203             considering it sets up six classes and three roles with some attributes
2204             and methods, applies the roles to the classes, and creates a type library
2205             with nine types in it, it's pretty concise.
2206              
2207 6     6 0 10 =head1 DESCRIPTION
2208 6         10  
2209 6         11 L<MooX::Press> (pronounced "Moo Express") is a quick way of creating a bunch
2210 6         21 of simple Moo classes and roles at once without needing to create separate
2211 6   33     18 Perl modules for each class and each role, and without needing to add a bunch
2212 6         66 of boilerplate to each file.
2213 8         70  
2214             It also supports Moose and Mouse, though Moo classes and roles play nicely
2215             with Moose (and to a certain extent with Mouse) anyway.
2216              
2217             =head2 Import Options
2218              
2219             MooX::Press is called like:
2220              
2221             use MooX::Press %import_opts;
2222              
2223             The following options are supported. To make these easier to remember, options
2224             follow the convention of using lower-case singular, and reusing keywords from
2225             Perl and Moo/Moose/Mouse when possible.
2226              
2227             =over
2228              
2229             =item C<< class >> I<< (OptList) >>
2230              
2231             This is the list of classes to create as an optlist. An optlist is an arrayref
2232             of strings, where each string is optionally followed by a reference.
2233              
2234             [ "A", "B", "C", \%opt_for_C, "D", "E", \%opts_for_E, "F" ]
2235              
2236             In particular, for the class optlist the references should be hashrefs of
2237             class options (see L</Class Options>), though key-value pair arrayrefs are
2238             also accepted.
2239              
2240             =item C<< role >> I<< (OptList) >>
2241              
2242             This is the list of roles to create, structured almost the same as the optlist
2243             for classes, but see L</Role Options>.
2244              
2245             =item C<< class_generator >> I<< (OptList) >>
2246              
2247             Kind of like C<class>, but:
2248              
2249             [ "A", \&generator_for_A, "B", \&generator_for_B, ... ]
2250              
2251             "A" and "B" are not classes, but when C<< MyApp->generate_a(...) >>
2252             is called, it will pass arguments to C<< &generator_for_A >> which is expected
2253             to return a hashref like C<< \%opts_for_A >>. Then a new pseudononymous class
2254             will be created with those options.
2255              
2256             See the FAQ for an example.
2257              
2258             =item C<< role_generator >> I<< (OptList) >>
2259              
2260             The same but for roles.
2261              
2262             See the FAQ for an example.
2263              
2264             =item C<< toolkit >> I<< (Str) >>
2265              
2266             The strings "Moo", "Moose", or "Mouse" are accepted and instruct MooX::Press
2267             to use your favourite OO toolkit. "Moo" is the default.
2268              
2269             =item C<< version >> I<< (Num) >>
2270              
2271             This has nothing to do with the version of MooX::Press you are using.
2272             It sets the C<< our $VERSION >> variable for the classes and roles being
2273             generated.
2274              
2275             =item C<< authority >> I<< (Str) >>
2276              
2277             This sets the C<< our $AUTHORITY >> variable for the classes and roles being
2278             generated.
2279              
2280             C<version> and C<authority> will be copied from the caller if they are not set,
2281             but you can set them to undef explicitly if you want to avoid that.
2282              
2283             =item C<< prefix >> I<< (Str|Undef) >>
2284              
2285             A namespace prefix for MooX::Press to put all your classes into. If MooX::Press
2286             is told to create a class "Animal" and C<prefix> is set to "MyApp::OO", then
2287             it will create a class called "MyApp::OO::Animal".
2288              
2289             This is optional and defaults to the caller. If you wish to have no prefix,
2290             then pass an explicit C<< prefix => undef >> option. (If the caller is
2291             C<main>, then the prefix defaults to undef.)
2292              
2293             You can bypass the prefix for a specific class or a specific role using a
2294             leading double colon, like "::Animal" (or "main::Animal").
2295              
2296             =item C<< factory_package >> I<< (Str|Undef) >>
2297              
2298             A package name to install methods like the C<new_cat> and C<new_cow> methods
2299             in L</SYNOPSIS>.
2300              
2301             This defaults to prefix if the prefix is defined, and "Local" otherwise, but
2302             may be explicitly set to undef to suppress the creation of such methods. If
2303             the factory_package is "Local", you'll get a warning, except in C<< perl -e >>
2304             one-liners.
2305              
2306             In every class (but not role) that MooX::Press builds, there will be a
2307             C<FACTORY> method created so that, for example
2308              
2309             MyApp::Cow->FACTORY # returns "MyApp"
2310              
2311             The factory package will also have a method called C<qualify> installed,
2312             which uses the same logic as MooX::Press to add prefixes to class/role
2313             names.
2314              
2315             MyApp::Cow->FACTORY->qualify('Pig') # 'MyApp::Pig'
2316             MyApp::Cow->FACTORY->qualify('::Pig') # 'Pig'
2317              
2318             There will also be C<get_role> and C<get_class> methods:
2319              
2320             my $Clever = MyApp->get_role( 'Clever' );
2321             my $Brave = MyApp->get_role( 'Brave' );
2322             my $Pig = MyApp->get_class( 'Pig', $Clever, $Brave );
2323             my $wilbur = $Pig->new( name => 'Wilbur' );
2324              
2325             Class generators and role generators are also allowed; just follow the name
2326             with an arrayref of parameters.
2327              
2328             The factory package will have a global variable C<< %PACKAGES >> where the
2329             keys are names of all the packages MooX::Press created for you, and the values
2330             are what kind of package they are:
2331              
2332             say $MyApp::PACKAGES{"MyApp::Cow"}; # 'class'
2333              
2334             =item C<< type_library >> I<< (Str|Undef) >>
2335              
2336             MooX::Press will automatically create a L<Type::Library>-based type library
2337             with type constraints for all your classes and roles. It will be named using
2338             your prefix followed by "::Types".
2339              
2340             You can specify a new name or explicitly set to undef to suppress this
2341             behaviour, but a lot of the coercion features of MooX::Press rely on there
2342             being a type library.
2343              
2344             MooX::Press will create a get_type_for_package method that allows you to
2345             do this:
2346              
2347             MyApp::Types->get_type_for_package(class => "MyApp::Animal")
2348              
2349             MooX::Press will mark "MyApp/Types.pm" as loaded in %INC, so you can do
2350             things like:
2351              
2352             use MyApp::Types qw(Animal);
2353              
2354             And it won't complain about "MyApp/Types.pm" not being found.
2355              
2356             MooX::Press will install a C<type_library> method into the factory package
2357             which returns the name of the type library, so you can do:
2358              
2359             MyApp->type_library->get_type_for_package(class => "MyApp::Animal")
2360              
2361             =item C<< caller >> I<< (Str) >>
2362              
2363             MooX::Press determines some things based on which package called it. If you
2364             are wrapping MooX::Press, you can fake the caller by passing it as an option.
2365              
2366             =item C<< end >> I<< (CodeRef|ArrayRef[CodeRef]) >>
2367              
2368             After creating each class or role, this coderef will be called. It will be
2369             passed two parameters; the fully-qualified package name of the class or role,
2370             plus the string "class" or "role" as appropriate.
2371              
2372             Optional; defaults to nothing.
2373              
2374             =item C<< begin >> I<< (CodeRef|ArrayRef[CodeRef]) >>
2375              
2376             Like C<end>, but called before setting up any attributes, methods, or
2377             method modifiers. (But after loading Moo/Moose/Mouse.)
2378              
2379             Optional; defaults to nothing.
2380              
2381             =item C<< mutable >> I<< (Bool) >>
2382              
2383             Boolean to indicate that classes should be left mutable after creating them
2384             rather than making them immutable. Constructors for mutable classes are
2385             considerably slower than for immutable classes, so this is usually a bad
2386             idea.
2387              
2388             Only supported for Moose. Unnecessary for Moo anyway. Defaults to false.
2389              
2390             =item C<< factory_package_can >> I<< (HashRef[CodeRef]) >>
2391              
2392             Hashref of additional subs to install into the factory package.
2393              
2394             =item C<< type_library_can >> I<< (HashRef[CodeRef]) >>
2395              
2396             Hashref of additional subs to install into the type library package.
2397              
2398             =item C<< default_is >>
2399              
2400             The default for the C<is> option when defining attributes. The default
2401             C<default_is> is "ro".
2402              
2403             =back
2404              
2405             At this top level, a shortcut is available for the 'class' and 'role' keys.
2406             Rather than:
2407              
2408             use MooX::Press (
2409             role => [
2410             'Quux',
2411             'Quuux' => { ... },
2412             ],
2413             class => [
2414             'Foo',
2415             'Bar' => { ... },
2416             'Baz' => { ... },
2417             ],
2418             );
2419              
2420             It is possible to write:
2421              
2422             use MooX::Press (
2423             'role:Quux' => {},
2424             'role:Quuux' => { ... },
2425             'class:Foo' => {},
2426             'class:Bar' => { ... },
2427             'class:Baz' => { ... },
2428             );
2429              
2430             This saves a level of indentation. (C<< => undef >> or C<< => 1 >> are
2431             supported as synonyms for C<< => {} >>.)
2432              
2433             The C<can>, C<before>, C<after>, C<around>, C<multimethod>, C<symmethod>,
2434             C<constant>, C<with>, and C<extends> options documented under Class Options
2435             can also be used as top-level import options to apply them to the factory
2436             package.
2437              
2438             =head3 Class Options
2439              
2440             Each class in the list of classes can be followed by a hashref of
2441             options:
2442              
2443             use MooX::Press (
2444             class => [
2445             'Foo' => \%options_for_foo,
2446             'Bar' => \%options_for_bar,
2447             ],
2448             );
2449              
2450             The following class options are supported.
2451              
2452             =over
2453              
2454             =item C<< extends >> I<< (Str|ArrayRef[Str]) >>
2455              
2456             The parent class for this class.
2457              
2458             The prefix is automatically added. Include a leading "::" if you
2459             don't want the prefix to be added.
2460              
2461             Multiple inheritance is supported.
2462              
2463             If you are using Moose to extend a non-Moose class, MooseX::NonMoose
2464             will load automatically. (This also happens with MouseX::Foreign.)
2465              
2466             =item C<< with >> I<< (ArrayRef[Str]) >>
2467              
2468             Roles for this class to consume.
2469              
2470             The prefix is automatically added. Include a leading "::" if you don't
2471             want the prefix to be added.
2472              
2473             Roles may include a trailing "?". When these are seen, the role will be
2474             created if it doesn't seem to exist. This is because sometimes it's useful
2475             to have roles to classify classes (and check them with the C<does> method)
2476             even if those roles don't have any other functionality.
2477              
2478             use MooX::Press (
2479             prefix => 'Farm',
2480             class => [
2481             'Sheep' => { with => ['Bleat?'] },
2482             ],
2483             );
2484            
2485             if (Farm::Sheep->new->does('Farm::Bleat')) {
2486             ...;
2487             }
2488              
2489             Without the "?", trying to compose a role that does not exist is an error.
2490              
2491             =item C<< has >> I<< (OptList) >>
2492              
2493             The list of attributes to add to the class as an optlist.
2494              
2495             The strings are the names of the attributes, but these strings may be
2496             "decorated" with sigils and suffixes:
2497              
2498             =over
2499              
2500             =item C<< $foo >>
2501              
2502             Creates an attribute "foo" intended to hold a single value.
2503             This adds a type constraint forbidding arrayrefs and hashrefs
2504             but allowing any other value, including undef, strings, numbers,
2505             and any other reference.
2506              
2507             =item C<< @foo >>
2508              
2509             Creates an attribute "foo" intended to hold a list of values.
2510             This adds a type constraint allowing arrayrefs or objects
2511             overloading C<< @{} >>.
2512              
2513             =item C<< %foo >>
2514              
2515             Creates an attribute "foo" intended to hold a collection of key-value
2516             pairs. This adds a type constraint allowing hashrefs or objects
2517             overloading C<< %{} >>.
2518              
2519             =item C<< foo! >>
2520              
2521             Creates an attribute "foo" which will be required by the constructor.
2522              
2523             =back
2524              
2525             An attribute can have both a sigil and a suffix.
2526              
2527             The references in the optlist may be attribute specification hashrefs,
2528             type constraint objects, or builder coderefs.
2529              
2530             # These mean the same thing...
2531             "name!" => Str,
2532             "name" => { is => "ro", required => 1, isa => Str },
2533              
2534             # These mean the same thing...
2535             "age" => sub { return 0 },
2536             "age" => {
2537             is => "ro",
2538             lazy => 1,
2539             builder => sub { return 0 },
2540             clearer => "clear_age",
2541             },
2542              
2543             Type constraints can be any blessed object supported by the toolkit. For
2544             Moo, use L<Type::Tiny>. For Moose, use L<Type::Tiny>, L<MooseX::Types>,
2545             or L<Specio>. For Mouse, use L<Type::Tiny> or L<MouseX::Types>.
2546              
2547             Builder coderefs are automatically installed as methods like
2548             "YourPrefix::YourClass::_build_age()".
2549              
2550             For details of the hashrefs, see L</Attribute Specifications>.
2551              
2552             =item C<< can >> I<< (HashRef[CodeRef|HashRef]) >>
2553              
2554             A hashref of coderefs to install into the package.
2555              
2556             package MyApp;
2557             use MooX::Press (
2558             class => [
2559             'Foo' => {
2560             can => {
2561             'bar' => sub { print "in bar" },
2562             },
2563             },
2564             ],
2565             );
2566            
2567             package main;
2568             MyApp->new_foo()->bar();
2569              
2570             As an alternative, you can do this to prevent your import from getting
2571             cluttered with coderefs. Which you choose depends a lot on stylistic
2572             preference.
2573              
2574             package MyApp;
2575             use MooX::Press (
2576             class => ['Foo'],
2577             );
2578            
2579             package MyApp::Foo;
2580             sub bar { print "in bar" },
2581            
2582             package main;
2583             MyApp->new_foo()->bar();
2584              
2585             =item C<< multimethod >> I<< (ArrayRef) >>
2586              
2587             An arrayref of name-spec pairs suitable for passing to
2588             L<Sub::MultiMethod>.
2589              
2590             package MyApp;
2591             use MooX::Press (
2592             class => [
2593             'Foo' => {
2594             multimethod => [
2595             'bar' => {
2596             signature => [ 'HashRef' ],
2597             code => sub { my ($self, $hash) = @_; ... },
2598             },
2599             'bar' => {
2600             signature => [ 'ArrayRef' ],
2601             code => sub { my ($self, $array) = @_; ... },
2602             },
2603             ],
2604             },
2605             ],
2606             );
2607              
2608             =item C<< symmethod >> I<< (ArrayRef) >>
2609              
2610             An arrayref of name-spec pairs suitable for passing to
2611             L<Sub::SymMethod>.
2612              
2613             =item C<< multifactory >> I<< (ArrayRef) >>
2614              
2615             Similar to C<multimethod> but the methods are created in the factory
2616             package.
2617              
2618             package MyApp;
2619             use MooX::Press (
2620             class => [
2621             'Foo' => {
2622             multifactory => [
2623             'new_foo' => {
2624             signature => [ 'HashRef' ],
2625             code => sub { my ($factory, $class, $hash) = @_; ... },
2626             },
2627             'new_foo' => {
2628             signature => [ 'ArrayRef' ],
2629             code => sub { my ($factory, $class, $array) = @_; ... },
2630             },
2631             ],
2632             },
2633             ],
2634             );
2635            
2636             my $obj1 = 'MyApp'->new_foo( {} );
2637             my $obj2 = 'MyApp'->new_foo( [] );
2638              
2639             =item C<< constant >> I<< (HashRef[Item]) >>
2640              
2641             A hashref of scalar constants to define in the package.
2642              
2643             package MyApp;
2644             use MooX::Press (
2645             class => [
2646             'Foo' => {
2647             constant => {
2648             'BAR' => 42,
2649             },
2650             },
2651             ],
2652             );
2653            
2654             package main;
2655             print MyApp::Foo::BAR, "\n";
2656             print MyApp->new_foo->BAR, "\n";
2657              
2658             =item C<< around >> I<< (ArrayRef|HashRef) >>
2659              
2660             =item C<< before >> I<< (ArrayRef|HashRef) >>
2661              
2662             =item C<< after >> I<< (ArrayRef|HashRef) >>
2663              
2664             Installs method modifiers.
2665              
2666             package MyApp;
2667             use MooX::Press (
2668             role => [
2669             'Loud' => {
2670             around => [
2671             'greeting' => sub {
2672             my $orig = shift;
2673             my $self = shift;
2674             return uc( $self->$orig(@_) );
2675             },
2676             ],
2677             }
2678             ],
2679             class => [
2680             'Person' => {
2681             can => {
2682             'greeting' => sub { "hello" },
2683             }
2684             subclass => [
2685             'LoudPerson' => { with => 'Loud' },
2686             ],
2687             },
2688             ],
2689             );
2690            
2691             package main;
2692             print MyApp::LoudPerson->new->greeting, "\n"; # prints "HELLO"
2693              
2694             =item C<< coerce >> I<< (ArrayRef) >>
2695              
2696             When creating a class or role "Foo", MooX::Press will also create a
2697             L<Type::Tiny::Class> or L<Type::Tiny::Role> called "Foo". The C<coerce>
2698             option allows you to add coercions to that type constraint. Coercions
2699             are called as methods on the class or role. This is perhaps best
2700             explained with an example:
2701              
2702             package MyApp;
2703             use Types::Standard qw(Str);
2704             use MooX::Press (
2705             class => [
2706             'Person' => {
2707             has => [ 'name!' => Str ],
2708             can => {
2709             'from_name' => sub {
2710             my ($class, $name) = @_;
2711             return $class->new(name => $name);
2712             },
2713             },
2714             coerce => [
2715             Str, 'from_name',
2716             ],
2717             },
2718             'Company' => {
2719             has => [ 'name!' => Str, 'owner!' => { isa => 'Person' } ],
2720             },
2721             ],
2722             );
2723              
2724             This looks simple but it's like the swan, graceful above the surface of the
2725             water, legs paddling frantically below.
2726              
2727             It creates a class called "MyApp::Person" with a "name" attribute, so you can
2728             do this kind of thing:
2729              
2730             my $bob = MyApp::Person->new(name => "Bob");
2731             my $bob = MyApp->new_person(name => "Bob");
2732              
2733             As you can see from the C<can> option, it also creates a method "from_name"
2734             which can be used like this:
2735              
2736             my $bob = MyApp::Person->from_name("Bob");
2737              
2738             But here's where coercions come in. It also creates a type constraint
2739             called "Person" in "MyApp::Types" and adds a coercion from the C<Str> type.
2740             The coercion will just call the "from_name" method.
2741              
2742             Then when the "MyApp::Company" class is created and the "owner" attribute
2743             is being set up, MooX::Press knows about the coercion from Str, and will
2744             set up coercion for that attribute.
2745              
2746             # So this should just work...
2747             my $acme = MyApp->new_company(name => "Acme Inc", owner => "Bob");
2748             print $acme->owner->name, "\n";
2749              
2750             Now that's out of the way, the exact structure for the arrayref of coercions
2751             can be explained. It is essentially a list of type-method pairs.
2752              
2753             The type may be either a blessed type constraint object (L<Type::Tiny>, etc)
2754             or it may be a string type name for something that your type library knows
2755             about.
2756              
2757             The method is a string containing the method name to perform the coercion.
2758              
2759             This may optionally be followed by coderef to install as the method. The
2760             following two examples are equivalent:
2761              
2762             use MooX::Press (
2763             class => [
2764             'Person' => {
2765             has => [ 'name!' => Str ],
2766             can => {
2767             'from_name' => sub {
2768             my ($class, $name) = @_;
2769             return $class->new(name => $name);
2770             },
2771             },
2772             coerce => [
2773             Str, 'from_name',
2774             ],
2775             },
2776             ],
2777             );
2778              
2779             use MooX::Press (
2780             class => [
2781             'Person' => {
2782             has => [ 'name!' => Str ],
2783             coerce => [
2784             Str, 'from_name' => sub {
2785             my ($class, $name) = @_;
2786             return $class->new(name => $name);
2787             },
2788             ],
2789             },
2790             ],
2791             );
2792              
2793             In the second example, you can see the C<can> option to install the "from_name"
2794             method has been dropped and the coderef put into C<coerce> instead.
2795              
2796             In case it's not obvious, I suppose it's worth explicitly stating that it's
2797             possible to have coercions from many different types.
2798              
2799             use MooX::Press (
2800             class => [
2801             'Foo::Bar' => {
2802             coerce => [
2803             Str, 'from_string', sub { ... },
2804             ArrayRef, 'from_array', sub { ... },
2805             HashRef, 'from_hash', sub { ... },
2806             'FBaz', 'from_foobaz', sub { ... },
2807             ],
2808             },
2809             'Foo::Baz' => {
2810             type_name => 'FBaz',
2811             },
2812             ],
2813             );
2814              
2815             You should generally order the coercions from most specific to least
2816             specific. If you list "Num" before "Int", "Int" will never be used
2817             because all integers are numbers.
2818              
2819             There is no automatic inheritance for coercions because that does not make
2820             sense. If C<< Mammal->from_string($str) >> is a coercion returning a
2821             "Mammal" object, and "Person" is a subclass of "Mammal", then there's
2822             no way for MooX::Press to ensure that when C<< Person->from_string($str) >>
2823             is called, it will return a "Person" object and not some other kind of
2824             mammal. If you want "Person" to have a coercion, define the coercion in the
2825             "Person" class and don't rely on it being inherited from "Mammal".
2826              
2827             Coercions can also be specified using the attribute 'coerce' or 'coercion'
2828             for methods/multimethods/factory methods, if they only take a single typed
2829             positional argument.
2830              
2831             =item C<< subclass >> I<< (OptList) >>
2832              
2833             Set up subclasses of this class. This accepts an optlist like the class list.
2834             It allows subclasses to be nested as deep as you like:
2835              
2836             package MyApp;
2837             use MooX::Press (
2838             class => [
2839             'Animal' => {
2840             has => ['name!'],
2841             subclass => [
2842             'Fish',
2843             'Bird',
2844             'Mammal' => {
2845             can => { 'lactate' => sub { ... } },
2846             subclass => [
2847             'Cat',
2848             'Dog',
2849             'Primate' => {
2850             subclass => ['Monkey', 'Gorilla', 'Human'],
2851             },
2852             ],
2853             },
2854             ],
2855             },
2856             ];
2857             );
2858            
2859             package main;
2860             my $uncle = MyApp->new_human(name => "Bob");
2861             $uncle->isa('MyApp::Human'); # true
2862             $uncle->isa('MyApp::Primate'); # true
2863             $uncle->isa('MyApp::Mammal'); # true
2864             $uncle->isa('MyApp::Animal'); # true
2865             $uncle->isa('MyApp::Bird'); # false
2866             $uncle->can('lactate'); # eww, but true
2867              
2868             We just defined a nested heirarchy with ten classes there!
2869              
2870             Subclasses can be named with a leading "+" to tell them to use their parent
2871             class name as a prefix. So, in the example above, if you'd called your
2872             subclasses "+Mammal", "+Dog", etc, you'd end up with packages like
2873             "MyApp::Animal::Mammal::Dog". (In cases of multiple inheritance, it uses
2874             C<< $ISA[0] >>.)
2875              
2876             =item C<< factory >> I<< (Str|ArrayRef|Undef) >>
2877              
2878             This is the name for the method installed into the factory package.
2879             So for class "Cat", it might be "new_cat".
2880              
2881             The default is the class name (excluding the prefix), lowercased,
2882             with double colons replaced by single underscores, and
2883             with "new_" added in front. To suppress the creation
2884             of this method, set C<factory> to an explicit undef.
2885              
2886             If set to an arrayref, it indicates you wish to create multiple
2887             methods in the factory package to make objects of this class.
2888              
2889             factory => [
2890             "grow_pig" => \"new_from_embryo",
2891             "new_pork", "new_bacon", "new_ham" => sub { ... },
2892             "new_pig", "new_swine",
2893             ],
2894              
2895             A scalarref indicates the name of a constructor and that the
2896             methods before are shortcuts for that constructor. So
2897             C<< MyApp->grow_pig(@args) >> is a shortcut for
2898             C<< MyApp::Pig->new_from_embryo(@args) >>.
2899              
2900             A coderef will have a custom method installed into the factory package
2901             so that C<< MyApp->new_pork(@args) >> will act as a shortcut for:
2902             C<< $coderef->("MyApp", "MyApp::Pig", @args) >>. Note that C<new_bacon>
2903             and C<new_ham> are just aliases for C<new_bacon>.
2904              
2905             The C<new_pig> and C<new_swine> method names are followed by
2906             neither a coderef nor a scalarref, so are treated as if they had
2907             been followed by C<< \"new" >>.
2908              
2909             =item C<< type_name >> I<< (Str) >>
2910              
2911             The name for the type being installed into the type library.
2912              
2913             The default is the class name (excluding the prefix), with
2914             double colons replaced by single underscores.
2915              
2916             This:
2917              
2918             use MooX::Press prefix => "ABC::XYZ", class => ["Foo::Bar"];
2919              
2920             Will create class "ABC::XYZ::Foo::Bar", a factory method
2921             C<< ABC::XYZ->new_foo_bar() >>, and a type constraint
2922             "Foo_Bar" in type library "ABC::XYZ::Types".
2923              
2924             =item C<< toolkit >> I<< (Str) >>
2925              
2926             Override toolkit choice for this class and any child classes.
2927              
2928             =item C<< version >> I<< (Num) >>
2929              
2930             Override version number for this class and any child classes.
2931              
2932             =item C<< authority >> I<< (Str) >>
2933              
2934             Override authority for this class and any child classes.
2935              
2936             See L</Import Options>.
2937              
2938             =item C<< prefix >> I<< (Str) >>
2939              
2940             Override namespace prefix for this class and any child classes.
2941              
2942             See L</Import Options>.
2943              
2944             =item C<< factory_package >> I<< (Str) >>
2945              
2946             Override factory_package for this class and any child classes.
2947              
2948             See L</Import Options>.
2949              
2950             =item C<< mutable >> I<< (Bool) >>
2951              
2952             Override mutability for this class and any child classes.
2953              
2954             See L</Import Options>.
2955              
2956             =item C<< default_is >> I<< (Str) >>
2957              
2958             Override default_is for this class and any child classes.
2959              
2960             See L</Import Options>.
2961              
2962             =item C<< end >> I<< (CodeRef|ArrayRef[CodeRef]) >>
2963              
2964             Override C<end> for this class and any child classes.
2965              
2966             See L</Import Options>.
2967              
2968             =item C<< begin >> I<< (CodeRef|ArrayRef[CodeRef]) >>
2969              
2970             Override C<begin> for this class and any child classes.
2971              
2972             use MooX::Press::Keywords qw( true false );
2973             use MooX::Press (
2974             prefix => 'Library',
2975             class => [
2976             'Book' => {
2977             begin => sub {
2978             my $classname = shift; # "Library::Book"
2979             my $registry = Type::Registry->for_class($classname);
2980             $registry->alias_type('ArrayRef[Str]' => 'StrList')
2981             },
2982             has => {
2983             'title' => { type => 'Str', required => true },
2984             'authors' => { type => 'StrList', required => true },
2985             },
2986             },
2987             ],
2988             );
2989              
2990             See L</Import Options>.
2991              
2992             =item C<< import >> I<< (OptList) >>
2993              
2994             Allows you to import packages into classes.
2995              
2996             use MooX::Press (
2997             prefix => 'Library',
2998             class => [
2999             toolkit => 'Moose',
3000             import => [ 'MooseX::StrictConstructor' ],
3001             ...,
3002             ],
3003             );
3004              
3005             Note that the coderefs you pass to MooX::Press are evaluated in the caller
3006             namespace, so this isn't very useful if you're looking to import functions.
3007             It can be useful for many MooX, MooseX, and MouseX extensions though.
3008              
3009             =item C<< overload >> I<< (HashRef) >>
3010              
3011             Options to pass to C<< use overload >>.
3012              
3013             =item C<< abstract >> I<< (Bool) >>
3014              
3015             Marks the class as abstract. Abstract classes cannot have factories or
3016             coercions, and do not have a constuctor. They may be inherited from though.
3017             It is usually better to use roles.
3018              
3019             =back
3020              
3021             =head3 Role Options
3022              
3023             Options for roles are largely the same as for classes with the following
3024             exceptions:
3025              
3026             =over
3027              
3028             =item C<< requires >> I<< (ArrayRef) >>
3029              
3030             A list of methods required by the role.
3031              
3032             package MyApp;
3033             use MooX::Press (
3034             role => [
3035             'Milkable' => {
3036             requires => ['get_udder'],
3037             ...,
3038             },
3039             ],
3040             );
3041              
3042             Each method can optionally be followed by a method-defining hashref like
3043             in C<can>:
3044              
3045             package MyApp;
3046             use MooX::Press (
3047             role => [
3048             'Milkable' => {
3049             requires => [
3050             'get_udder', { signature => [...], named => 0 },
3051             ],
3052             ...,
3053             },
3054             ],
3055             );
3056              
3057             These hashrefs are currently ignored, but may be useful for people reading
3058             your role declarations.
3059              
3060             =item C<< extends >> I<< (Any) >>
3061              
3062             This option is disallowed.
3063              
3064             =item C<< can >> I<< (HashRef[CodeRef|HashRef]) >>
3065              
3066             The alternative style for defining methods may cause problems with the order
3067             in which things happen. Because C<< use MooX::Press >> happens at compile time,
3068             the following might not do what you expect:
3069              
3070             package MyApp;
3071             use MooX::Press (
3072             role => ["MyRole"],
3073             class => ["MyClass" => { with => "MyRole" }],
3074             );
3075            
3076             package MyApp::MyRole;
3077             sub my_function { ... }
3078              
3079             The "my_function" will not be copied into "MyApp::MyClass" because at the
3080             time the class is constructed, "my_function" doesn't yet exist within the
3081             role "MyApp::MyRole".
3082              
3083             You can combat this by changing the order you define things in:
3084              
3085             package MyApp::MyRole;
3086             sub my_function { ... }
3087            
3088             package MyApp;
3089             use MooX::Press (
3090             role => ["MyRole"],
3091             class => ["MyClass" => { with => "MyRole" }],
3092             );
3093              
3094             If you don't like having method definitions "above" MooX::Press in your file,
3095             then you can move them out into a module.
3096              
3097             # MyApp/Methods.pm
3098             #
3099             package MyApp::MyRole;
3100             sub my_function { ... }
3101              
3102             # MyApp.pm
3103             #
3104             package MyApp;
3105             use MyApp::Methods (); # load extra methods
3106             use MooX::Press (
3107             role => ["MyRole"],
3108             class => ["MyClass" => { with => "MyRole" }],
3109             );
3110              
3111             Or force MooX::Press to happen at runtime instead of compile time.
3112              
3113             package MyApp;
3114             require MooX::Press;
3115             import MooX::Press (
3116             role => ["MyRole"],
3117             class => ["MyClass" => { with => "MyRole" }],
3118             );
3119            
3120             package MyApp::MyRole;
3121             sub my_function { ... }
3122            
3123             =item C<< subclass >> I<< (Any) >>
3124              
3125             This option is not allowed.
3126              
3127             =item C<< factory >> I<< (Any) >>
3128              
3129             This option is not allowed.
3130              
3131             =item C<< mutable >> I<< (Any) >>
3132              
3133             This option is silently ignored.
3134              
3135             =item C<< overload >> I<< (Any) >>
3136              
3137             This option is not allowed.
3138              
3139             =item C<< abstract >> I<< (Any) >>
3140              
3141             This option is not allowed.
3142              
3143             =item C<< interface >> I<< (Bool) >>
3144              
3145             An interface is a "light" role.
3146              
3147             If a role is marked as an interface, it must not have any C<can>, C<before>,
3148             C<after>, C<around>, C<has>, or C<multimethod> options. C<requires>,
3149             C<constant>, and C<type_name> are allowed. C<with> is allowed; you should
3150             only use C<with> to compose other interfaces (not full roles) though this
3151             is not currently enforced.
3152              
3153             =item C<< before_apply >> I<< (CodeRef|ArrayRef[CodeRef]) >>
3154              
3155             Coderef to pass to C<before_apply> from L<Role::Hooks>.
3156              
3157             =item C<< after_apply >> I<< (CodeRef|ArrayRef[CodeRef]) >>
3158              
3159             Coderef to pass to C<after_apply> from L<Role::Hooks>.
3160              
3161             =back
3162              
3163             =head3 Attribute Specifications
3164              
3165             Attribute specifications are mostly just passed to the OO toolkit unchanged,
3166             somewhat like:
3167              
3168             has $attribute_name => %attribute_spec;
3169              
3170             So whatever specifications (C<required>, C<trigger>, C<coerce>, etc) the
3171             underlying toolkit supports should be supported.
3172              
3173             The following are exceptions:
3174              
3175             =over
3176              
3177             =item C<< is >> I<< (Str) >>
3178              
3179             This is optional rather than being required, and defaults to "ro" (or
3180             to C<default_is> if you defined that).
3181              
3182             MooX::Press supports the Moo-specific values of "rwp" and "lazy", and
3183             will translate them if you're using Moose or Mouse.
3184              
3185             There is a special value C<< is => "private" >> to create private
3186             attributes. These attributes cannot be set by the constructor
3187             (they always have C<< init_arg => undef >>) and do not have accessor
3188             methods by default. They are stored inside-out, so cannot even be accessed
3189             using direct hashref access of the object. If you're thinking this makes
3190             them totally inaccessible, and therefore useless, think again.
3191              
3192             For private attributes, you can request an accessor as a coderef:
3193              
3194             my $my_attr; # pre-declare lexical!
3195             use MooX::Press (
3196             'class:Foo' => {
3197             has => {
3198             'my_attr' => { is => 'private', accessor => \$my_attr },
3199             },
3200             can => {
3201             'my_method' => sub {
3202             my $self = shift;
3203             $self->$my_attr(42); # writer
3204             return $self->$my_attr(); # reader
3205             },
3206             },
3207             },
3208             );
3209              
3210             Private attributes may have defaults and builders (but they are always
3211             lazy!) They may also have C<handles>. You may find you can do everything
3212             you need with the builders and delegations, so having an accessor is
3213             unnecessary.
3214              
3215             (As of version 0.050, setting C<reader>, C<writer>, C<accessor>, C<clearer>,
3216             or C<predicate> to a scalarref will also work for I<public> attributes
3217             too!)
3218              
3219             =item C<< isa >> I<< (Str|Object) >>
3220              
3221             When the type constraint is a string, it is B<always> assumed to be a class
3222             name and your application's namespace prefix is added. So
3223             C<< isa => "HashRef" >> doesn't mean what you think it means. It means
3224             an object blessed into the "YourApp::HashRef" class.
3225              
3226             That is a feature though, not a weakness.
3227              
3228             use MooX::Press (
3229             prefix => 'Nature',
3230             class => [
3231             'Leaf' => {},
3232             'Tree' => {
3233             has => {
3234             'nicest_leaf' => { isa => 'Leaf' },
3235             },
3236             },
3237             ],
3238             );
3239              
3240             The C<< Nature::Tree >> and C<< Nature::Leaf >> classes will be built, and
3241             MooX::Press knows that the C<nicest_leaf> is supposed to be a blessed
3242             C<< Nature::Leaf >> object.
3243              
3244             String type names can be prefixed with C<< @ >> or C<< % >> to indicate an
3245             arrayref or hashref of a type:
3246              
3247             use MooX::Press (
3248             prefix => 'Nature',
3249             class => [
3250             'Leaf' => {},
3251             'Tree' => {
3252             has => {
3253             'foliage' => { isa => '@Leaf' },
3254             },
3255             },
3256             ],
3257             );
3258              
3259             For more everything else, use blessed type constraint objects, such as those
3260             from L<Types::Standard>, or use C<type> as documented below.
3261              
3262             use Types::Standard qw( Str );
3263             use MooX::Press (
3264             prefix => 'Nature',
3265             class => [
3266             'Leaf' => {},
3267             'Tree' => {
3268             has => {
3269             'foliage' => { isa => '@Leaf' },
3270             'species' => { isa => Str },
3271             },
3272             },
3273             ],
3274             );
3275              
3276             =item C<< type >> I<< (Str) >>
3277              
3278             C<< type => "HashRef" >> does what you think C<< isa => "HashRef" >> should
3279             do. More specifically it searches (by name) your type library, along with
3280             L<Types::Standard>, L<Types::Common::Numeric>, and L<Types::Common::String>
3281             to find the type constraint it thinks you wanted. It's smart enough to deal
3282             with parameterized types, unions, intersections, and complements.
3283              
3284             use MooX::Press (
3285             prefix => 'Nature',
3286             class => [
3287             'Leaf' => {},
3288             'Tree' => {
3289             has => {
3290             'foliage' => { isa => '@Leaf' },
3291             'species' => { type => 'Str' },
3292             },
3293             },
3294             ],
3295             );
3296              
3297             C<< type => $blessed_type_object >> does still work.
3298              
3299             C<type> and C<isa> are basically the same as each other, but differ in
3300             how they'll interpret a string. C<isa> assumes it's a class name as applies
3301             the package prefix to it; C<type> assumes it's the name of a type constraint
3302             which has been defined in some type library somewhere.
3303              
3304             =item C<< does >> I<< (Str) >>
3305              
3306             Similarly to C<isa>, these will be given your namespace prefix.
3307              
3308             # These mean the same...
3309             does => 'SomeRole',
3310             type => Types::Standard::ConsumerOf['MyApp::SomeRole'],
3311              
3312             =item C<< enum >> I<< (ArrayRef[Str]) >>
3313              
3314             This is a cute shortcut for an enum type constraint.
3315              
3316             # These mean the same...
3317             enum => ['foo', 'bar'],
3318             type => Types::Standard::Enum['foo', 'bar'],
3319              
3320             If the type constraint is set to an enum and C<handles> is provided,
3321             then MooX::Press will automatically load L<MooX::Enumeration> or
3322             L<MooseX::Enumeration> as appropriate. (This is not supported for
3323             Mouse.)
3324              
3325             use MooX::Press (
3326             prefix => 'Nature',
3327             class => [
3328             'Leaf' => {
3329             has => {
3330             'colour' => {
3331             enum => ['green', 'red', 'brown'],
3332             handles => 2,
3333             default => 'green',
3334             },
3335             },
3336             },
3337             ],
3338             );
3339            
3340             my $leaf = Nature->new_leaf;
3341             if ( $leaf->colour_is_green ) {
3342             print "leaf is green!\n";
3343             }
3344              
3345             =item C<< handles_via >> I<< (Str|ArrayRef[Str]) >>
3346              
3347             If your attribute has a C<handles_via> option, MooX::Press will load
3348             L<Sub::HandlesVia> for you.
3349              
3350             =item C<< handles >> I<< (ArrayRef|HashRef|RoleName) >>
3351              
3352             C<handles> is effectively a mapping of methods in the package being
3353             defined to methods in a target package. If C<handles> is a hashref,
3354             then it is obvious how that works. If C<handles> is a role name, then
3355             the mapping includes all the methods that are part of the role's API,
3356             and they map to methods of the same name in the target package.
3357             (Only Moose and Mouse support C<handles> being a role name.)
3358              
3359             For attributes with an enum type constraint, the special values
3360             C<< handles => 1 >> and C<< handles => 2 >> described above also
3361             work.
3362              
3363             When C<handles> is an arrayref, then the different backend modules
3364             would interpret it differently:
3365              
3366             # Moo, Moose, Mouse, Sub::HandlesVia, Moo(se)X::Enumeration
3367             [ "value1", "value2", "value3", "value4" ]
3368            
3369             # Lexical::Accessor
3370             [ "key1" => "value1", "key2" => "value2" ]
3371              
3372             Since version 0.050, MooX::Press smooths over the differences between
3373             them by converting these arrayrefs to hashrefs. Rather surprisingly,
3374             I<< the Lexical::Accessor interpretation of arrayrefs is used >>. It
3375             is treated as a list of key-value pairs.
3376              
3377             This is because even though that's the minority interpretation, it's
3378             the more useful interpretation, allowing methods from the target
3379             package to be given a different name in the package being defined,
3380             or even assigned to lexical variables.
3381              
3382             has => [
3383             'ua' => {
3384             is => 'bare',
3385             default => sub { HTTP::Tiny->new },
3386             handles => [
3387             \$get => 'get',
3388             \$post => 'post',
3389             ],
3390             },
3391             ],
3392              
3393             Now C<< $get >> will be a coderef that you can call as a method:
3394              
3395             $self->$get($url); # same as $self->{ua}->get($url)
3396              
3397             If you use C<< handles => \%hash >>, you should get expected behaviour.
3398             If you use C<< handles => \@array >>, just be aware that your array is
3399             going to be interpreted like a hash from MooX::Press 0.050 onwards!
3400              
3401             =item C<< coerce >> I<< (Bool|CodeRef) >>
3402              
3403             MooX::Press automatically implies C<< coerce => 1 >> when you give a
3404             type constraint that has a coercion. If you don't want coercion then
3405             explicitly provide C<< coerce => 0 >>.
3406              
3407             C<< coerce => sub { ... } >> is supported even for Moose and Mouse.
3408              
3409             =item C<< builder >> I<< ("1"|Str|CodeRef) >>
3410              
3411             MooX::Press supports the Moo-specific C<< builder => 1 >> and
3412             C<< builder => sub { ... } >> and will translate them if you're using
3413             Moose or Mouse.
3414              
3415             =item C<< trigger >> I<< ("1"|Str|CodeRef) >>
3416              
3417             MooX::Press supports the Moo-specific C<< trigger => 1 >> and
3418             C<< trigger => $methodname >> and will translate them if you're using
3419             Moose or Mouse.
3420              
3421             =item C<< clearer >> I<< ("1"|Str) >>
3422              
3423             MooX::Press supports the Moo-specific C<< clearer => 1 >> and
3424             will translate it if you're using Moose or Mouse.
3425              
3426             =item C<< default >> I<< (CodeRef|~Ref|Overloaded|ScalarRef) >>
3427              
3428             Coderefs and non-reference values can be used as defaults the same
3429             as in Moo/Moose/Mouse.
3430              
3431             Blessed L<Ask::Question> objects are additionally supported as
3432             defaults. The C<type> of the attribute will automatically be injected
3433             as the target type of the question if the target type is missing.
3434              
3435             A scalarref is converted to an L<Ask::Question> object so:
3436              
3437             has age => ( is => 'ro', type => 'Int', default => \"Enter age" );
3438              
3439             Will require age to be an integer, and if it's not provided to the
3440             constructor, L<Ask> will prompt the user via STDIN/STDOUT, a GUI
3441             dialogue box, or whatever other method is available.
3442              
3443             =back
3444              
3445             =head3 Method Signatures
3446              
3447             Most places where a coderef is expected, MooX::Press will also accept a
3448             hashref of the form:
3449              
3450             {
3451             signature => [ ... ],
3452             named => 1,
3453             code => sub { ... },
3454             attributes => [ ... ],
3455             }
3456              
3457             The C<signature> is a specification to be passed to C<compile> or
3458             C<compile_named_oo> from L<Type::Params> (depending on whether C<named>
3459             is true or false).
3460              
3461             Unlike L<Type::Params>, these signatures allow type constraints to be
3462             given as strings, which will be looked up by name.
3463              
3464             This should work for C<can>, C<factory_can>, C<type_library_can>,
3465             C<factory>, C<builder> methods, and method modifiers. (Though if you
3466             are doing type checks in both the methods and method modifiers, this
3467             may result in unnecessary duplication of checks.)
3468              
3469             The invocant (C<< $self >>) is not included in the signature.
3470             (For C<around> method modifiers, the original coderef C<< $orig >> is
3471             logically a second invocant. For C<factory> methods installed in the
3472             factory package, the factory package name and class name are both
3473             considered invocants.)
3474              
3475             Example with named parameters:
3476              
3477             use MooX::Press (
3478             prefix => 'Wedding',
3479             class => [
3480             'Person' => { has => [qw( $name $spouse )] },
3481             'Officiant' => {
3482             can => {
3483             'marry' => {
3484             signature => [ bride => 'Person', groom => 'Person' ],
3485             named => 1,
3486             code => sub {
3487             my ($self, $args) = @_;
3488             $args->bride->spouse($args->groom);
3489             $args->groom->spouse($args->bride);
3490             printf("%s, you may kiss the bride\n", $args->groom->name);
3491             return $self;
3492             },
3493             },
3494             },
3495             },
3496             ],
3497             );
3498            
3499             my $alice = Wedding->new_person(name => 'Alice');
3500             my $bob = Wedding->new_person(name => 'Robert');
3501            
3502             my $carol = Wedding->new_officiant(name => 'Carol');
3503             $carol->marry(bride => $alice, groom => $bob);
3504              
3505             Example with positional parameters:
3506              
3507             use MooX::Press (
3508             prefix => 'Wedding',
3509             class => [
3510             'Person' => { has => [qw( $name $spouse )] },
3511             'Officiant' => {
3512             can => {
3513             'marry' => {
3514             signature => [ 'Person', 'Person' ],
3515             code => sub {
3516             my ($self, $bride, $groom) = @_;
3517             $bride->spouse($groom);
3518             $groom->spouse($bride);
3519             printf("%s, you may kiss the bride\n", $groom->name);
3520             return $self;
3521             },
3522             },
3523             },
3524             },
3525             ],
3526             );
3527            
3528             my $alice = Wedding->new_person(name => 'Alice');
3529             my $bob = Wedding->new_person(name => 'Robert');
3530            
3531             my $carol = Wedding->new_officiant(name => 'Carol');
3532             $carol->marry($alice, $bob);
3533              
3534             Methods with a mixture of named and positional parameters are not supported.
3535             If you really want such a method, don't provide a signature; just provide a
3536             coderef and manually unpack C<< @_ >>.
3537              
3538             B<< Advanced features: >>
3539              
3540             C<signature> may be a coderef, which is passed C<< @_ >> (minus invocants)
3541             and is expected to return a new C<< @_ >> in list context after checking
3542             and optionally coercing parameters.
3543              
3544             Setting C<< optimize => 1 >> tells MooX::Press to attempt to perform
3545             additional compile-time optimizations on the signature to make it slightly
3546             faster at runtime. (Sometimes it will find it's unable to optimize anything,
3547             so you've just wasted time at compile time.)
3548              
3549             C<code> can be a string of Perl code like C<< sub { ... } >> instead of
3550             a real coderef. This doesn't let you close over any variables, but if
3551             you can provide code this way, it might be slightly faster.
3552              
3553             =head2 Optimization Features
3554              
3555             MooX::Press will automatically load and apply L<MooX::XSConstructor> if it's
3556             installed, which will optmimize constructors for some very basic classes.
3557             Again, this is only for Moo classes.
3558              
3559             MooX::Press will automatically load L<MooseX::XSAccessor> if it's installed,
3560             which speeds up some Moose accessors. This is only used for Moose classes.
3561              
3562             =head2 Subclassing MooX::Press
3563              
3564             All the internals of MooX::Press are called as methods, which should make
3565             subclassing it possible.
3566              
3567             package MyX::Press;
3568             use parent 'MooX::Press';
3569             use Class::Method::Modifiers;
3570            
3571             around make_class => sub {
3572             my $orig = shift;
3573             my $self = shift;
3574             my ($name, %opts) = @_;
3575             ## Alter %opts here
3576             my $qname = $self->$orig($name, %opts);
3577             ## Maybe do something to the returned class
3578             return $qname;
3579             };
3580              
3581             It is beyond the scope of this documentation to fully describe all the methods
3582             you could potentially override, but here is a quick summary of some that may
3583             be useful.
3584              
3585             =over
3586              
3587             =item C<< import(%opts|\%opts) >>
3588              
3589             =item C<< qualify_name($name, $prefix) >>
3590              
3591             =item C<< croak($error) >>
3592              
3593             =item C<< prepare_type_library($qualified_name) >>
3594              
3595             =item C<< make_type_for_role($name, %opts) >>
3596              
3597             =item C<< make_type_for_class($name, %opts) >>
3598              
3599             =item C<< make_role($name, %opts) >>
3600              
3601             =item C<< make_class($name, %opts) >>
3602              
3603             =item C<< install_methods($qualified_name, \%methods) >>
3604              
3605             =item C<< install_constants($qualified_name, \%values) >>
3606              
3607             =back
3608              
3609             =head1 FAQ
3610              
3611             This is a new module so I haven't had any questions about it yet, let alone
3612             any frequently asked ones, but I will anticipate some.
3613              
3614             =head2 Why doesn't MooX::Press automatically import strict and warnings for me?
3615              
3616             Your MooX::Press import will typically contain a lot of strings, maybe some
3617             as barewords, some coderefs, etc. You should manually import strict and
3618             warnings B<before> importing MooX::Press to ensure all of that is covered
3619             by strictures.
3620              
3621             =head2 Why all the factory stuff?
3622              
3623             Factories are big and cool and they put lots of smoke into our atmosphere.
3624              
3625             Also, if you do something like:
3626              
3627             use constant APP => 'MyGarden';
3628             use MooX::Press (
3629             prefix => APP,
3630             role => [
3631             'LeafGrower' => {
3632             has => [ '@leafs' => sub { [] } ],
3633             can => {
3634             'grow_leaf' => sub {
3635             my $self = shift;
3636             my $leaf = $self->FACTORY->new_leaf;
3637             push @{ $self->leafs }, $leaf;
3638             return $leaf;
3639             },
3640             },
3641             },
3642             ],
3643             class => [
3644             'Leaf',
3645             'Tree' => { with => ['LeafGrower'] },
3646             ],
3647             );
3648            
3649             my $tree = APP->new_tree;
3650             my $leaf = $tree->grow_leaf;
3651              
3652             And you will notice that the string "MyGarden" doesn't appear anywhere in
3653             the definitions for any of the classes and roles. The prefix could be
3654             changed to something else entirely and all the classes and roles, all the
3655             methods within them, would continue to work.
3656              
3657             Whole collections of classes and roles now have portable namespaces. The same
3658             classes and roles could be used with different prefixes in different scripts.
3659             You could load two different versions of your API in the same script with
3660             different prefixes. The possibilities are interesting.
3661              
3662             Factory methods are also exportable.
3663              
3664             use MyGarden 'new_tree';
3665            
3666             my $maple = new_tree(); # called as a function, not a method
3667              
3668             Exported functions can be renamed (see L<Exporter::Tiny>).
3669              
3670             use MyGarden 'new_tree' => { -as => 'germinate' };
3671            
3672             my $maple = germinate();
3673              
3674             =head2 Why doesn't C<< $object->isa("Leaf") >> work?
3675              
3676             In the previous question, C<< $object->isa("Leaf") >> won't work to check
3677             if an object is a Leaf. This is because the full name of the class is
3678             "MyGarden::Leaf".
3679              
3680             You can of course check C<< $object->isa("MyGarden::Leaf") >> but this
3681             means you're starting to hard-code class names and prefixes again, which
3682             is one of the things MooX::Press aims to reduce.
3683              
3684             The "correct" way to check something is a leaf is:
3685              
3686             use MyGarden::Types qw( is_Leaf );
3687            
3688             if ( is_Leaf($object) ) {
3689             ...;
3690             }
3691              
3692             Or if you really want to use C<isa>:
3693              
3694             use MyGarden::Types qw( Leaf );
3695            
3696             if ( $object->isa(Leaf->class) ) {
3697             ...;
3698             }
3699              
3700             However, the type library is only available I<after> you've used MooX::Press.
3701             This can make it tricky to refer to types within your methods.
3702              
3703             use constant APP => 'MyGarden';
3704             use MooX::Press (
3705             prefix => APP,
3706             class => [
3707             'Leaf',
3708             'Tree' => {
3709             can => {
3710             'add_leaf' => sub {
3711             my ($self, $leaf) = @_;
3712            
3713             # How to check is_Leaf() here?
3714             # It's kind of tricky!
3715            
3716             my $t = $self->FACTORY->type_library->get_type('Leaf');
3717             if ($t->check($leaf)) {
3718             ...;
3719             }
3720             },
3721             },
3722             },
3723             ],
3724             );
3725              
3726             As of version 0.019, MooX::Press has method signatures, so you're less
3727             likely to need to check types within your methods; you can just do it in
3728             the signature. This won't cover every case you need to check types, but
3729             it will cover the common ones.
3730              
3731             use constant APP => 'MyGarden';
3732             use MooX::Press (
3733             prefix => APP,
3734             class => [
3735             'Leaf',
3736             'Tree' => {
3737             can => {
3738             'add_leaf' => {
3739             signature => ['Leaf'],
3740             code => sub {
3741             my ($self, $leaf) = @_;
3742             ...;
3743             },
3744             },
3745             },
3746             },
3747             ],
3748             );
3749              
3750             This also makes your code more declarative and less imperative, and that
3751             is a Good Thing, design-wise.
3752              
3753             =head2 The plural of "leaf" is "leaves", right?
3754              
3755             Yeah, but that sounds like something is leaving.
3756              
3757             =head2 How do generators work?
3758              
3759             A class generator is like a class of classes.
3760              
3761             A role generator is like a class of roles.
3762              
3763             use MooX::Press (
3764             prefix => 'MyApp',
3765             class => [
3766             'Animal' => {
3767             has => ['$name'],
3768             },
3769             ],
3770             class_generator => [
3771             'Species' => sub {
3772             my ($gen, $binomial) = @_;
3773             return {
3774             extends => ['Animal'],
3775             constant => { binomial => $binomial },
3776             };
3777             },
3778             ],
3779             );
3780              
3781             This generates MyApp::Animal as a class, as you might expect, but also
3782             creates a class generator called MyApp::Species.
3783              
3784             MyApp::Species is not itself a class but it can make classes. Calling
3785             either C<< MyApp::Species->generate_package >> or
3786             C<< MyApp->generate_species >> will compile a new class
3787             and return the class name as a string.
3788              
3789             my $Human = MyApp->generate_species('Homo sapiens');
3790             my $Dog = MyApp->generate_species('Canis familiaris');
3791            
3792             my $alice = $Human->new(name => 'Alice');
3793             say $alice->name; # Alice
3794             say $alice->binomial; # Homo sapiens
3795            
3796             my $fido = $Dog->new(name => 'Fido');
3797             $fido->isa($Dog); # true
3798             $fido->isa($Human); # false
3799             $fido->isa('MyApp::Animal'); # true
3800             $fido->isa('MyApp::Species'); # false!!!
3801            
3802             use Types::Standard -types;
3803             use MyApp::Types -types;
3804            
3805             is_ClassName($fido) # false
3806             is_Object($fido) # true
3807             is_Animal($fido); # true
3808             is_SpeciesInstance($fido); # true
3809             is_SpeciesClass($fido); # false
3810             is_ClassName($Dog) # true
3811             is_Object($Dog) # false
3812             is_Animal($Dog); # false
3813             is_SpeciesInstance($Dog); # false
3814             is_SpeciesClass($Dog); # true
3815              
3816             Note that there is no B<Species> type created, but instead a pair of types
3817             is created: B<SpeciesClass> and B<SpeciesInstance>.
3818              
3819             It is also possible to inherit from generated classes.
3820              
3821             use MooX::Press (
3822             prefix => 'MyApp',
3823             class => [
3824             'Animal' => {
3825             has => ['$name'],
3826             },
3827             'Dog' => {
3828             extends => [ 'Species' => ['Canis familiaris'] ]
3829             },
3830             ],
3831             class_generator => [
3832             'Species' => sub {
3833             my ($gen, $binomial) = @_;
3834             return {
3835             extends => ['Animal'],
3836             constant => { binomial => $binomial },
3837             };
3838             },
3839             ],
3840             );
3841            
3842             my $fido = MyApp->new_dog(name => 'Fido');
3843              
3844             The inheritance heirarchy for C<< $fido >> is something like:
3845              
3846             Moo::Object
3847             -> MyApp::Animal
3848             -> MyApp::Species::__GEN000001__
3849             -> MyApp::Dog
3850              
3851             Note that MyApp::Species itself isn't in that heirarchy!
3852              
3853             Generated roles work pretty much the same, but C<role_generator> instead
3854             of C<class_generator>, C<does> instead of C<isa>, and C<with> instead of
3855             C<extends>.
3856              
3857             No type constraints are automatically created for generated roles.
3858              
3859             =head2 Are you insane?
3860              
3861             Quite possibly.
3862              
3863             =head1 BUGS
3864              
3865             Please report any bugs to
3866             L<http://rt.cpan.org/Dist/Display.html?Queue=MooX-Press>.
3867              
3868             =head1 SEE ALSO
3869              
3870             L<Zydeco::Lite>, L<Zydeco>.
3871              
3872             L<Moo>, L<MooX::Struct>, L<Types::Standard>.
3873              
3874             L<portable::loader>.
3875              
3876             =head1 AUTHOR
3877              
3878             Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
3879              
3880             =head1 COPYRIGHT AND LICENCE
3881              
3882             This software is copyright (c) 2019-2020 by Toby Inkster.
3883              
3884             This is free software; you can redistribute it and/or modify it under
3885             the same terms as the Perl 5 programming language system itself.
3886              
3887             =head1 DISCLAIMER OF WARRANTIES
3888              
3889             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
3890             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
3891             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
3892