File Coverage

blib/lib/Sub/MultiMethod.pm
Criterion Covered Total %
statement 388 441 87.9
branch 168 242 69.4
condition 69 108 63.8
subroutine 55 60 91.6
pod 13 14 92.8
total 693 865 80.1


line stmt bran cond sub pod time code
1 23     23   6111765 use 5.008001;
  23         100  
2 23     23   146 use strict;
  23         44  
  23         804  
3 23     23   147 use warnings;
  23         77  
  23         2493  
4              
5             package Sub::MultiMethod;
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '1.003';
9              
10 23     23   153 use B ();
  23         75  
  23         664  
11 23     23   5330 use Eval::TypeTiny qw( set_subname );
  23         33696  
  23         173  
12 23         176 use Exporter::Shiny qw(
13             multimethod monomethod
14             multifunction monofunction
15             VOID SCALAR LIST NONVOID NONSCALAR NONLIST
16 23     23   97681 );
  23         13502  
17 23     23   13953 use Role::Hooks;
  23         184357  
  23         1517  
18 23     23   298 use List::Util qw( max min any );
  23         105  
  23         2568  
19 23     23   191 use Scalar::Util qw( refaddr );
  23         54  
  23         1227  
20 23     23   17934 use Type::Params ();
  23         1472571  
  23         1085  
21 23     23   213 use Types::TypeTiny qw( TypeTiny );
  23         48  
  23         226  
22 23     23   90133 use Types::Standard qw( -types -is );
  23         56  
  23         233  
23              
24             use constant {
25 23         20183 VOID => 'VOID',
26             LIST => 'LIST',
27             SCALAR => 'SCALAR',
28             NONVOID => '~VOID',
29             NONLIST => '~LIST',
30             NONSCALAR => '~SCALAR',
31 23     23   427165 };
  23         55  
32              
33             # Options other than these will be passed through to
34             # Type::Params.
35             #
36             my %KNOWN_OPTIONS = (
37             alias => 1,
38             code => 1,
39             compiled => 1,
40             copied => 1,
41             declaration_order => 1,
42             die => 1,
43             height => 1,
44             if => 1,
45             is_monomethod => 1,
46             method => 1,
47             named => 'legacy',
48             no_dispatcher => 1,
49             return => 1,
50             score => 1,
51             signature => 'legacy',
52             want => 1,
53             );
54              
55             # But not these!
56             #
57             my %BAD_OPTIONS = (
58             want_details => 1,
59             want_object => 1,
60             want_source => 1,
61             goto_next => 1,
62             on_die => 1,
63             message => 1,
64             );
65              
66             my %CACHE = ();
67              
68             {
69             my %CANDIDATES;
70             sub _get_multimethods_ref {
71 450     450   934 my ($me, $target) = @_;
72 450 100       1242 if ( not $CANDIDATES{$target} ) {
73 68         261 $CANDIDATES{$target} = {};
74             }
75 450         1106 $CANDIDATES{$target};
76             }
77             }
78              
79             sub get_multimethods {
80 34     34 1 77 my ($me, $target) = @_;
81 34         54 sort keys %{ $me->_get_multimethods_ref($target) };
  34         98  
82             }
83              
84             sub _get_multimethod_candidates_ref {
85 410     410   883 my ($me, $target, $method_name) = @_;
86 410 100       1091 my ( $package_key, $method_key ) = ref( $method_name )
87             ? ( '__CODE__', refaddr( $method_name ) )
88             : ( $target, $method_name );
89 410         1128 my $mm = $me->_get_multimethods_ref( $package_key );
90 410   100     1962 $mm->{$method_key} ||= [];
91             }
92              
93             sub _clear_multimethod_candidates_ref {
94 4     4   12 my ( $me, $target, $method_name ) = ( shift, @_ );
95 4         17 $me->clear_cache;
96 4 50       15 my ( $package_key, $method_key ) = ref( $method_name )
97             ? ( '__CODE__', refaddr( $method_name ) )
98             : ( $target, $method_name );
99 4         13 my $mm = $me->_get_multimethods_ref( $package_key );
100 4         10 delete $mm->{$method_key};
101 4         11 return $me;
102             }
103            
104             sub get_multimethod_candidates {
105 90     90 1 258 my ($me, $target, $method_name) = @_;
106 90         156 @{ $me->_get_multimethod_candidates_ref($target, $method_name) };
  90         245  
107             }
108              
109             sub has_multimethod_candidates {
110 94     94 1 308 my ($me, $target, $method_name) = @_;
111 94         210 scalar @{ $me->_get_multimethod_candidates_ref($target, $method_name) };
  94         257  
112             }
113              
114             sub _add_multimethod_candidate {
115 226     226   743 my ($me, $target, $method_name, $spec) = @_;
116 226         909 $me->clear_cache;
117 226         790 my $mmc = $me->_get_multimethod_candidates_ref($target, $method_name);
118 23     23   213 no warnings 'uninitialized';
  23         58  
  23         9660  
119 226 50 66     1059 if ( @$mmc and $spec->{method} != $mmc->[0]{method} ) {
120 0         0 require Carp;
121             Carp::carp(sprintf(
122             "Added multimethod candidate for %s with method=>%d but expected method=>%d",
123             $method_name,
124             $spec->{method},
125             $mmc->[0]{method},
126 0         0 ));
127             }
128 226         577 push @$mmc, $spec;
129 226         592 $me;
130             }
131              
132             sub clear_cache {
133 230     230 1 582 %CACHE = ();
134             }
135              
136             sub get_cache {
137 0     0 1 0 return \%CACHE;
138             }
139              
140             sub get_all_multimethod_candidates {
141 38     38 1 173 my ($me, $target, $method_name, $is_method) = @_;
142            
143             # Figure out which packages to consider when finding candidates.
144 38         85 my (@packages, $is_coderef_method);
145 38 100 66     1186 if (is_Int $method_name or is_ScalarRef $method_name) {
146 2         6 @packages = '__CODE__';
147 2         4 $is_coderef_method = 1;
148             }
149             else {
150             @packages = $is_method
151 36 100       126 ? @{ mro::get_linear_isa($target) }
  32         256  
152             : $target;
153             }
154            
155 38         94 my $curr_height = @packages;
156            
157             # Find candidates from each package
158 38         77 my @candidates;
159 38         89 my $final_fallback = undef;
160 38         136 PACKAGE: while (@packages) {
161 94         213 my $p = shift @packages;
162 94         185 my @c;
163 94         328 my $found = $me->has_multimethod_candidates($p, $method_name);
164 94 100       337 if ($found) {
    50          
165 56         194 @c = $me->get_multimethod_candidates($p, $method_name);
166             }
167             elsif (not $is_coderef_method) {
168 23     23   342 no strict 'refs';
  23         219  
  23         79496  
169 38 100       80 if (exists &{"$p\::$method_name"}) {
  38         260  
170             # We found a potential monomethod.
171 4         9 my $coderef = \&{"$p\::$method_name"};
  4         15  
172 4 50       18 if (!$me->known_dispatcher($coderef)) {
173             # Definite monomethod. Stop falling back.
174 4         9 $final_fallback = $coderef;
175 4         13 last PACKAGE;
176             }
177             }
178 34         80 @c = ();
179             }
180             # Record their height in case we need it later
181 90         451 $_->{height} = $curr_height for @c;
182 90         202 push @candidates, @c;
183 90         253 --$curr_height;
184             }
185            
186             # If a monomethod was found, use it as last resort
187 38 100       128 if (defined $final_fallback) {
188             push @candidates, {
189 16     16   67 signature => sub { @_ },
190 4         29 code => $final_fallback,
191             };
192             }
193            
194 38         434 return @candidates;
195             }
196              
197             {
198             my %DISPATCHERS;
199            
200             sub known_dispatcher {
201 52     52 1 139 my ($me, $coderef) = @_;
202 52         292 $DISPATCHERS{refaddr($coderef)};
203             }
204            
205             sub _mark_as_dispatcher {
206 48     48   141 my ($me, $coderef) = @_;
207 48         186 $DISPATCHERS{refaddr($coderef)} = 1;
208 48         92 $me;
209             }
210            
211             sub _unmark_as_dispatcher {
212 0     0   0 my ($me, $coderef) = @_;
213 0         0 $DISPATCHERS{refaddr($coderef)} = 0;
214 0         0 $me;
215             }
216             }
217              
218             sub _generate_exported_function {
219 80     80   347 my ( $me, $name, $args, $globals ) = ( shift, @_ );
220            
221 80         242 my $target = $globals->{into};
222 80 50 33     610 if ( ref $target or not defined $target ) {
223 0         0 require Carp;
224 0         0 Carp::croak( "Function $name can only be installed into a package by package name" );
225             }
226            
227 80 50       178 my %defaults = %{ $args->{defaults} || {} };
  80         501  
228 80   100     436 my $api_call = $args->{api_call} || 'install_candidate';
229            
230             return sub {
231 106     106   5708939 my $sub_name = shift;
232            
233 106         233 my @tmp_sigs;
234 106   33     1081 while ( is_ArrayRef $_[0] or is_HashRef $_[0] ) {
235 0         0 push @tmp_sigs, shift;
236             }
237            
238 106         232 my @tmp_code;
239 106 50       440 if ( @_ % 2 == 1 ) {
240 0 0       0 if ( is_CodeRef $_[-1] ) {
241 0         0 push @tmp_code, pop;
242             }
243             else {
244 0         0 require Carp;
245 0         0 Carp::croak( "Odd-length list passed to $name; should be key-value pairs" );
246             }
247             }
248            
249 106         597 my %spec = @_;
250 106 50 0     399 $spec{positional} ||= delete $spec{pos} if exists $spec{pos};
251 106 50 0     347 $spec{multiple} ||= delete $spec{multi} if exists $spec{multi};
252            
253 106         425 while ( my $sig = shift @tmp_sigs ) {
254 0 0       0 if ( is_ArrayRef $sig ) {
    0          
255 0 0       0 if ( $spec{positional} ) {
256 0         0 require Carp;
257 0         0 Carp::croak( "Leading arrayref passed as argument to $name; unexpected positional signature found in list of key-value pairs" );
258             }
259             else {
260 0         0 $spec{positional} = $sig;
261             }
262             }
263             elsif ( is_HashRef $sig ) {
264 0 0       0 if ( $spec{named} ) {
265 0         0 require Carp;
266 0         0 Carp::croak( "Leading hashref passed as argument to $name; unexpected named signature found in list of key-value pairs" );
267             }
268             else {
269 0         0 $spec{named} = [ %$sig ];
270             }
271             }
272             }
273            
274 106 50 66     366 if ( $spec{named} and $spec{positional} ) {
275 0   0     0 push @{ $spec{multiple} ||= [] }, (
276             { named => delete $spec{named}, named_to_list => !!1 },
277             { positional => delete $spec{positional} },
278 0         0 );
279             }
280            
281 106 50       293 if ( @tmp_code ) {
282 0 0       0 if ( $spec{code} ) {
283 0         0 require Carp;
284 0         0 Carp::croak( "Trailing coderef passed as argument to $name; unexpected code key found in list of key-value pairs" );
285             }
286 0         0 $spec{code} = shift @tmp_code;
287             }
288            
289 106 0 66     317 unless ( exists $spec{code} or exists $spec{return} or exists $spec{die} ) {
      33        
290 0         0 require Carp;
291 0         0 Carp::croak( "Missing 'code', 'return', or 'die'" );
292             }
293            
294 106 50       338 if ( ref $spec{return} ) {
295 0         0 require Carp;
296 0         0 Carp::croak( "Setting 'return' to a reference is not supported" );
297             }
298            
299 106 100       422 if ( $defaults{no_dispatcher} eq 'auto' ) {
300 46         468 $defaults{no_dispatcher} = 0+!! 'Role::Hooks'->is_role( $target );
301             }
302            
303 106 100       3118 $me->$api_call(
304             $target,
305             $sub_name,
306             %defaults,
307             'package' => $target,
308             'subname' => ( ref($sub_name) ? '__ANON__' : $sub_name ),
309             %spec,
310             );
311 80         1150 };
312             }
313              
314             sub _generate_multimethod {
315 46     46   281082 my ( $me, $name, $args, $globals ) = ( shift, @_ );
316 46 50       415 $args->{defaults}{no_dispatcher} = 'auto' unless exists $args->{defaults}{no_dispatcher};
317 46 50       271 $args->{defaults}{method} = !!1 unless exists $args->{defaults}{method};
318 46         416 return $me->_generate_exported_function( $name, $args, $globals );
319             }
320              
321             sub _generate_monomethod {
322 12     12   1995 my ( $me, $name, $args, $globals ) = ( shift, @_ );
323 12 50       86 $args->{defaults}{no_dispatcher} = !!1 unless exists $args->{defaults}{no_dispatcher};
324 12 50       59 $args->{defaults}{method} = !!1 unless exists $args->{defaults}{method};
325 12         69 $args->{api_call} = 'install_monomethod';
326 12         49 return $me->_generate_exported_function( $name, $args, $globals );
327             }
328              
329             sub _generate_multifunction {
330 12     12   1876 my ( $me, $name, $args, $globals ) = ( shift, @_ );
331 12 50       149 $args->{defaults}{no_dispatcher} = 'auto' unless exists $args->{defaults}{no_dispatcher};
332 12 50       54 $args->{defaults}{method} = !!0 unless exists $args->{defaults}{method};
333 12         69 return $me->_generate_exported_function( $name, $args, $globals );
334             }
335              
336             sub _generate_monofunction {
337 10     10   953 my ( $me, $name, $args, $globals ) = ( shift, @_ );
338 10 50       82 $args->{defaults}{no_dispatcher} = !!1 unless exists $args->{defaults}{no_dispatcher};
339 10 50       67 $args->{defaults}{method} = !!0 unless exists $args->{defaults}{method};
340 10         25 $args->{api_call} = 'install_monomethod';
341 10         33 return $me->_generate_exported_function( $name, $args, $globals );
342             }
343              
344             sub _extract_type_params_spec {
345 106     106   336 my ( $me, $target, $sub_name, $spec ) = ( shift, @_ );
346            
347 106         336 my %tp = ( method => 1 );
348 106 50       486 $tp{method} = $spec->{method} if defined $spec->{method};
349            
350 106 100       561 if ( is_ArrayRef $spec->{signature} ) {
351 51 100       158 my $key = $spec->{named} ? 'named' : 'positional';
352 51         167 $tp{$key} = delete $spec->{signature};
353             }
354             else {
355 55 100       167 $tp{named} = $spec->{named} if ref $spec->{named};
356             }
357            
358             # Options which are not known by this module must be intended for
359             # Type::Params instead.
360 106         504 for my $key ( keys %$spec ) {
361            
362 614 100 100     2353 next if ( $KNOWN_OPTIONS{$key} or $key =~ /^_/ );
363            
364 264 50       650 if ( $BAD_OPTIONS{$key} ) {
365 0         0 require Carp;
366 0         0 Carp::carp( "Unsupported option: $key" );
367 0         0 next;
368             }
369            
370 264         819 $tp{$key} = delete $spec->{$key};
371             }
372            
373 106   33     468 $tp{package} ||= $target;
374 106 50 66     325 $tp{subname} ||= ref( $sub_name ) ? '__ANON__' : $sub_name;
375            
376             # Historically we allowed method=2, etc
377 106 100       515 if ( is_Int $tp{method} ) {
378 98 100       322 if ( $tp{method} > 1 ) {
379 4         11 my $excess = $tp{method} - 1;
380 4         10 $tp{method} = 1;
381 4 50       19 ref( $tp{head} ) ? push( @{ $tp{head} }, ( Any ) x $excess ) : ( $tp{head} += $excess );
  0         0  
382             }
383 98 100       391 if ( $tp{method} == 1 ) {
384 86         465 $tp{method} = Any;
385             }
386             }
387              
388 106 50 66     5191 if ( not ( $tp{named} or $tp{pos} or $tp{positional} or $tp{multi} or $tp{multiple} ) ) {
      66        
      66        
      33        
389 4         19 $tp{pos} = [ Slurpy[Any] ];
390 4         2227 $spec->{smiple} = 1;
391             }
392            
393 106         430 $spec->{signature_spec} = \%tp;
394             }
395              
396             my %delete_while_copying = (
397             _id => '_id should be unique',
398             alias => 'alias should only be installed into package where originally declared',
399             copied => 'this will be set after copying',
400             height => 'this should never be kept anyway',
401             is_monomethod => 'if it has been copied, it is no longer mono!',
402             no_dispatcher => 'after a candidate gets copied from a role to a class, there SHOULD be a dispatcher',
403             );
404             sub copy_package_candidates {
405 20     20 1 43 my $me = shift;
406 20         55 my (@sources) = @_;
407 20         40 my $target = pop @sources;
408            
409 20         48 for my $source (@sources) {
410 20         96 for my $method_name ($me->get_multimethods($source)) {
411 20         63 for my $candidate ($me->get_multimethod_candidates($source, $method_name)) {
412             my %new = map {
413 128         440 $delete_while_copying{$_}
414             ? ()
415 642 100       1941 : ( $_ => $candidate->{$_} )
416             } keys %$candidate;
417 128         353 $new{copied} = 1;
418 128         346 $me->_add_multimethod_candidate($target, $method_name, \%new);
419             }
420             }
421             }
422             }
423              
424             sub install_missing_dispatchers {
425 14     14 1 611 my $me = shift;
426 14         33 my ($target) = @_;
427            
428 14         48 for my $method_name ($me->get_multimethods($target)) {
429 14         46 my ($first) = $me->get_multimethod_candidates($target, $method_name);
430             $me->install_dispatcher(
431             $target,
432             $method_name,
433 14 50       76 $first ? $first->{'method'} : 0,
434             );
435             }
436             }
437              
438             sub install_monomethod {
439 4     4 1 28 my ( $me, $target, $sub_name, %spec ) = ( shift, @_ );
440            
441 4   50     29 $spec{alias} ||= [];
442 4 50       13 $spec{alias} = [$spec{alias}] if !ref $spec{alias};
443 4         7 unshift @{$spec{alias}}, $sub_name;
  4         12  
444            
445 4         23 $me->install_candidate($target, undef, no_dispatcher => 1, %spec, is_monomethod => 1);
446             }
447              
448             my %hooked;
449             my $DECLARATION_ORDER = 0;
450             sub install_candidate {
451 106     106 1 895 my ( $me, $target, $sub_name, %spec ) = ( shift, @_ );
452 106         509 $me->_extract_type_params_spec( $target, $sub_name, \%spec );
453              
454 106         308 my $is_method = $spec{method};
455            
456 106 100       352 if ( $spec{want} ) {
457             my @canonical =
458             map {
459 1         4 ( my $x = $_ ) =~ s/^NON/~/;
460 1 50       10 $_ eq '~VOID' ? qw( SCALAR LIST ) :
    50          
    50          
461             $_ eq '~LIST' ? qw( SCALAR VOID ) :
462             $_ eq '~SCALAR' ? qw( LIST VOID ) : $_
463             }
464 1         5 map { split /,/, $_ }
465 1         5 map { uc $_ }
466 1 50       8 is_ArrayRef($spec{want}) ? @{$spec{want}} : $spec{want};
  0         0  
467 1         4 $spec{want} = \@canonical;
468             }
469            
470 106         286 $spec{declaration_order} = ++$DECLARATION_ORDER;
471            
472 106 100       760 $me->_add_multimethod_candidate($target, $sub_name, \%spec)
473             if defined $sub_name;
474            
475 106 100       330 if ($spec{alias}) {
476             my @aliases = is_ArrayRef( $spec{alias} )
477 4         14 ? @{ $spec{alias} }
478 16 100       140 : $spec{alias};
479            
480 16         40 my ($check, @sig);
481 16 50       117 if (is_CodeRef $spec{signature}) {
482 0         0 $check = $spec{signature};
483             }
484            
485             my %sig_spec = (
486 16         136 %{ $spec{signature_spec} },
487             goto_next =>
488             defined($spec{code}) ? $spec{code} :
489 0     0   0 is_CodeRef($spec{die}) ? sub { require Carp; Carp::croak($spec{die}->()) } :
  0         0  
490 0     0   0 defined($spec{die}) ? sub { require Carp; Carp::croak($spec{die}) } :
  0         0  
491 0     0   0 sub { $spec{return} },
492 16 0       46 );
    0          
    50          
493 16         50 my $code = sprintf(
494             q{
495             package %s;
496             sub {
497             $check ||= Type::Params::signature( %%sig_spec );
498             goto $check;
499             }
500             },
501             $target,
502             );
503 16         156 my $coderef = do {
504 16         46 local $@;
505 16 50 66 59   2346 eval $code or die $@,
  50         41915  
  50         622100  
506             };
507 16         55 for my $alias (@aliases) {
508 16         31 my $existing = do {
509 23     23   11248 no strict 'refs';
  23         55  
  23         15834  
510 16         130 exists(&{"$target\::$alias"})
511 16 100       28 ? \&{"$target\::$alias"}
  4         18  
512             : undef;
513             };
514 16 100       67 if ($existing) {
515 4 100 66     72 my $kind = ($spec{is_monomethod} && ($alias eq $aliases[0]))
516             ? 'Monomethod'
517             : 'Alias';
518 4         33 require Carp;
519 4         1150 Carp::croak("$kind conflicts with existing method $target\::$alias, bailing out");
520             }
521 12         68 $me->_install_coderef( $target, $alias, $coderef );
522             }
523             }
524            
525             $me->install_dispatcher($target, $sub_name, $is_method)
526 102 100 100     795 if defined $sub_name && !$spec{no_dispatcher};
527            
528 98 100 100     741 if ( !$hooked{$target} and 'Role::Hooks'->is_role($target) ) {
529             'Role::Hooks'->after_apply($target, sub {
530 20     20   11038 my ($rolepkg, $consumerpkg) = @_;
531 20         91 $me->copy_package_candidates($rolepkg => $consumerpkg);
532 20 100       90 $me->install_missing_dispatchers($consumerpkg)
533             unless 'Role::Hooks'->is_role($consumerpkg);
534 10         302 });
535 10         2777 $hooked{$target}++;
536             }
537             }
538              
539             {
540             my %CLEANUP;
541            
542             sub _install_coderef {
543 60     60   146 my $me = shift;
544 60         266 my ($target, $sub_name, $coderef) = @_;
545 60 100       540 if (is_ScalarRef $sub_name) {
    50          
546 14 100 33     138 if (is_Undef $$sub_name) {
    50          
547 4         30 set_subname("$target\::__ANON__", $coderef);
548 4         69 bless( $coderef, $me );
549 4         55 $CLEANUP{"$coderef"} = [ $target, refaddr($sub_name) ];
550 4         40 return( $$sub_name = $coderef );
551             }
552             elsif (is_CodeRef $$sub_name or is_Object $$sub_name) {
553 10 50       40 if ( $me->known_dispatcher($$sub_name) ) {
554 10         26 return $$sub_name;
555             }
556             else {
557 0         0 require Carp;
558 0         0 Carp::croak(sprintf(
559             'Sub name was a reference to an unknown coderef or object: %s',
560             $$sub_name,
561             ));
562             }
563             }
564             }
565             elsif (is_Str $sub_name) {
566 23     23   197 no strict 'refs';
  23         69  
  23         7624  
567 46         131 my $qname = "$target\::$sub_name";
568 46         279 *$qname = set_subname($qname, $coderef);
569 46         1242 return $coderef;
570             }
571 0         0 require Carp;
572 0         0 Carp::croak(sprintf(
573             'Expected string or reference to coderef as sub name, but got: %s %s',
574             $sub_name,
575             ));
576             }
577            
578             sub DESTROY {
579 4     4   3393 my $blessed_coderef = shift;
580 4 50       9 my ( $target, $sub_name ) = @{ $CLEANUP{"$blessed_coderef"} or [] };
  4         30  
581 4 50 33     142 if ( $target and $sub_name ) {
582 4         19 $blessed_coderef->_clear_multimethod_candidates_ref($target, $sub_name);
583             }
584 4         105 return;
585             }
586             }
587              
588             sub install_dispatcher {
589 86     86 1 192 my $me = shift;
590 86         220 my ($target, $sub_name, $is_method) = @_;
591            
592             exists &mro::get_linear_isa
593 0         0 or eval { require mro }
594 86 50 33     439 or do { require MRO::Compat };
  0         0  
595            
596 86         202 my $existing = do {
597 23     23   194 no strict 'refs';
  23         54  
  23         41803  
598 86         553 exists(&{"$target\::$sub_name"})
599 86 100       147 ? \&{"$target\::$sub_name"}
  38         173  
600             : undef;
601             };
602            
603 86 50       251 return if !defined $sub_name;
604            
605 86 100 100     566 if ($existing and $me->known_dispatcher($existing)) {
    100          
606 34         106 return $me; # already installed
607             }
608             elsif ($existing) {
609 4         39 require Carp;
610 4         1013 Carp::croak("Multimethod conflicts with monomethod $target\::$sub_name, bailing out");
611             }
612            
613 48 100 100     832 my $code = sprintf(
614             q{
615             package %s;
616             sub {
617             @_ = (%s, %s, %s, %d, [@_], wantarray);
618             goto $next;
619             }
620             },
621             $target, # package %s
622             B::perlstring($me), # $_[0]
623             B::perlstring($target), # $_[1]
624             ref($sub_name) # $_[2]
625             ? refaddr($sub_name)
626             : B::perlstring("$sub_name"),
627             $is_method || 0, # $_[3]
628             );
629            
630 48         125 my $coderef = do {
631 48         91 local $@;
632 48         471 my $next = $me->can('dispatch');
633 48 50   16   7384 eval $code or die $@;
  7         6040  
  7         32  
634             };
635            
636 48         287 $me->_install_coderef($target, $sub_name, $coderef);
637 48         390 $me->_mark_as_dispatcher($coderef);
638 48         293 return $coderef;
639             }
640              
641             sub dispatch {
642 149     149 0 13268 my $me = shift;
643 149         560 my ($pkg, $method_name, $is_method, $argv, $wantarray) = @_;
644 139 50       17643 $wantarray = wantarray if @_ < 5;
645            
646 139         361 my $search_from = $pkg;
647 136 100 100     14421 if ( $is_method and is_Object $argv->[0] ) {
    100 100        
648             # object method; reset package search from invocant class
649 91         297 $search_from = ref $argv->[0];
650             }
651             elsif ( $is_method and is_ClassName $argv->[0] ) {
652             # class method; reset package search from invocant class
653 17         5646 $search_from = $argv->[0];
654             }
655            
656             my ($winner, $new_argv) = $me->pick_candidate(
657             $CACHE{"$pkg/$search_from/$method_name/$is_method"} ||=
658             [ $me->get_all_multimethod_candidates($search_from, $method_name, $is_method) ],
659             $argv,
660             $wantarray ? LIST : defined($wantarray) ? SCALAR : VOID,
661 130 100 100     1406 ) or do {
    100          
    100          
662 15         8418 require Carp;
663 15         1530 Carp::croak('Multimethod could not find candidate to dispatch to, stopped');
664             };
665            
666 126 50       8720 if ( my $next = $winner->{code} ) {
    0          
667 126         463 @_ = @$new_argv;
668 117         762 goto $next;
669             }
670             elsif ( defined $winner->{die} ) {
671 0         0 require Carp;
672 0 0       0 Carp::croak( is_CodeRef( $winner->{die} ) ? $winner->{die}->() : $winner->{die} );
673             }
674             else {
675 0         0 return $winner->{return};
676             }
677             }
678              
679             # Optimization for simple signatures: those consisting of only non-coercing positional parameters.
680             my $smiple_keys = Enum[qw/ package subname method pos positional /];
681             sub _maybe_make_smiple {
682 162     178   575 my ( $me, $candidate ) = @_;
683 162 100       624 return if $candidate->{smiple};
684 158 100       394 return unless $smiple_keys->all( keys %{ $candidate->{signature_spec} } );
  158         1663  
685             my @types =
686 244 0       1072 map { is_Bool( $_ ) ? ( $_ ? Any : Optional[Any] ) : $_ }
    50          
687 152 50 33     15025 @{ $candidate->{signature_spec}{pos} or $candidate->{signature_spec}{positional} or [] };
  152         1309  
688 152 50       670 return unless TypeTiny->all( @types );
689 152 100       20676 if ( TypeTiny->check( $candidate->{signature_spec}{method} ) ) {
    50          
690 136         3327 unshift @types, $candidate->{signature_spec}{method};
691             }
692             elsif ( $candidate->{signature_spec}{method} ) {
693 0         0 unshift @types, Any;
694             }
695 152 100       646 return if grep { $_->has_coercion } @types;
  380         4833  
696 148         3817 $candidate->{smiple} = Tuple->of( @types )->compiled_check;
697             }
698              
699             sub pick_candidate {
700 123     136 1 404 my ( $me, $candidates, $argv, $wantarray ) = ( shift, @_ );
701            
702 123         216 my @remaining = @{ $candidates };
  123         438  
703            
704             # Compile signatures into something useful. (Cached.)
705             #
706            
707 123         326 for my $candidate (@remaining) {
708 754 100       463282 next if $candidate->{compiled};
709 166 100       1246 if ( is_CodeRef $candidate->{signature} ) {
710 4         19 $candidate->{compiled}{closure} = $candidate->{signature};
711 4         11 $candidate->{compiled}{min_args} = 0;
712 4         15 $candidate->{compiled}{max_args} = undef;
713             }
714             else {
715             $candidate->{compiled} = Type::Params::signature(
716 162         301 %{ $candidate->{signature_spec} },
  162         1304  
717             want_details => 1,
718             );
719 162         2266987 $me->_maybe_make_smiple( $candidate );
720             }
721             }
722            
723             # Weed out signatures that cannot match because of
724             # argument count.
725             #
726            
727 123         41592 my $argc = @$argv;
728            
729             @remaining =
730 735 100       1639 grep { $_->{if} ? &{$_->{if}} : 1 }
  3         11  
731 736 100 66 9   2041 grep { ($_->{want} and $wantarray) ? (!!any { $wantarray eq $_ } @{$_->{want}}) : 1 }
  2         13  
  2         13  
732             grep {
733 123         354 (defined $_->{compiled}{min_args} and $_->{compiled}{min_args} > $argc) ? 0 :
734 754 100 66     5441 (defined $_->{compiled}{max_args} and $_->{compiled}{max_args} < $argc) ? 0 : 1;
    100 100        
735             }
736             @remaining;
737            
738             # Weed out signatures that cannot match because
739             # they fail type checks, etc
740             #
741            
742 123         252 my %returns;
743            
744             @remaining = grep {
745 123 100       245 if ( my $smiple = $_->{smiple} ) {
  733         53843  
746 667 100 100     3607 !ref($smiple) || $smiple->($argv) ? ($returns{"$_"} = $argv) : ();
747             }
748             else {
749 66         144 eval {
750 66         273 $returns{"$_"} = [ $_->{compiled}{closure}->(@$argv) ];
751 30         581 1;
752             };
753             }
754             } @remaining;
755            
756             # Various techniques to cope with @remaining > 1...
757             #
758            
759 123 100       414 if (@remaining > 1) {
760 23     23   287 no warnings qw(uninitialized numeric);
  23         48  
  23         8020  
761             # Calculate signature constrainedness score. (Cached.)
762 58         117 my $max_score;
763 58         174 for my $candidate (@remaining) {
764 164         325 my $score = $candidate->{score};
765 164 100       428 if ( not defined $score ) {
766 74         315 my $slurpyAny = Slurpy[Any];
767 74         68643 $score = 0;
768             my @sig = map {
769 74 100       197 is_ArrayRef( $candidate->{signature_spec}{$_} ) ? @{ $candidate->{signature_spec}{$_} } : ();
  222         1246  
  70         240  
770             } qw(positional pos named);
771 74         214 foreach my $type ( @sig ) {
772 100 50       484 next unless is_Object $type;
773 100 100       424 next if $type == $slurpyAny;
774 96         137312 my @real_parents = grep !$_->_is_null_constraint, $type, $type->parents;
775 96         7349 $score += @real_parents;
776             }
777 74 100 100     838 $score += 100_000 if $candidate->{want} || $candidate->{if};
778 74         395 $candidate->{score} = $score;
779             };
780 164         5103 $max_score = max( grep defined, $score, $max_score );
781             }
782             # Only keep those with (equal) highest score
783 58         145 @remaining = grep { $_->{score} == $max_score } @remaining;
  164         469  
784             }
785            
786 123 100       420 if (@remaining > 1) {
787             # Only keep those from the most derived class
788 23     23   223 no warnings qw(uninitialized numeric);
  23         54  
  23         2635  
789 20         129 my $max_score = max( map $_->{height}, @remaining );
790 20         51 @remaining = grep { $_->{height} == $max_score } @remaining;
  58         127  
791             }
792            
793 123 100       432 if (@remaining > 1) {
794             # Only keep those from the most non-role-like packages
795 23     23   162 no warnings qw(uninitialized numeric);
  23         70  
  23         2541  
796 10         60 my $min_score = min( map $_->{copied}, @remaining );
797 10         25 @remaining = grep { $_->{copied} == $min_score } @remaining;
  38         79  
798             }
799            
800 123 100       340 if (@remaining > 1) {
801             # Argh! Still got multiple candidates! Just choose whichever
802             # was declared first...
803 23     23   176 no warnings qw(uninitialized numeric);
  23         64  
  23         11009  
804 8         36 my $min_score = min( map $_->{declaration_order}, @remaining );
805 8         19 @remaining = grep { $_->{declaration_order} == $min_score } @remaining;
  34         60  
806             }
807            
808 123 50       435 wantarray or die 'MUST BE CALLED IN LIST CONTEXT';
809            
810 123 100       344 return unless @remaining;
811 117         1072 return ( $remaining[0], $returns{''.$remaining[0]} );
812             }
813              
814             1;
815              
816             __END__
817              
818             =pod
819              
820             =encoding utf-8
821              
822             =head1 NAME
823              
824             Sub::MultiMethod - yet another implementation of multimethods
825              
826             =head1 SYNOPSIS
827              
828             How to generate JSON (albeit with very naive string quoting) using
829             multimethods:
830              
831             use v5.20;
832             use strict;
833             use warnings;
834             use experimental 'signatures';
835            
836             package My::JSON {
837             use Moo;
838             use Sub::MultiMethod qw(multimethod);
839             use Types::Standard -types;
840            
841             multimethod stringify => (
842             positional => [ Undef ],
843             code => sub ( $self, $undef ) {
844             return 'null';
845             },
846             );
847            
848             multimethod stringify => (
849             positional => [ ScalarRef[Bool] ],
850             code => sub ( $self, $bool ) {
851             return $$bool ? 'true' : 'false';
852             },
853             );
854            
855             multimethod stringify => (
856             alias => "stringify_str",
857             positional => [ Str ],
858             code => sub ( $self, $str ) {
859             return sprintf( q<"%s">, quotemeta($str) );
860             },
861             );
862            
863             multimethod stringify => (
864             positional => [ Num ],
865             code => sub ( $self, $n ) {
866             return $n;
867             },
868             );
869            
870             multimethod stringify => (
871             positional => [ ArrayRef ],
872             code => sub ( $self, $arr ) {
873             return sprintf(
874             q<[%s]>,
875             join( q<,>, map( $self->stringify($_), @$arr ) )
876             );
877             },
878             );
879            
880             multimethod stringify => (
881             positional => [ HashRef ],
882             code => sub ( $self, $hash ) {
883             return sprintf(
884             q<{%s}>,
885             join(
886             q<,>,
887             map sprintf(
888             q<%s:%s>,
889             $self->stringify_str($_),
890             $self->stringify( $hash->{$_} )
891             ), sort keys %$hash,
892             )
893             );
894             },
895             );
896             }
897            
898             my $json = My::JSON->new;
899            
900             say $json->stringify( {
901             foo => 123,
902             bar => [ 1, 2, 3 ],
903             baz => \1,
904             quux => { xyzzy => 666 },
905             } );
906              
907             While this example requires Perl 5.20+, Sub::MultiMethod is tested and works
908             on Perl 5.8.1 and above.
909              
910             =head1 DESCRIPTION
911              
912             Sub::MultiMethod focusses on implementing the dispatching of multimethods
913             well and is less concerned with providing a nice syntax for setting them
914             up. That said, the syntax provided is inspired by Moose's C<has> keyword
915             and hopefully not entirely horrible.
916              
917             =head2 Functions
918              
919             Sub::MultiMethod exports nothing by default. You can import the functions
920             you want by listing them in the C<use> statement:
921              
922             use Sub::MultiMethod "multimethod";
923              
924             You can rename functions:
925              
926             use Sub::MultiMethod "multimethod" => { -as => "mm" };
927              
928             You can import everything using C<< -all >>:
929              
930             use Sub::MultiMethod -all;
931              
932             Sub::MultiMethod also offers an API for setting up multimethods for a
933             class, in which case, you don't need to import anything.
934              
935             =head3 C<< multimethod $name => %spec >>
936              
937             The specification supports the same options as L<Type::Params> v2
938             to specify a signature for the method, plus a few Sub::MultiMethod-specific
939             options. Any options not included in the list below are passed through to
940             Type::Params. (The options C<goto_next>, C<on_die>, C<message>, and
941             C<want_*> are not supported.)
942              
943             =over
944              
945             =item C<< code >> I<< (CodeRef) >>
946              
947             Conceptually required, but see the C<return> and C<die> shortcuts.
948              
949             The sub to dispatch to. It will receive parameters in C<< @_ >> as you
950             would expect, but these parameters have been passed through the signature
951             already, so will have had defaults and coercions applied.
952              
953             An example for positional parameters:
954              
955             code => sub ( $self, $prefix, $match, $output ) {
956             print { $output } $prefix;
957             ...;
958             },
959              
960             An example for named parameters:
961              
962             code => sub ( $self, $arg ) {
963             print { $arg->output } $arg->prefix;
964             ...;
965             },
966              
967             Note that C<< $arg >> is an object with methods for each named parameter.
968              
969             Corresponding examples for older versions of Perl without signature support.
970              
971             code => sub {
972             my ( $self, $prefix, $match, $output ) = @_;
973             print { $output } $prefix;
974             ...;
975             },
976              
977             And:
978              
979             code => sub {
980             my ( $self, $arg ) = @_;
981             print { $arg->output } $arg->prefix;
982             ...;
983             },
984              
985             =item C<< return >> I<< (Value) >>
986              
987             Shortcut.
988              
989             You can use C<< return => "foo" >> as a shortcut for
990             C<< code => sub { return "foo" } >>. This cannot be used
991             to return refereneces.
992              
993             =item C<< die >> I<< (CodeRef|Str) >>
994              
995             Shortcut.
996              
997             You can use C<< die => "foo" >> as a shortcut for
998             C<< code => sub { require Carp; Carp::croak("foo") } >>.
999              
1000             You can use C<< die => \&foo >> as a shortcut for
1001             C<< code => sub { require Carp; Carp::croak(foo()) } >>.
1002              
1003             =item C<< signature >> I<< (CodeRef) >>
1004              
1005             Optional.
1006              
1007             If C<signature> is set, then Sub::MultiMethod won't use L<Type::Params>
1008             to build a signature for this multimethod candidate. It will treat the
1009             coderef as an already-built signature.
1010              
1011             A coderef signature is expected to take C<< @_ >>, throw an exception if
1012             the arguments cannot be handled, and return C<< @_ >> (possibly after some
1013             manipulation).
1014              
1015             =item C<< alias >> I<< (Str|ArrayRef[Str]) >>
1016              
1017             Optional.
1018              
1019             Installs an alias for the candidate, bypassing multimethod dispatch. (But not
1020             bypassing the checks, coercions, and defaults in the signature!)
1021              
1022             =item C<< method >> I<< (Bool) >>
1023              
1024             Optional, defaults to 1.
1025              
1026             Indicates whether the multimethod should be treated as a method (i.e. with an
1027             implied C<< $self >>). Defaults to true, but C<< method => 0 >> can be
1028             given if you want multifuncs with no invocant.
1029              
1030             Multisubs where some candidates are methods and others are non-methods are
1031             not currently supported! (And probably never will be.)
1032              
1033             =item C<< want >> I<< (Str|ArrayRef) >>
1034              
1035             Optional.
1036              
1037             Allows you to specify that a candidate only applies in certain contexts.
1038             The context may be "VOID", "SCALAR", or "LIST". May alternatively be an
1039             arrayref of contexts. "NONVOID" is a shortcut for C<< ["SCALAR","LIST"] >>.
1040             "NONLIST" and "NONSCALAR" are also allowed.
1041              
1042             =item C<< if >> I<< (CodeRef) >>
1043              
1044             Optional.
1045              
1046             Allows you to specify that a candidate only applies in certain conditions.
1047              
1048             if => sub { $ENV{OSTYPE} eq 'linux' },
1049              
1050             The coderef is called with no parameters. It has no access to the multimethod's
1051             C<< @_ >>.
1052              
1053             =item C<< score >> I<< (Int) >>
1054              
1055             Optional.
1056              
1057             Overrides the constrainedness score calculated as described in the dispatch
1058             technique. Most scores calculated that way will typically between 0 and 100.
1059             Setting a score manually to something very high (e.g. 9999) will pretty much
1060             guarantee that it gets chosen over other candidates when multiple signatures
1061             match. Setting it to something low (e.g. -1) will mean it gets avoided.
1062              
1063             =item C<< no_dispatcher >> I<< (Bool) >>
1064              
1065             Optional. Defaults to true in roles, false otherwise.
1066              
1067             If set to true, Sub::MultiMethods will register the candidate method
1068             but won't install a dispatcher. You should mostly not worry about this
1069             and accept the default.
1070              
1071             =back
1072              
1073             The C<< @_ >> passed to Sub::MultiMethod is pre-processed slightly
1074             after C<< $name >> has been shifted off but before being interpreted as
1075             the C<< %spec >> hash. Obviously hashes are expected to have string keys,
1076             so if the first argument of C<< @_ >> is an arrayref or hashref, those
1077             are interpreted as a positional or named signature respectively.
1078              
1079             So the following are equivalent:
1080              
1081             multimethod foo => [...] => %spec;
1082             multimethod foo => ( positional => [...], %spec );
1083              
1084             And so are the following (note that the hashref becomes an arrayref):
1085              
1086             multimethod foo => {...} => ( %spec );
1087             multimethod foo => ( named => [...], %spec );
1088              
1089             After this, if C<< @_ >> is an odd-sized list with a coderef in the last
1090             position, the coderef is treated as the C<code> option.
1091              
1092             So the following are equivalent:
1093              
1094             multimethod foo => ( %spec ) => sub { ... };
1095             multimethod foo => ( %spec, code => sub { ... } );
1096              
1097             For the common case of:
1098              
1099             multimethod foo => (
1100             positional => [...],
1101             code => sub {
1102             ...;
1103             },
1104             );
1105              
1106             These combination of shortcuts allow it to be written as:
1107              
1108             multimethod foo => [...] => sub {
1109             ...;
1110             };
1111              
1112             =head3 C<< monomethod $name => %spec >>
1113              
1114             C<< monomethod($name, %spec) >> is basically just a shortcut for
1115             C<< multimethod(undef, alias => $name, %spec) >> though with error
1116             messages which don't mention it being an alias.
1117              
1118             =head3 C<< multifunction $name => %spec >>
1119              
1120             Like C<multimethod> but defaults to C<< method => 0 >>.
1121              
1122             =head3 C<< monofunction $name => %spec >>
1123              
1124             Like C<monomethod> but defaults to C<< method => 0 >>.
1125              
1126             =head3 C<< VOID >>, C<< SCALAR >>, C<< LIST >>, C<< NONVOID >>, C<< NONSCALAR >>, C<< NONLIST >>
1127              
1128             Useful constants you can export to allow this to work:
1129              
1130             want => NONVOID,
1131              
1132             =head2 Dispatch Technique
1133              
1134             When a multimethod is called, a list of packages to inspect for candidates
1135             is obtained by crawling C<< @ISA >>. (For multifuncs, C<< @ISA >> is ignored.)
1136              
1137             All candidates for the invoking class and all parent classes are considered.
1138              
1139             If any parent class includes a mono-method (i.e. not a multimethod) of the
1140             same name as this multimethod, then it is considered to have override any
1141             candidates further along the C<< @ISA >> chain. (With multiple inheritance,
1142             this could get confusing though!) Those further candidates will not be
1143             considered, however the mono-method will be considered to be a candidate,
1144             albeit one with a very low score. (See scoring later.)
1145              
1146             Any candidates where it is clear they will not match based on parameter
1147             count will be discarded immediately.
1148              
1149             After that, the signatures of each are tried. If they throw an error, that
1150             candidate will be discarded.
1151              
1152             If there are still multiple possible candidates, they will be sorted based
1153             on how constrained they are.
1154              
1155             To determine how constrained they are, every type constraint in their
1156             signature is assigned a score. B<Any> is 0. B<Defined> inherits from
1157             B<Any>, so has score 1. B<Value> inherits from B<Defined>, so has score 2.
1158             Etc. Some types inherit from a parent but without further constraining
1159             the parent. (For example, B<Item> inherits from B<Any> but doesn't place
1160             any additional constraints on values.) In these cases, the child type
1161             has the same score as its parent. All these scores are added together
1162             to get a single score for the candidate. For candidates where the
1163             signature is a coderef, this is essentially a zero score for the
1164             signature unless a score was specified explicitly.
1165              
1166             The score has 100,000 added if C<want> or C<if> was specified.
1167              
1168             If multiple candidates are equally constrained, child class candidates
1169             beat parent class candidates; class candidates beat role candidates;
1170             and the candidate that was declared earlier wins.
1171              
1172             Method-resolution order (DFS/C3) is respected, though in Perl 5.8 under
1173             very contrived conditions (calling a sub as a function when it was
1174             defined as a method, but not passing a valid invocant as the first
1175             parameter), MRO may not always work correctly.
1176              
1177             Note that invocants are not part of the signature, so not taken into
1178             account when calculating scores, but because child class candidates
1179             beat parent class candidates, they should mostly behave as expected.
1180              
1181             After this, there should be one preferred candidate or none. If there is
1182             none, an error occurs. If there is one, that candidate is dispatched to
1183             using C<goto> so there is no trace of Sub::MultiMethod in C<caller>. It
1184             gets passed the result from checking the signature earlier as C<< @_ >>.
1185              
1186             =head3 Roles
1187              
1188             As far as I'm aware, Sub::MultiMethod is the only multimethod implementation
1189             that allows multimethods imported from roles to integrate into a class.
1190              
1191             use v5.12;
1192             use strict;
1193             use warnings;
1194            
1195             package My::RoleA {
1196             use Moo::Role;
1197             use Sub::MultiMethod qw(multimethod);
1198             use Types::Standard -types;
1199            
1200             multimethod foo => (
1201             positional => [ HashRef ],
1202             code => sub { return "A" },
1203             alias => "foo_a",
1204             );
1205             }
1206            
1207             package My::RoleB {
1208             use Moo::Role;
1209             use Sub::MultiMethod qw(multimethod);
1210             use Types::Standard -types;
1211            
1212             multimethod foo => (
1213             positional => [ ArrayRef ],
1214             code => sub { return "B" },
1215             );
1216             }
1217            
1218             package My::Class {
1219             use Moo;
1220             use Sub::MultiMethod qw(multimethod);
1221             use Types::Standard -types;
1222            
1223             with qw( My::RoleA My::RoleB );
1224            
1225             multimethod foo => (
1226             positional => [ HashRef ],
1227             code => sub { return "C" },
1228             );
1229             }
1230            
1231             my $obj = My::Class->new;
1232            
1233             say $obj->foo_a( {} ); # A (alias defined in RoleA)
1234             say $obj->foo( [] ); # B (candidate from RoleB)
1235             say $obj->foo( {} ); # C (Class overrides candidate from RoleA)
1236              
1237             All other things being equal, candidates defined in classes should
1238             beat candidates imported from roles.
1239              
1240             =head2 CodeRef multimethods
1241              
1242             The C<< $name >> of a multimethod may be a scalarref, in which case
1243             C<multimethod> will install the multimethod as a coderef into the
1244             scalar referred to. Example:
1245              
1246             my ($coderef, $otherref);
1247            
1248             multimethod \$coderef => (
1249             method => 0,
1250             positional => [ ArrayRef ],
1251             code => sub { say "It's an arrayref!" },
1252             );
1253            
1254             multimethod \$coderef => (
1255             method => 0,
1256             alias => \$otherref,
1257             positional => [ HashRef ],
1258             code => sub { say "It's a hashref!" },
1259             );
1260            
1261             $coderef->( [] );
1262             $coderef->( {} );
1263            
1264             $otherref->( {} );
1265              
1266             The C<< $coderef >> and C<< $otherref >> variables will actually end up
1267             as blessed coderefs so that some tidy ups can take place in C<DESTROY>.
1268              
1269             =head2 Exporter
1270              
1271             Sub::MultiMethod uses L<Exporter::Tiny> as an exporter, which means
1272             exported functions can be renamed, etc.
1273              
1274             use Sub::MultiMethod multimethod => { -as => 'mm' };
1275              
1276             You can import everything using C<< -all >>:
1277              
1278             use Sub::MultiMethod -all;
1279              
1280             If your Perl version is recent enough, you can import everything as lexical
1281             keywords:
1282              
1283             use Sub::MultiMethod -lexical, -all;
1284              
1285             You may also set various defaults in the import:
1286              
1287             use Sub::MultiMethod multimethod => {
1288             -as => 'mm',
1289             defaults => { bless => 0 }, # see Type::Params
1290             };
1291              
1292             =head2 API
1293              
1294             Sub::MultiMethod avoids cute syntax hacks because those can be added by
1295             third party modules. It provides an API for these modules.
1296              
1297             Brief note on terminology: when you define multimethods in a class,
1298             each possible signature+coderef is a "candidate". The method which
1299             makes the decision about which candidate to call is the "dispatcher".
1300             Roles will typically have candidates but no dispatcher. Classes will
1301             need dispatchers setting up for each multimethod.
1302              
1303             =over
1304              
1305             =item C<< Sub::MultiMethod->install_candidate($target, $sub_name, %spec) >>
1306              
1307             C<< $target >> is the class (package) name being installed into.
1308              
1309             C<< $sub_name >> is the name of the method.
1310              
1311             C<< %spec >> is the multimethod spec. If C<< $target >> is a role, you
1312             probably want to include C<< no_dispatcher => 1 >> as part of the spec.
1313              
1314             =item C<< Sub::MultiMethod->install_dispatcher($target, $sub_name, $is_method) >>
1315              
1316             C<< $target >> is the class (package) name being installed into.
1317              
1318             C<< $sub_name >> is the name of the method.
1319              
1320             C<< $is_method >> is an integer/boolean.
1321              
1322             This rarely needs to be manually called as C<install_candidate> will do it
1323             automatically.
1324              
1325             =item C<< Sub::MultiMethod->install_monomethod($target, $sub_name, %spec) >>
1326              
1327             Installs a regular (non-multimethod) method into the target.
1328              
1329             =item C<< Sub::MultiMethod->copy_package_candidates(@sources => $target) >>
1330              
1331             C<< @sources >> is the list of packages to copy candidates from.
1332              
1333             C<< $target >> is the class (package) name being installed into.
1334              
1335             Sub::MultiMethod will use L<Role::Hooks> to automatically copy candidates
1336             from roles to consuming classes if your role implementation is supported.
1337             (Supported implementations include Role::Tiny, Role::Basic, Moo::Role,
1338             Moose::Role, and Mouse::Role, plus any role implementations that extend
1339             those. If your role implementation is something else, then when you consume
1340             a role into a class you may need to copy the candidates from the role to
1341             the class.)
1342              
1343             =item C<< Sub::MultiMethod->install_missing_dispatchers($target) >>
1344              
1345             Should usually be called after C<copy_package_candidates>, unless
1346             C<< $target >> is a role.
1347              
1348             Again, this is unnecessary if your role implementation is supported
1349             by Role::Hooks.
1350              
1351             =item C<< Sub::MultiMethod->get_multimethods($target) >>
1352              
1353             Returns the names of all multimethods declared for a class or role,
1354             not including any parent classes.
1355              
1356             =item C<< Sub::MultiMethod->has_multimethod_candidates($target, $method_name) >>
1357              
1358             Indicates whether the class or role has any candidates for a multimethod.
1359             Does not include parent classes.
1360              
1361             =item C<< Sub::MultiMethod->get_multimethod_candidates($target, $method_name) >>
1362              
1363             Returns a list of candidate spec hashrefs for the method, not including
1364             candidates from parent classes.
1365              
1366             =item C<< Sub::MultiMethod->get_all_multimethod_candidates($target, $method_name, $is_method) >>
1367              
1368             Returns a list of candidate spec hashrefs for the method, including candidates
1369             from parent classes (unless C<< $is_method >> is false, because non-methods
1370             shouldn't be inherited).
1371              
1372             =item C<< Sub::MultiMethod->known_dispatcher($coderef) >>
1373              
1374             Returns a boolean indicating whether the coderef is known to be a multimethod
1375             dispatcher.
1376              
1377             =item C<< Sub::MultiMethod->pick_candidate(\@candidates, \@args, $wantarray) >>
1378              
1379             Returns a list of two items: first the winning candidate from an array of specs,
1380             given the args and invocants, and second the modified args after coercion has
1381             been applied. C<< $wantarray >> should be a string 'VOID', 'SCALAR', or 'LIST'.
1382              
1383             This is basically how the dispatcher for a method works:
1384              
1385             my $pkg = __PACKAGE__;
1386             if ( $ismethod ) {
1387             $pkg = Scalar::Util::blessed( $_[0] ) || $_[0];
1388             }
1389            
1390             my ( $winner, $new_args ) = 'Sub::MultiMethod'->pick_candidate(
1391             [
1392             'Sub::MultiMethod'->get_all_multimethod_candidates(
1393             $pkg,
1394             $sub,
1395             $ismethod,
1396             )
1397             ],
1398             \@_,
1399             wantarray ? 'LIST' : defined(wantarray) ? 'SCALAR' : 'VOID',
1400             );
1401            
1402             $winner->{code}->( @$new_args );
1403              
1404             =item C<< Sub::MultiMethod->clear_cache >>
1405              
1406             The C<dispatch> method caches what C<get_all_multimethod_candidates> returns.
1407             It is expected that by the time a multisub/multimethod is called, you have
1408             finished adding new candidates, so this should not be harmful. If you do add
1409             new candidates, then the cache should automatically clear itself anyway.
1410             However if new candidates emerge by, for example, altering a class's
1411             C<< @ISA >> at run time, you may need to manually clear the cache. This is
1412             a very unlikely situation though.
1413              
1414             =item C<< Sub::MultiMethod->get_cache >>
1415              
1416             Gets a reference to the dispatch cache hash. Mostly for people wanting to
1417             subclass Sub::MultiMethod, especially if you want to override the C<dispatch>
1418             method.
1419              
1420             =back
1421              
1422             =head1 EXAMPLES
1423              
1424             =head2 Naive (Slightly Broken) JSON Writer
1425              
1426             Here is similar code to the L</SYNOPSIS>, but written as a function
1427             instead of a method, employing a few shortcuts, and with a variant
1428             that throws an error if called in void context.
1429              
1430             use v5.20;
1431             use strict;
1432             use warnings;
1433             use experimental 'signatures';
1434            
1435             package My::JSON {
1436             use Sub::MultiMethod multifunction => { -as => 'multi' };
1437             use Types::Standard -types;
1438            
1439             multi stringify => ( want => 'VOID', die => 'Unexpected void context' );
1440            
1441             multi stringify => [ Undef ] => ( return => 'null' );
1442            
1443             multi stringify => [ ScalarRef[Bool] ] => sub ( $bool ) {
1444             return $$bool ? 'true' : 'false';
1445             };
1446            
1447             multi stringify => [ Str ] => (
1448             alias => "stringify_str",
1449             code => sub ( $str ) {
1450             return sprintf( q<"%s">, quotemeta($str) );
1451             },
1452             );
1453            
1454             multi stringify => [ Num ] => sub ( $n ) {
1455             return $n;
1456             };
1457            
1458             multi stringify => [ ArrayRef ] => sub ( $arr ) {
1459             return sprintf(
1460             q<[%s]>,
1461             join( q<,>, map( stringify($_), @$arr ) )
1462             );
1463             };
1464            
1465             multi stringify => [ HashRef ] => sub ( $hash ) {
1466             return sprintf(
1467             q<{%s}>,
1468             join(
1469             q<,>,
1470             map sprintf(
1471             q<%s:%s>,
1472             stringify_str($_),
1473             stringify( $hash->{$_} )
1474             ), sort keys %$hash,
1475             )
1476             );
1477             };
1478             }
1479            
1480             say My::JSON::stringify( {
1481             foo => 123,
1482             bar => [ 1, 2, 3 ],
1483             baz => \1,
1484             quux => { xyzzy => 666 },
1485             } );
1486              
1487             =head1 BUGS
1488              
1489             Please report any bugs to
1490             L<http://rt.cpan.org/Dist/Display.html?Queue=Sub-MultiMethod>.
1491              
1492             =head1 SEE ALSO
1493              
1494             L<Multi::Dispatch> - probably almost as nice an implementation as
1495             Sub::MultiMethod. It correctly handles inheritance, does a good job of
1496             dispatching to the best candidate, etc. It's even significantly faster than
1497             Sub::MultiMethod. On the downsides, it doesn't handle roles or coercions.
1498              
1499             L<Class::Multimethods> - uses Perl classes and ref types to dispatch.
1500             No syntax hacks but the fairly nice syntax shown in the pod relies on
1501             C<use strict> being switched off! Need to quote a few more things otherwise.
1502              
1503             L<Class::Multimethods::Pure> - similar to Class::Multimethods but with
1504             a more complex type system and a more complex dispatch method.
1505              
1506             L<Logic> - a full declarative programming framework. Overkill if all
1507             you want is multimethods. Uses source filters.
1508              
1509             L<Dios> - object oriented programming framework including multimethods.
1510             Includes a full type system and Keyword::Declare-based syntax. Pretty
1511             sensible dispatch technique which is almost identical to
1512             Sub::MultiMethod. Much much slower though, at both compile time and
1513             runtime.
1514              
1515             L<MooseX::MultiMethods> - uses Moose type system and Devel::Declare-based
1516             syntax. Not entirely sure what the dispatching method is.
1517              
1518             L<Kavorka> - I wrote this, so I'm allowed to be critical. Type::Tiny-based
1519             type system. Very naive dispatching; just dispatches to the first declared
1520             candidate that can handle it rather than trying to find the "best".
1521              
1522             L<Sub::Multi::Tiny> - uses Perl attributes to declare candidates to
1523             be dispatched to. Pluggable dispatching, but by default uses argument
1524             count.
1525              
1526             L<Sub::Multi> - syntax wrapper around Class::Multimethods::Pure?
1527              
1528             L<Sub::SmartMatch> - kind of abandoned and smartmatch is generally seen
1529             as teh evilz these days.
1530              
1531             =head1 AUTHOR
1532              
1533             Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
1534              
1535             =head1 COPYRIGHT AND LICENCE
1536              
1537             This software is copyright (c) 2020-2022 by Toby Inkster.
1538              
1539             This is free software; you can redistribute it and/or modify it under
1540             the same terms as the Perl 5 programming language system itself.
1541              
1542             =head1 DISCLAIMER OF WARRANTIES
1543              
1544             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
1545             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1546             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1547