File Coverage

blib/lib/Class/Multimethods/Pure.pm
Criterion Covered Total %
statement 406 456 89.0
branch 93 114 81.5
condition 30 58 51.7
subroutine 98 117 83.7
pod 0 8 0.0
total 627 753 83.2


line stmt bran cond sub pod time code
1             package Class::Multimethods::Pure;
2              
3 21     21   659160 use 5.006001;
  21         82  
  21         1093  
4 21     21   210 use strict;
  21         61  
  21         790  
5 21     21   140 use warnings;
  21         47  
  21         719  
6 21     21   120 no warnings 'uninitialized';
  21         39  
  21         1289  
7              
8 21     21   123 use Carp;
  21         42  
  21         4128  
9              
10             our $VERSION = '0.13';
11              
12             our %MULTI;
13             our %MULTIPARAM;
14              
15             our $REGISTRY;
16             $REGISTRY = {
17             multi => \%MULTI,
18             multiparam => \%MULTIPARAM,
19             install_wrapper => sub {
20             my ($pkg, $name) = @_;
21 21     21   115 no strict 'refs';
  21         34  
  21         593  
22 21     21   125 no warnings 'redefine';
  21         35  
  21         18657  
23             *{"$pkg\::$name"} = make_wrapper($name, $REGISTRY);
24             },
25             };
26              
27             our $DEFAULT_CORE = 'Class::Multimethods::Pure::Method::Slow';
28              
29             {
30             # This env check is mostly for testing. No, correction, it's only for
31             # testing. Don't use it.
32             if (my $core = $ENV{CMMP_DEFAULT_MULTI_CORE}) {
33             $DEFAULT_CORE = $core;
34             }
35             }
36              
37             sub process_multi {
38 87     87 0 306 my $registry = shift; # multi, multiparam, and install_wrapper
39 87 50       277 my $name = shift or return;
40            
41 87 50       280 if (@_) {
42 87         121 my @params;
43 87   66     594 until (!@_ || ref $_[0] eq 'CODE') {
44 99 50       458 if ($_[0] =~ /^-/) {
45 0         0 my ($k, $v) = splice @_, 0, 2;
46 0         0 $k =~ s/^-//;
47              
48 0         0 $registry->{multiparam}{$name}{$k} = $v;
49             }
50             else {
51 99         293 my $type = shift;
52 99 100       247 unless (ref $type) {
53 63 100       301 if (Class::Multimethods::Pure::Type::Unblessed->is_unblessed($type)) {
54 21         67 $type = Class::Multimethods::Pure::Type::Unblessed->new($type);
55             }
56             else {
57 42         159 $type = Class::Multimethods::Pure::Type::Package->new($type);
58             }
59             }
60 99         584 push @params, $type;
61             }
62             }
63            
64 87 50       232 return () unless @_;
65            
66 87         124 my $code = shift;
67              
68 87   66     669 my $multi = $registry->{multi}{$name} ||=
69             Class::Multimethods::Pure::Method->new(
70             Core => $registry->{multiparam}{$name}{Core},
71             Variant => $registry->{multiparam}{$name}{Variant},
72             );
73            
74 87         303 $multi->add_variant(\@params, $code);
75             }
76              
77 87         209 my $pkg = caller 1;
78 87         242 $registry->{install_wrapper}->($pkg, $name);
79            
80 87         13439 @_;
81             }
82              
83             sub make_wrapper {
84 87     87 0 230 my ($name, $registry) = @_;
85 87         230 my $method = \$registry->{multi}{$name};
86             sub {
87 135     135   52225 my $call = $$method->can('call');
88 135         334 unshift @_, $$method;
89 135         490 goto &$call;
90 87         470 };
91             }
92              
93             # exports a multimethod with a given name and arguments
94             sub multi {
95 84 50   84 0 18745 if (process_multi($REGISTRY, @_)) {
96 0         0 croak "Usage: multi name => (Arg1, Arg2, ...) => sub { code };";
97             }
98             }
99              
100             our @exports = qw;
101              
102             sub import {
103 27     27   2219 my $class = shift;
104 27         56 my $cmd = shift;
105            
106 27         127 my $pkg = caller;
107              
108 27 100       238 if ($cmd eq 'multi') {
    100          
    50          
109 3         17 while (@_ = process_multi($REGISTRY, @_)) { }
110             }
111             elsif ($cmd eq 'import') {
112 3         10 for my $export (@_) {
113 6 50       12 unless (grep { $_ eq $export } @exports) {
  36         75  
114 0         0 croak "$export is not exported from " . __PACKAGE__;
115             }
116            
117 21     21   136 no strict 'refs';
  21         44  
  21         2701  
118 6         10 *{"$pkg\::$export"} = \&{__PACKAGE__ . "::$export"};
  6         317  
  6         23  
119             }
120             }
121             elsif (!defined $cmd) {
122 21         64 for my $export (@exports) {
123 21     21   114 no strict 'refs';
  21         39  
  21         6886  
124 126         155 *{"$pkg\::$export"} = \&{__PACKAGE__ . "::$export"};
  126         1571  
  126         414  
125             }
126             }
127             else {
128 0         0 croak "Unknown command: $cmd";
129             }
130             }
131              
132             sub all(@) {
133 0     0 0 0 Class::Multimethods::Pure::Type::Conjunction->new(
134             Class::Multimethods::Pure::Type->promote(@_)
135             );
136             }
137              
138             sub any(@) {
139 3     3 0 38 Class::Multimethods::Pure::Type::Disjunction->new(
140             Class::Multimethods::Pure::Type->promote(@_)
141             );
142             }
143              
144             sub none(@) {
145 0     0 0 0 Class::Multimethods::Pure::Type::Injunction->new(
146             Class::Multimethods::Pure::Type->promote(@_)
147             );
148             }
149              
150             sub Any() {
151 27     27 0 1688 Class::Multimethods::Pure::Type::Any->new;
152             }
153              
154             sub subtype($$) {
155 21     21 0 132 Class::Multimethods::Pure::Type::Subtype->new(
156             Class::Multimethods::Pure::Type->promote($_[0]), $_[1]
157             );
158             }
159              
160             package Class::Multimethods::Pure::Type;
161              
162 21     21   316 use Carp;
  21         40  
  21         1484  
163 21     21   118 use Scalar::Util qw;
  21         33  
  21         28483  
164              
165             # The promote multimethod is where the logic is to turn the string "Foo::Bar"
166             # into a Type::Package object.
167             our $PROMOTE = Class::Multimethods::Pure::Method->new;
168              
169             sub promote {
170 24     24   95 my ($class, @types) = @_;
171 24         40 map { $PROMOTE->call($_) } @types;
  27         102  
172             }
173              
174             {
175             # I put each subtype into a variable so that you can extend the subtypes easily.
176            
177             my $pkg = sub { "Class::Multimethods::Pure::Type::$_[0]"->new(@_[1..$#_]) };
178              
179             # Anything that is blessed is probably already a Type object
180             our $PROMOTE_BLESSED = $pkg->('Subtype', $pkg->('Any'), sub { blessed $_[0] });
181             $PROMOTE->add_variant([ $PROMOTE_BLESSED ] => sub { $_[0] });
182            
183             # ARRAY, HASH, etc. get an Unblessed type for unblessed references.
184             our $PROMOTE_UNBLESSED = $pkg->('Subtype', $pkg->('Any'),
185             sub { Class::Multimethods::Pure::Type::Unblessed->is_unblessed($_[0]) });
186             $PROMOTE->add_variant(
187             [ $PROMOTE_UNBLESSED ] => sub {
188             Class::Multimethods::Pure::Type::Unblessed->new($_[0])
189             });
190              
191             # Anything else gets turned into a package.
192             $PROMOTE->add_variant(
193             [ $pkg->('Any') ] => sub {
194             Class::Multimethods::Pure::Type::Package->new($_[0])
195             });
196             }
197              
198             # The subset multimethod is the most important multi used in the core. It
199             # determines whether the left class is a subset of the right class.
200             our $SUBSET = Class::Multimethods::Pure::Method::DumbCache->new;
201              
202             sub subset {
203 4469     4469   5392 my ($self, $other) = @_;
204 4469         8730 $SUBSET->call($self, $other);
205             }
206              
207             sub equal {
208 0     0   0 my ($self, $other) = @_;
209 0 0       0 subset($self, $other) && subset($other, $self);
210             }
211              
212             sub matches;
213             sub string;
214              
215             # returns whether this type depends on anything other than the package
216 0     0   0 sub ref_cacheable { 0 }
217             # returns whether this type *could possibly* match an object in this package
218             # (keep in mind that you could implement this even if ref_cacheable is false)
219 0     0   0 sub ref_match { 1 }
220              
221             {
222             my $pkg = sub { Class::Multimethods::Pure::Type::Package->new(
223             'Class::Multimethods::Pure::' . $_[0]) };
224              
225             $SUBSET->add_variant(
226             [ $pkg->('Type'), $pkg->('Type') ] => sub {
227             my ($a, $b) = @_;
228             $a == $b;
229             });
230            
231             # If you change this, remember to change Type::Package::subset
232             # which is used in the bootstrap.
233             $SUBSET->add_variant(
234             [ $pkg->('Type::Package'), $pkg->('Type::Package') ] => sub {
235             my ($a, $b) = @_;
236             $a->name->isa($b->name);
237             });
238            
239             $SUBSET->add_variant(
240             [ $pkg->('Type::Unblessed'), $pkg->('Type::Unblessed') ] => sub {
241             my ($a, $b) = @_;
242             $a->name eq $b->name;
243             });
244              
245             $SUBSET->add_variant(
246             [ $pkg->('Type::Any'), $pkg->('Type::Normal') ] => sub { 0 });
247              
248             $SUBSET->add_variant(
249             [ $pkg->('Type::Normal'), $pkg->('Type::Any') ] => sub { 1 });
250              
251             $SUBSET->add_variant(
252             [ $pkg->('Type::Any'), $pkg->('Type::Any') ] => sub { 1 });
253              
254             $SUBSET->add_variant(
255             [ $pkg->('Type::Subtype'), $pkg->('Type::Subtypable') ] => sub {
256             my ($a, $b) = @_;
257             $a->base->subset($b);
258             });
259              
260             $SUBSET->add_variant(
261             [ $pkg->('Type::Subtypable'), $pkg->('Type::Subtype') ] => sub { 0 });
262              
263             $SUBSET->add_variant(
264             [ $pkg->('Type::Subtype'), $pkg->('Type::Subtype') ] => sub {
265             my ($a, $b) = @_;
266             $a->base->subset($b) ||
267             $a->base->subset($b->base) && $a->condition == $b->condition;
268             });
269            
270             $SUBSET->add_variant(
271             [ $pkg->('Type::Junction'), $pkg->('Type') ] => sub {
272             my ($a, $b) = @_;
273             $a->logic(map { $_->subset($b) } $a->values);
274             });
275              
276             $SUBSET->add_variant(
277             [ $pkg->('Type'), $pkg->('Type::Junction') ] => sub {
278             my ($a, $b) = @_;
279             $b->logic(map { $a->subset($_) } $b->values);
280             });
281              
282             $SUBSET->add_variant(
283             [ $pkg->('Type::Junction'), $pkg->('Type::Junction') ] => sub {
284             my ($a, $b) = @_;
285             # just like (Junction, Type)
286             $a->logic(map { $_->subset($b) } $a->values);
287             });
288             }
289              
290             package Class::Multimethods::Pure::Type::Normal;
291              
292             # Non-junctive thingies
293 21     21   131 use base 'Class::Multimethods::Pure::Type';
  21         39  
  21         14568  
294              
295             package Class::Multimethods::Pure::Type::Subtypable;
296              
297 21     21   130 use base 'Class::Multimethods::Pure::Type::Normal';
  21         35  
  21         11152  
298              
299             package Class::Multimethods::Pure::Type::Package;
300              
301             # A regular package type
302 21     21   239 use base 'Class::Multimethods::Pure::Type::Subtypable';
  21         52  
  21         13637  
303              
304 21     21   132 use Scalar::Util qw;
  21         71  
  21         7892  
305              
306             sub new {
307 555     555   799 my ($class, $package) = @_;
308 555   33     5839 bless {
309             name => $package,
310             } => ref $class || $class;
311             }
312              
313             # This is overridden for bootstrapping purposes. If you change
314             # logic here, you should change it in the multimethod above
315             # too.
316             sub subset {
317 1236     1236   1926 my ($self, $other) = @_;
318            
319 1236 100 66     5724 if (ref $self eq __PACKAGE__ && ref $other eq __PACKAGE__) {
320 1157         2287 $self->name->isa($other->name);
321             }
322             else {
323 79         288 $self->SUPER::subset($other);
324             }
325             }
326              
327             sub name {
328 2966     2966   3590 my ($self) = @_;
329 2966         16471 $self->{name};
330             }
331              
332             sub matches {
333 640     640   1075 my ($self, $obj) = @_;
334 640 50       2531 blessed($obj) ? $obj->isa($self->name) : 0;
335             }
336              
337             sub string {
338 12     12   20 my ($self) = @_;
339 12         22 $self->name;
340             }
341              
342 3308     3308   15642 sub ref_cacheable { 1 }
343              
344             sub ref_match {
345 0     0   0 my ($self, $package) = @_;
346 0         0 $package->isa($self->name);
347             }
348              
349             package Class::Multimethods::Pure::Type::Unblessed;
350              
351             # SCALAR, ARRAY, etc.
352 21     21   116 use base 'Class::Multimethods::Pure::Type::Subtypable';
  21         34  
  21         9508  
353 21     21   119 use Carp;
  21         37  
  21         7967  
354              
355             our %SPECIAL = (
356             SCALAR => 1,
357             ARRAY => 1,
358             HASH => 1,
359             CODE => 1,
360             REF => 1,
361             GLOB => 1,
362             LVALUE => 1,
363             IO => 1,
364             FORMAT => 1,
365             Regexp => 1,
366             );
367              
368             sub is_unblessed {
369 90     90   148 my ($class, $name) = @_;
370 90         354 $SPECIAL{$name};
371             }
372              
373             sub new {
374 21     21   33 my ($class, $name) = @_;
375 21 50       62 croak "$name is not a valid unblessed type"
376             unless $SPECIAL{$name};
377 21   33     183 bless {
378             name => $name,
379             } => ref $class || $class;
380             }
381              
382             sub name {
383 5557     5557   5075 my ($self) = @_;
384 5557         15237 $self->{name};
385             }
386              
387             sub matches {
388 111     111   143 my ($self, $obj) = @_;
389 111         171 $self->name eq ref $obj;
390             }
391              
392             sub string {
393 0     0   0 my ($self) = @_;
394 0         0 $self->name;
395             }
396              
397 22     22   99 sub ref_cacheable { 1 }
398              
399             sub ref_match {
400 0     0   0 my ($self, $package) = @_;
401 0         0 $self->name eq $package;
402             }
403              
404             package Class::Multimethods::Pure::Type::Any;
405              
406             # Anything whatever
407              
408 21     21   126 use base 'Class::Multimethods::Pure::Type::Normal';
  21         46  
  21         15010  
409              
410             sub new {
411 90     90   258 my ($class) = @_;
412 90   33     1166 bless { } => ref $class || $class;
413             }
414              
415             sub matches {
416 203     203   249 my ($self, $obj) = @_;
417 203         700 1;
418             }
419              
420             sub string {
421 6     6   10 my ($self) = @_;
422 6         16 "Any";
423             }
424              
425 9     9   53 sub ref_cacheable { 1 }
426              
427 0     0   0 sub ref_match { 1 }
428              
429             package Class::Multimethods::Pure::Type::Subtype;
430              
431             # A restricted type
432              
433 21     21   133 use base 'Class::Multimethods::Pure::Type::Subtypable';
  21         36  
  21         17408  
434              
435             sub new {
436 63     63   128 my ($class, $base, $condition) = @_;
437 63   33     652 bless {
438             base => $base,
439             condition => $condition,
440             } => ref $class || $class;
441             }
442              
443             sub base {
444 1476     1476   1623 my ($self) = @_;
445 1476         3417 $self->{base};
446             }
447              
448             sub condition {
449 914     914   1022 my ($self) = @_;
450 914         4101 $self->{condition};
451             }
452              
453             sub matches {
454 150     150   202 my ($self, $obj) = @_;
455 150 100       320 $self->base->matches($obj) && $self->condition->($obj);
456             }
457              
458             sub string {
459 6     6   10 my ($self) = @_;
460 6         16 "where(" . $self->base->string . ", {@{[$self->condition]}})";
  6         13  
461             }
462              
463 28     28   268 sub ref_cacheable { 0 }
464              
465             sub ref_match {
466 0     0   0 my ($self, $package) = @_;
467 0         0 $self->base->ref_match($package);
468             }
469              
470             package Class::Multimethods::Pure::Type::Junction;
471              
472             # Any junction type
473              
474 21     21   131 use base 'Class::Multimethods::Pure::Type';
  21         51  
  21         17015  
475              
476             sub new {
477 3     3   9 my ($class, @types) = @_;
478 3   33     54 bless {
479             values => \@types,
480             } => ref $class || $class;
481             }
482              
483             sub values {
484 86     86   100 my ($self) = @_;
485 86         90 @{$self->{values}};
  86         225  
486             }
487              
488             sub matches {
489 12     12   20 my ($self, $obj) = @_;
490 12         38 $self->logic(map { $_->matches($obj) } $self->values);
  24         51  
491             }
492              
493             sub ref_cacheable {
494 2     2   3 my ($self) = @_;
495 2         13 for ($_->values) {
496 4 50       8 return 0 unless $_->ref_cacheable;
497             }
498 2         12 return 1;
499             }
500              
501             sub ref_match {
502 0     0   0 my ($self, $package) = @_;
503 0         0 $self->logic(map { $_->ref_match($package) } $self->values);
  0         0  
504             }
505              
506             sub logic; # takes a list of true/false values and returns
507             # the boolean evaluation of them
508              
509             package Class::Multimethods::Pure::Type::Disjunction;
510              
511             # An any type
512 21     21   133 use base 'Class::Multimethods::Pure::Type::Junction';
  21         47  
  21         19932  
513              
514             sub logic {
515 84     84   187 my ($self, @values) = @_;
516 84         137 for (@values) {
517 132 100       471 return 1 if $_;
518             }
519 34         170 return 0;
520             }
521              
522             sub string {
523 0     0   0 my ($self) = @_;
524 0         0 'any(' . join(', ', map { $_->string } $self->values) . ')';
  0         0  
525             }
526              
527             package Class::Multimethods::Pure::Type::Conjunction;
528              
529             # An all type
530 21     21   135 use base 'Class::Multimethods::Pure::Type::Junction';
  21         110  
  21         13322  
531              
532             sub logic {
533 0     0   0 my ($self, @values) = @_;
534 0         0 for (@values) {
535 0 0       0 return 0 unless $_;
536             }
537 0         0 return 1;
538             }
539              
540             sub string {
541 0     0   0 my ($self) = @_;
542 0         0 'all(' . join(', ', map { $_->string } $self->values) . ')';
  0         0  
543             }
544              
545             package Class::Multimethods::Pure::Type::Injunction;
546             # The none() type has some very, very strange behavior when you think
547             # about it. In particular, note that none() (with no arguments) is
548             # at both the top and bottom of the type lattice. Perhaps none()
549             # should not be allowed, or should require arguments.
550              
551             # A none type
552 21     21   121 use base 'Class::Multimethods::Pure::Type::Junction';
  21         43  
  21         12742  
553              
554             sub logic {
555 0     0   0 my ($self, @values) = @_;
556 0         0 for (@values) {
557 0 0       0 return 0 if $_;
558             }
559 0         0 return 1;
560             }
561              
562             sub string {
563 0     0   0 my ($self) = @_;
564 0         0 'none(' . join(', ', map { $_->string } $self->values) . ')';
  0         0  
565             }
566              
567             package Class::Multimethods::Pure::Variant;
568              
569 21     21   128 use Carp;
  21         38  
  21         20317  
570              
571             sub new {
572 402     402   1142 my ($class, %o) = @_;
573 402   33     4008 bless {
      33        
      33        
574             params => $o{params} || croak("Multi needs a list of 'params' types"),
575             code => $o{code} || croak("Multi needs a 'code'ref"),
576             } => ref $class || $class;
577             }
578              
579             sub params {
580 9124     9124   9801 my ($self) = @_;
581 9124         8507 @{$self->{params}};
  9124         22407  
582             }
583              
584             sub param {
585 0     0   0 my ($self, $param) = @_;
586 0         0 $self->{params}[$param];
587             }
588              
589             sub code {
590 4622     4622   4930 my ($self) = @_;
591 4622         13007 $self->{code};
592             }
593              
594             sub less {
595 2461     2461   3022 my ($a, $b) = @_;
596              
597 2461         3945 my @args = $a->params;
598 2461         4388 my @brgs = $b->params;
599 2461 100       5516 return 1 if @brgs < @args;
600 2440 100       5074 return 0 if @args < @brgs;
601            
602 2424         2847 my $proper = 0;
603 2424         4447 for my $i (0..$#args) {
604 2636         5099 my $cmp = $args[$i]->subset($brgs[$i]);
605 2636 100       11118 return 0 unless $cmp;
606 1084 100 66     5002 if ($cmp && !$proper) {
607 1035         2118 $proper = !$brgs[$i]->subset($args[$i]);
608             }
609             }
610              
611 872         4103 return $proper;
612             }
613              
614             sub matches {
615 680     680   834 my ($self, $args) = @_;
616            
617 680         2254 my @params = $self->params;
618 680 100       1729 return 0 if @$args < @params;
619            
620 661         1342 for my $i (0..$#params) {
621 804 100       1849 unless ($params[$i]->matches($args->[$i])) {
622 420         2031 return 0;
623             }
624             }
625 241         838 return 1;
626             }
627              
628             sub param_ref_match {
629 0     0   0 my ($self, $param, $package) = @_;
630 0         0 $self->param($param)->ref_match($package);
631             }
632              
633             sub string {
634 12     12   19 my ($self) = @_;
635 12         38 "(" . join(', ', map { $_->string } $self->params) . ")";
  18         45  
636             }
637              
638             package Class::Multimethods::Pure::Method;
639              
640 21     21   151 use Carp;
  21         53  
  21         6425  
641              
642             sub new { # this needs to be overridden by subclasses
643 51     51   235 my ($class, %opt) = @_;
644 51   33     266 my $core = $opt{Core} || $Class::Multimethods::Pure::DEFAULT_CORE;
645            
646 51 100       613 if ($core->can('new')) {
647 17         83 return $core->new(%opt);
648             }
649            
650 34         91 $core = "Class::Multimethods::Pure::Method::$core";
651 34 50       433 if ($core->can('new')) {
652 34         164 return $core->new(%opt);
653             }
654              
655 0         0 croak "Multimethod core $opt{Core} doesn't exist!";
656             }
657              
658             sub call {
659 4631     4631   7614 my $self = shift;
660              
661 4631         9043 my $code = $self->find_variant(\@_)->code;
662 4622         9626 goto &$code;
663             }
664              
665             package Class::Multimethods::Pure::Method::Slow;
666              
667 21     21   159 use base 'Class::Multimethods::Pure::Method';
  21         39  
  21         14010  
668 21     21   139 use Carp;
  21         48  
  21         15242  
669              
670             sub new {
671 55     55   119 my ($class, %o) = @_;
672 55   50     843 bless {
      33        
673             variants => [],
674             Variant => $o{Variant} || 'Class::Multimethods::Pure::Variant',
675             } => ref $class || $class;
676             }
677              
678             sub add_variant {
679 352     352   477 my ($self, $params, $code) = @_;
680            
681 352         373 push @{$self->{variants}},
  352         1275  
682             $self->{Variant}->new(params => $params,
683             code => $code);
684             }
685              
686             sub variants {
687 302     302   360 my ($self) = @_;
688 302         457 @{$self->{variants}};
  302         904  
689             }
690              
691             sub find_variant {
692 136     136   194 my ($self, $args) = @_;
693            
694 136         170 my @cand;
695 136         355 VARIANT:
696 136         159 for my $variant (@{$self->{variants}}) {
697 680 100       1399 if ($variant->matches($args)) {
698 241         575 for (@cand) {
699 116 100       298 if ($_->less($variant)) {
700             # we're dominated: don't enter the list
701 12         37 next VARIANT;
702             }
703             }
704             # okay, we're in
705 229         675 for (my $i = 0; $i < @cand; $i++) {
706 104 100       247 if ($variant->less($cand[$i])) {
707             # we dominate this variant: take it out of the list
708 90         153 splice @cand, $i, 1;
709 90         288 $i--;
710             }
711             }
712 229         501 push @cand, $variant;
713             }
714             }
715              
716 136 100       378 if (@cand == 1) {
    100          
717 131         559 return $cand[0];
718             }
719             elsif (@cand == 0) {
720 1         214 croak "No method found for args (@$args)";
721             }
722             else {
723 8         39 croak "Ambiguous method call for args (@$args):\n" .
724 4         62 join '', map { " " . $_->string . "\n" } @cand;
725             }
726             }
727              
728             package Class::Multimethods::Pure::Method::DumbCache;
729             # This dispatcher is the most presumptuous dispatcher there is. It can
730             # optimize the simplest cases. It will be faster for methods which:
731             # * Don't use subtypes
732             # * Have a fixed arity
733             # It will be slower otherwise. Also it is a memory guzzler. The more
734             # different kinds of objects you call it with, the more memory it guzzles. So
735             # if you're subclassing a lot, avoid this dispatcher.
736              
737 21     21   141 use base 'Class::Multimethods::Pure::Method::Slow';
  21         63  
  21         12493  
738 21     21   164 use Carp;
  21         41  
  21         11889  
739              
740             sub new {
741 38     38   90 my ($class, %o) = @_;
742 38         247 my $self = $class->SUPER::new(%o);
743 38         262 $self->{cache} = {};
744 38         81 $self->{can_cache} = 1;
745 38         70 $self->{arity} = undef;
746 38         131 $self;
747             }
748              
749             sub add_variant {
750 302     302   434 my ($self, $params, $code) = @_;
751 302         1021 $self->SUPER::add_variant($params, $code);
752 302         709 $self->{cache} = {};
753 302         636 $self->{can_cache} = 1;
754 302         426 $self->{arity} = undef;
755            
756             # Find out if we should even try caching
757             VARIANT:
758 302         710 for my $var ($self->variants) {
759 1721         3125 my @params = $var->params;
760 1721 100       3361 unless (defined $self->{arity}) {
761 302         500 $self->{arity} = @params;
762             }
763             else {
764 1419 100       4392 unless ($self->{arity} == @params) {
765 2         5 $self->{can_cache} = 0;
766 2         7 last VARIANT;
767             }
768             }
769              
770 1719         3092 for ($var->params) {
771 3365 100       5791 unless ($_->ref_cacheable) {
772 28         42 $self->{can_cache} = 0;
773 28         98 last VARIANT;
774             }
775             }
776             }
777             }
778              
779             sub find_variant {
780 4523     4523   4776 my ($self, $args) = @_;
781 4523 100       7964 if ($self->{can_cache}) {
782 4484 100       9199 if (@$args < $self->{arity}) {
783 1         495 croak "Not enough arguments to multimethod";
784             }
785            
786 4483         8868 my $idx = join $;, map { ref } @$args[0..$self->{arity}-1];
  8954         17502  
787 4483 100       12713 if (my $var = $self->{cache}{$idx}) {
788 4440         11135 return $var;
789             }
790             else {
791 43         247 return $self->{cache}{$idx} = $self->SUPER::find_variant($args);
792             }
793             }
794             else {
795 39         122 return $self->SUPER::find_variant($args);
796             }
797             }
798              
799             package Class::Multimethods::Pure::Method::DecisionTree;
800              
801 21     21   214 use base 'Class::Multimethods::Pure::Method';
  21         40  
  21         13023  
802 21     21   132 use Carp;
  21         492  
  21         49470  
803              
804             sub new {
805 17     17   55 my ($class, %opt) = @_;
806 17   50     314 bless {
      33        
807             variants => [],
808             find_variant => undef,
809             Variant => $opt{Variant} || 'Class::Multimethods::Pure::Variant',
810             } => ref $class || $class;
811             }
812              
813             sub add_variant {
814 50     50   77 my ($self, $params, $code) = @_;
815              
816 50         57 push @{$self->{variants}},
  50         272  
817             $self->{Variant}->new(params => $params,
818             code => $code);
819              
820 50         156 undef $self->{find_variant};
821             }
822              
823             sub variants {
824 0     0   0 my ($self) = @_;
825 0         0 @{$self->{variants}};
  0         0  
826             }
827              
828             sub find_variant {
829 54     54   79 my ($self, $args) = @_;
830 54         113 $self->_compile->($args);
831             }
832              
833             sub _compile {
834 54     54   64 my ($self) = @_;
835 54 100       213 return $self->{find_variant} if defined $self->{find_variant};
836            
837 12         63 my $tree = $self->_make_tree([$self->_all_conditions], [$self->_make_condmap]);
838 12         242 my $code = $self->_compile_tree($tree, 0);
839            
840 12         129 $self->{find_variant} = $code;
841             }
842              
843             sub _compile_tree {
844 282     282   406 my ($self, $tree) = @_;
845            
846 282 100       665 if ($tree->{node_type} eq 'unique') {
847 39         65 my $variant = $self->{variants}[$tree->{variantno}];
848             return sub {
849 51     51   123 $variant;
850 39         136 };
851             }
852 243 100       460 if ($tree->{node_type} eq 'none_found') {
853             return sub {
854 1     1   2 my ($args) = @_;
855 1         229 croak "No method found for args (@$args)";
856 39         187 };
857             }
858 204 100       361 if ($tree->{node_type} eq 'ambiguous') {
859             return sub {
860 2     2   4 my ($args) = @_;
861 2         5 my @variants = @{$self->{variants}}[@{$tree->{variants}}];
  2         7  
  2         6  
862 4         13 croak "Ambiguous method call for args (@$args):\n" .
863 2         21 join '', map { " " . $_->string . "\n" } @variants;
864             }
865 69         314 }
866 135 50       280 if ($tree->{node_type} eq 'branch') {
867 135         182 my $position = $tree->{cond}{position};
868 135         179 my $type = $tree->{cond}{type};
869 135         305 my $good = $self->_compile_tree($tree->{good});
870 135         282 my $bad = $self->_compile_tree($tree->{bad});
871             return sub {
872 148 100 100 148   512 if (exists $_[0][$position] && $type->matches($_[0][$position])) {
873 68         219 goto &$good;
874             }
875             else {
876 80         252 goto &$bad;
877             }
878 135         561 };
879             }
880              
881 0         0 die "Unknown node type $tree->{node_type}";
882             }
883              
884             sub _reduce_condmap {
885 282     282   339 my ($self, $condmap) = @_;
886            
887 282         526 my @ret = @$condmap;
888 282         858 for (my $i = 0; $i < @ret; $i++) {
889 706         1468 for (my $j = 0; $j < @ret; $j++) {
890 2241 100       6400 if ($self->{variants}[$ret[$j]{variantno}]
891             ->less($self->{variants}[$ret[$i]{variantno}])) {
892              
893 103         177 splice @ret, $i, 1;
894 103         116 $i--;
895 103         319 last;
896             }
897             }
898             }
899              
900 282         595 \@ret;
901             }
902              
903             sub _make_tree {
904 282     282   659 my ($self, $conds, $condmap) = @_;
905              
906             {
907 282         296 my $rcmap = $self->_reduce_condmap($condmap);
  282         550  
908            
909 282 100       829 if (@$rcmap == 0) {
910             return {
911 39         381 node_type => 'none_found',
912             };
913             }
914              
915 243 100       569 if (@$conds == 0) {
916 108 100       237 if (@$rcmap == 1) {
917             return {
918 39         298 node_type => 'unique',
919             variantno => $rcmap->[0]{variantno},
920             };
921             }
922 69 50       147 if (@$rcmap > 1) {
923             return {
924 211         875 node_type => 'ambiguous',
925 69         107 variants => [ map { $_->{variantno} } @$rcmap ],
926             };
927             }
928             }
929             }
930            
931 135         150 my $bestbalance = 1e999;
932 135         144 my $bestcond;
933 135         251 for my $cond (0..$#$conds) {
934 251         408 my (@good, @bad);
935 251         390 for (@$condmap) {
936 869         1926 my $bits = $_->{cond}->($conds->[$cond]);
937 869 50       1921 if ($bits & 0b01) {
938 869         1411 push @good, $_;
939             }
940 869 100       1834 if ($bits & 0b10) {
941 524         852 push @bad, $_;
942             }
943             }
944              
945 251         1176 my $balance = abs(@good - @$conds/2) + abs(@bad - @$conds/2);
946 251 100       731 if ($balance < $bestbalance) {
947 152         180 $bestbalance = $balance;
948 152         519 $bestcond = [ $cond, \@good, \@bad ];
949             }
950             }
951              
952 135 50       515 die "Couldn't find best condition for some reason" unless defined $bestcond;
953              
954 135         239 my $newconds = [ @$conds ];
955 135         237 splice @$newconds, $bestcond->[0], 1;
956              
957             return {
958 135         704 node_type => 'branch',
959             cond => $conds->[$bestcond->[0]],
960             good => $self->_make_tree($newconds, $bestcond->[1]),
961             bad => $self->_make_tree($newconds, $bestcond->[2]),
962             };
963             }
964              
965             sub _make_condmap {
966 12     12   24 my ($self) = @_;
967              
968 35         112 map {
969 12         37 { variantno => $_, cond => $self->_make_condition($self->{variants}[$_]) }
970 12         37 } 0..@{$self->{variants}}-1;
971             }
972              
973             sub _make_condition {
974 35     35   64 my ($self, $variant, $childrenq) = @_;
975              
976 35         73 my @params = $variant->params;
977 35         49 my @conds;
978              
979             # we return a bitfield:
980             # bit 0 = consistent with cond
981             # bit 1 = consistent with not cond
982            
983 35         121 for my $i (0..$#params) {
984             push @conds, sub {
985 997     997   1043 my ($cond) = @_;
986 997 100       2295 return 0b11 if $cond->{position} != $i;
987 867 100       1999 return 0b01 if $params[$i]->subset($cond->{type});
988 522         1271 return 0b11;
989             }
990 39         255 }
991              
992             # 'and' all of @conds together
993             return sub {
994 869     869   938 my ($cond) = @_;
995 869         876 my $ret = 0b11;
996 869         1137 for (@conds) {
997 997         1610 $ret &= $_->($cond);
998             }
999 869         1439 return $ret;
1000 35         299 };
1001             }
1002              
1003             sub _all_conditions {
1004 12     12   24 my ($self) = @_;
1005              
1006 12         16 my @conds;
1007 12         21 for (@{$self->{variants}}) {
  12         42  
1008 35         81 my @params = $_->params;
1009 35         82 push @conds, map { { position => $_, type => $params[$_] } } 0..$#params;
  39         164  
1010             }
1011              
1012 12         54 for (my $i = 0; $i < @conds; $i++) {
1013 35         126 for (my $j = $i+1; $j < @conds; $j++) {
1014 55 100 100     392 if ($conds[$i]->{position} == $conds[$j]->{position}
      100        
1015             && $conds[$i]->{type}->subset($conds[$j]->{type})
1016             && $conds[$j]->{type}->subset($conds[$i]->{type})) {
1017 4         13 splice @conds, $j, 1;
1018 4         19 $j--;
1019             }
1020             }
1021             }
1022              
1023 12         72 return @conds;
1024             }
1025              
1026             1;
1027              
1028             =head1 NAME
1029              
1030             Class::Multimethods::Pure - Method-ordered multimethod dispatch
1031              
1032             =head1 SYNOPSIS
1033              
1034             use Class::Multimethods::Pure;
1035              
1036             package A;
1037             sub magic { rand() > 0.5 }
1038             package B;
1039             use base 'A';
1040             package C;
1041             use base 'A';
1042            
1043             BEGIN {
1044             multi foo => ('A', 'A') => sub {
1045             "Generic catch-all";
1046             };
1047              
1048             multi foo => ('A', 'B') => sub {
1049             "More specific";
1050             };
1051            
1052             multi foo => (subtype('A', sub { $_[0]->magic }), 'A') => sub {
1053             "This gets called half the time instead of catch-all";
1054             };
1055              
1056             multi foo => (any('B', 'C'), 'A') => sub {
1057             "Accepts B or C as the first argument, but not A"
1058             };
1059             }
1060              
1061             =head1 DESCRIPTION
1062              
1063             =head2 Introduciton to Multimethods
1064              
1065             When you see the perl expression:
1066              
1067             $animal->speak;
1068              
1069             You're asking for C to be performed on C<$animal>, based on
1070             C<$animal>'s current type. For instance, if C<$animal> were a Tiger, it
1071             would say "Roar", whereas if C<$animal> were a Dog, it would say "Woof".
1072             The information of the current type of C<$animal> need not be known by
1073             the caller, which is what makes this mechanism powerful.
1074              
1075             Now consider a space-shooter game. You want to create a routine
1076             C that does something based on the types of I arguments.
1077             For instance, if a Bullet hits a Ship, you want to deliver some damage,
1078             but if a Ship hits an Asteroid, you want it to bounce off. You could
1079             write it like this:
1080              
1081             sub collide {
1082             my ($a, $b) = @_;
1083             if ($a->isa('Bullet') && $b->isa('Ship')) {...}
1084             elsif ($a->isa('Ship') && $b->isa('Asteroid')) {...}
1085             ...
1086             }
1087              
1088             Just as you could have written C that way. But, above being
1089             ugly, this prohibits the easy addition of new types. You first have to
1090             create the type in one file, and then remember to add it to this list.
1091              
1092             However, there is an analog to methods for multiple arguments, called
1093             I. This allows the logic for a routine that dispatches on
1094             multiple arguments to be spread out, so that you can include the
1095             relevant logic for the routine in the file for the type you just added.
1096              
1097             =head2 Usage
1098              
1099             You can define multimethods with the "multi" declarator:
1100              
1101             use Class::Multimethods::Pure;
1102              
1103             multi collide => ('Bullet', 'Ship') => sub {
1104             my ($a, $b) = @_; ...
1105             };
1106              
1107             multi collide => ('Ship', 'Asteroid') => sub {
1108             my ($a, $b) = @_; ...
1109             };
1110              
1111             It is usually wise to put such declarations within a BEGIN block, so
1112             they behave more like Perl treats subs (you can call them without
1113             parentheses and you can use them before you define them).
1114              
1115             If you think BEGIN looks ugly, then you can define them inline as you
1116             use the module:
1117              
1118             use Class::Multimethods::Pure
1119             multi => collide => ('Bullet', 'Ship') => sub {...};
1120              
1121             But you miss out on a couple of perks if you do that. See
1122             L below.
1123              
1124             After these are declared, you can call C like a regular
1125             subroutine:
1126              
1127             collide($ship, $asteroid);
1128              
1129             If you defined any variant of a multimethod within a package, then the
1130             multi can also be called as a method on any object of that package (and
1131             any package derived from it). It will be passed as the first argument.
1132              
1133             $ship->collide($asteroid); # same as above
1134              
1135             If you want to allow a multi to be called as a method on some package
1136             without defining any variants in that package, use the null declaration:
1137              
1138             multi 'collide';
1139             # or
1140             use Class::Multimethods::Pure multi => collide;
1141              
1142             This is also used to import a particular multi into your scope without
1143             defining any variants there.
1144              
1145             All multis are global; that is, C always refers to the same
1146             multi, no matter where/how it is defined. Allowing scoped multis is on
1147             the TODO list. But you still have to import it (as shown above) to use
1148             it.
1149              
1150             =head2 Non-package Types
1151              
1152             In addition to any package name, there are a few special names that
1153             represent unblessed references. These are the strings returned by
1154             C when given an unblessed reference. For the record:
1155              
1156             SCALAR
1157             ARRAY
1158             HASH
1159             CODE
1160             REF
1161             GLOB
1162             LVALUE
1163             IO
1164             FORMAT
1165             Regexp
1166              
1167             For example:
1168              
1169             multi pretty => (Any) => sub { $_[0] };
1170             multi pretty => ('ARRAY') => sub {
1171             "[ " . join(', ', map { pretty($_) } @{$_[0]}) . " ]";
1172             };
1173             multi pretty => ('HASH') => sub {
1174             my $hash = shift;
1175             "{ " . join(', ',
1176             map { "$_ => " . pretty($hash->{$_}) } keys %$hash)
1177             . " }";
1178             };
1179              
1180             =head2 Special Types
1181              
1182             There are several types which don't refer to any package. These are
1183             Junctive types, Any, and Subtypes.
1184              
1185             Junctive types represent combinations of types. C
1186             'Asteroid')> represents an object that is of either (or both) of the
1187             classes C and C. C represents an
1188             object that is of both types C and C (probably some sort of
1189             pegasus). Finally, C represents an object that is I a
1190             C (or anything derived from C).
1191              
1192             For example:
1193              
1194             multi fly => ('Horse') => sub { die "Horses don't fly!" };
1195             multi fly => ('Bird') => sub { "Flap flap chirp" };
1196             multi fly => (all('Horse', 'Bird')) => sub { "Flap flap whinee" };
1197              
1198             The C type represents anything at all, object or not. Use it like
1199             so:
1200              
1201             multi fly => (Any) => sub { die "Most things can't fly." };
1202              
1203             Note that it is not a string. If you give it the string "Any", it will
1204             refer to the C package, which generally doesn't exist. C is a
1205             function that takes no arguments and returns an C type object.
1206              
1207             Finally, there is a C function which allows you to specify
1208             constrained types. It takes two arguments: another type and a code
1209             reference. The code reference is called on the argument that is being
1210             tested for that type (after checking that the first argument---the base
1211             type---is satisfied), and if it returns true, then the argument is of
1212             that type. For example:
1213              
1214             my $ZeroOne = subtype(Any, sub { $_[0] < 2 });
1215              
1216             We have just defined a type object that is only true when its argument
1217             is less than two and placed it in the type variable C<$ZeroOne>. Now we
1218             can define the Fibonacci sequence function:
1219              
1220             multi fibo => (Any) => sub { fibo($_[0]-1) + fibo($_[0]-2) };
1221             multi fibo => ($ZeroOne) => sub { 1 };
1222              
1223             Of course, we didn't have to use a type variable; we could have just put
1224             the C call right where C<$ZeroOne> appears in the definition.
1225              
1226             Consider the follwing declarations:
1227              
1228             multi describe => (subtype(Any, sub { $_[0] > 10 })) => sub {
1229             "Big";
1230             };
1231             multi describe => (subtype(Any, sub { $_[0] == 42 })) => sub {
1232             "Forty-two";
1233             };
1234              
1235             Calling C causes an ambiguity error, stating that both
1236             variants of C match. We can clearly see that the latter is
1237             more specific than the former (see L for a precise
1238             definition of how this relates to dispatch), but getting the computer to
1239             see that involves solving the halting problem.
1240              
1241             So we have to make explicit the relationships between the two subtypes,
1242             using type variables:
1243              
1244             my $Big = subtype(Any, sub { $_[0] > 10 });
1245             my $FortyTwo = subtype($Big, sub { $_[0] == 42 });
1246             multi describe => ($Big) => sub {
1247             "Big";
1248             };
1249             multi describe => ($FortyTwo) => sub {
1250             "Forty-two";
1251             };
1252              
1253             Here we have specified that C<$FortyTwo> is more specific than C<$Big>,
1254             since it is a subtype of C<$Big>. Now calling C results
1255             in "Forty-two".
1256              
1257             In order to get the definitions of C, C, C, C, and
1258             C, you need to import them from the module. This happens by
1259             default if you use the module with no arguments. If you only want to
1260             export some of these, use the C command:
1261              
1262             use Class::Multimethods::Pure import => [qw];
1263              
1264             This will accept a null list for you folks who don't like to import
1265             anything.
1266              
1267             =head2 Semantics
1268              
1269             I've put off explaining the method for determing which method to call
1270             until now. That's mostly because it will either do exactly what you
1271             want, or yell at you for being ambiguous[1]. I'll take a moment to
1272             define it precisely and mathematically, and then explain what that means
1273             for Mere Mortals.
1274              
1275             First, think of a class simply as the set of all of its possible
1276             instances. When you say C is derived from C, you're saying
1277             that "anything that is a C is also a C", and therefore that
1278             C is a subset of C.
1279              
1280             Now define a partial order C<< < >> on the variants of a multimethod.
1281             This will represent the relationship "is more specific than". This is
1282             defined as follows:
1283              
1284             Variant A < variant B if and only if
1285              
1286             =over
1287              
1288             =item *
1289              
1290             Every parameter type in A is a subset of the corresponding parameter in
1291             B.
1292              
1293             =item *
1294              
1295             At least one of them is a proper subset (that is, a subset but not
1296             equal).
1297              
1298             =back
1299              
1300             A particular argument list matches a variant A if:
1301              
1302             =over
1303              
1304             =item *
1305              
1306             Each argument is an element of the corresponding parameter type.
1307              
1308             =item *
1309              
1310             For every variant B, if B matches then A <= B.
1311              
1312             =back
1313              
1314             In other words, we define "is more specific than" in the most
1315             conservative possible terms. One method is more specific than the other
1316             only when I of its parameters are either equal or more specific.
1317              
1318             A couple of notes:
1319              
1320             =over
1321              
1322             =item *
1323              
1324             Both A and B are more specific than any(A, B), unless one is a subset of
1325             the other, in which case the junction is equivalent the more general
1326             one.
1327              
1328             =item *
1329              
1330             all(A, B) is more specific than both A and B, unless one is a subset of
1331             the other, in which case the junction is equivalent to the more specific
1332             one.
1333              
1334             =item *
1335              
1336             A subtype with base type X is always more specific than X. This is true
1337             even if the constraint is C, unfortunately. That's one of
1338             those halting problem thingamajiggers.
1339              
1340             =item *
1341              
1342             Everything is more specific than C, except C itself.
1343              
1344             =back
1345              
1346             [1] Unlike Manhattan Distance as implemented by L,
1347             which does what you want more often, but does what you don't want
1348             sometimes without saying a word.
1349              
1350             =head2 Dispatch Straegties (and speed)
1351              
1352             Class::Multimethods::Pure currently has three different strategies
1353             it can use for dispatch, named I. If you're having issues
1354             with speed, you might want to play around with the different cores
1355             (or write a new one and send it to me C<:-)>. The three cores are:
1356              
1357             =over
1358              
1359             =item Class::Multimethods::Pure::Method::Slow
1360              
1361             This is the default core. It implements the algorithm described above in an
1362             obvious and straightforward way: it loops through all the defined variants and
1363             sees which ones are compatible with your argument list, eliminates dominated
1364             methods, and returns. The performance of this core can be miserable,
1365             especially if you have many variants. However, if you only have two or three
1366             variants, it might the best one for your job.
1367              
1368             =item Class::Multimethods::Pure::Method::DumbCache
1369              
1370             This core implements the semantics above by asking the slow core what it would
1371             do, then caching the result based on the ref type of the arguments. It can
1372             guzzle memory if you pass many different types into the multi. For example,
1373             even if you only have one variant (A,A), but you subclass A I times and pass
1374             instances of the subclass into the multi instead, the DumbCache core will use
1375             memory proportional to I squared. If all your variants have the same arity,
1376             they don't use junctions or subtypes, and you're sure that the number of
1377             subclasses of the classes defined in the variants is bounded (and small), then
1378             this will be the fastest core.
1379              
1380             =item Class::Multimethods::Pure::Method::DecisionTree
1381              
1382             This core implements the semantics above by building a decision tree of
1383             type membership checks. That is, it does all its logic (like the Slow core)
1384             by asking whether arguments are of type X, without any magic caching or ref
1385             checking or anything. It also minimizes the numbers of such checks necessary
1386             in the worst case. It takes some time to compile the multimethod the first
1387             time you dispatch to it after a change. If you don't meet the conditions for
1388             DumbCache to be efficient, and you are not making frequent changes to the
1389             dispatch table (almost nobody does), then this is going to be the fastest
1390             core.
1391              
1392             =back
1393              
1394             To enable a different core for all multimethods, set
1395             C<$Class::Multimethods::Pure::DEFAULT_CORE> to the desired core. For example:
1396              
1397             use Class::Multimethods::Pure;
1398             $Class::Multimethods::Pure::DEFAULT_CORE = 'DecisionTree';
1399              
1400             (If the name given to core is not already a class, then the module will try
1401             prepending Class::Multimethods::Pure::Method. I suppose you could get in
1402             trouble if you happened to have a package named Slow, DumbCache,
1403             DecisionTree in your program. When in doubt, fully qualify.)
1404              
1405             A more courteous and versatile approach is to specify the core as an
1406             option to the method definition; i.e.:
1407              
1408             use Class::Multimethods::Pure foo => ('A', 'B'),
1409             -Core => 'DecisionTree',
1410             sub {...}
1411              
1412             or:
1413              
1414             multi foo => ('A', 'B'), -Core => 'DecisionTree', sub {
1415             ...
1416             };
1417              
1418             You may also set options separately from definiton, like:
1419              
1420             use Class::Multimethods::Pure 'foo', -Core => 'DecisionTree';
1421              
1422             or:
1423            
1424             multi 'foo', -Core => 'DecisionTree';
1425              
1426             which sets the core but defines no variant.
1427              
1428             =head2 Combinator Factoring
1429              
1430             One of the things that I find myself wanting to do most when working
1431             with multimethods is to have combinator types. These are types that
1432             simply call the multimethod again for some list of aggregated objects
1433             and perform some operation on them (like a Junction). They're easy
1434             to make if they're by themselves.
1435              
1436             multi foo => ('Junction', 'Object') => sub {...}
1437             multi foo => ('Object', 'Junction') => sub {...}
1438             multi foo => ('Junction', 'Junction') => sub {...}
1439              
1440             However, you find yourself in a major pickle if you want to have more of
1441             them. For instance:
1442              
1443             multi foo => ('Kunction', 'Object') => sub {...}
1444             multi foo => ('Object', 'Kunction') => sub {...}
1445             multi foo => ('Kunction', 'Kunction') => sub {...}
1446              
1447             Now they're both combinators, but the module yells at you if you pass
1448             (Kunction, Junction), because there are two methods that would satisfy
1449             that.
1450              
1451             The way to define precedence with these combinators is similar to the
1452             way you define precedence in a recursive descent grammar. You create a
1453             cascade of empty classes at the top of your heirarchy, and derive each
1454             of your generics from a different one of those:
1455              
1456             package AnyObject;
1457             package JunctionObject;
1458             use base 'AnyObject';
1459             package KunctionObject;
1460             use base 'JunctionObject';
1461             package Object;
1462             use base 'KunctionObject';
1463             # derive all other classes from Object
1464            
1465             package Junction;
1466             use base 'JunctionObject';
1467             ...
1468             package Kunction;
1469             use base 'KunctionObject';
1470             ...
1471              
1472             Now define your multis using these:
1473              
1474             multi foo => ('Junction', 'JunctionObject') => {...}
1475             multi foo => ('JunctionObject', 'Junction') => {...}
1476             multi foo => ('Junction', 'Junction') => {...}
1477             multi foo => ('Kunction', 'KunctionObject') => {...}
1478             multi foo => ('KunctionObject', 'Kunction') => {...}
1479             multi foo => ('Kunction', 'Kunction') => {...}
1480              
1481             Then the upper one (Junction in this case) will get threaded first,
1482             because a Junction is not a KunctionObject, so it doesn't fit in the
1483             latter three methods.
1484              
1485             =head2 Extending
1486              
1487             Class::Multimethods::Pure was written to be extended in many ways, but
1488             with a focus on adding new types of, er, types. Let's say you want to
1489             add Perl 6-ish roles to the Class::Multimethods::Pure dispatcher. You
1490             need to do four things:
1491              
1492             =over
1493              
1494             =item *
1495              
1496             Create a class, say My::Role derived from
1497             Class::Multimethods::Pure::Type.
1498              
1499             =item *
1500              
1501             Define the method My::Role::matches, which takes a scalar and returns
1502             whether it is a member of that class (including subclasses, etc.).
1503              
1504             =item *
1505              
1506             Define the method My::Role::string, which returns a reasonable string
1507             representation of the type, for the user's sake.
1508              
1509             =item *
1510              
1511             Define as many multimethod variants of "subset" as necessary, which
1512             return whether an object which is a member of the left type implies that
1513             it is a member of the right type. Construct a
1514             Class::Multimethods::Pure::Type::Package type for your type for the
1515             multimethod. For a role, you'd need to define:
1516              
1517             $Class::Multimethods::Pure::Type::SUBSET->add_variant(
1518             [ Class::Multimethods::Pure::Type::Package->new('My::Role'),
1519             Class::Multimethods::Pure::Type::Package->new('My::Role') ] =>
1520             sub {...});
1521              
1522             And:
1523              
1524             $Class::Multimethods::Pure::Type::SUBSET->add_variant(
1525             [ Class::Multimethods::Pure::Type::Package->new(
1526             'Class::Multimethods::Pure::Type::Package'),
1527             Class::Multimethods::Pure::Type::Package->new('My::Role') ] =>
1528             sub {...});
1529              
1530             (Ugh, I wish my module name weren't so long).
1531              
1532             =back
1533              
1534             After you have defined these, you have fulfilled the
1535             Class::Multimethods::Pure::Type interface, and now you can pass an
1536             object of type My::Role to multi() and it will be dispatched using the
1537             pure-ordered scheme. It is nice to give the user a concise constructor
1538             for your object type.
1539              
1540             You can also automatically promote strings into objects by defining
1541             variants on the (unary) multimethod
1542             $Class::Multimethods::Pure::Type::PROMOTE. So to promote strings that
1543             happen to be the names of roles, do:
1544              
1545             $Class::Multimethods::Pure::Type::PROMOTE->add_variant(
1546             [ Class::Multimethods::Pure::Type::Subtype->new(
1547             Class::Multimethods::Pure::Type::Any->new,
1548             sub { is_a_role_name($_[0]) })
1549             ] =>
1550             sub { My::Role->new($_[0]) });
1551              
1552             Now when you pass strings to "multi", if is_a_role_name returns true on
1553             them, they will be promoted to a My::Role object.
1554              
1555             =head1 AUTHOR
1556              
1557             Luke Palmer
1558              
1559             =head1 COPYRIGHT
1560              
1561             Copyright (C) 2005 by Luke Palmer (lrpalmer@gmail.com)
1562              
1563             This library is free software; you can redistribute it and/or modify
1564             it under the same terms as Perl itself, either Perl version 5.8.5 or,
1565             at your option, any later version of Perl 5 you may have available.