File Coverage

blib/lib/Sub/Multi.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Sub::Multi;
2             our $VERSION = '0.003';
3 1     1   31509 use 5.008;
  1         5  
  1         91  
4 1     1   7 use base 'Class::Multimethods::Pure';
  1         2  
  1         2877  
5 1     1   37584 use Data::Bind 0.27;
  0            
  0            
6              
7             =head1 NAME
8              
9             Sub::Multi - Data::Bind-based multi-sub dispatch
10              
11             =head1 SYNOPSIS
12              
13             my $multi_sub = Sub::Multi->new($sub1, $sub2, $sub3);
14              
15             Now dispatch to the right subroutine, based on C<@args>.
16              
17             $multi_sub->(@args);
18              
19             =head1 DESCRIPTION
20              
21             Perl6 allows multiple subs and methods with the same name, differing only in
22             their signature.
23              
24             multi sub bar (Dog $foo) {?}
25             multi sub bar (Cat $foo) {?}
26              
27             Dispatching will happen based on the runtime signature of the subroutine or
28             method call.
29              
30             =head2 new
31              
32             my $multi_sub = Sub::Multi->new($sub1, $sub2, $sub3);
33             $multi_sub->(@args);
34              
35             Build and return a code reference that will dispatch based on the Perl6
36             multi dispatch semantics.
37              
38             I Before the method is actually dispatched,
39             a call to Data::Bind->sub_signature should be made to register the subroutine
40             signature.
41              
42             =cut
43              
44              
45             sub new {
46             my ($class, @subs) = @_;
47             return bless sub { $class->dispatch(\@subs, @_) }, 'Sub::Multi::Method';
48             }
49              
50             =head2 add_multi
51              
52             my $multi_sub = Sub::Multi->add_multi($sub_name, \&sub );
53             $multi_sub->(@args);
54              
55             Associates C<$sub_name> with C<\&sub>, and returns code reference
56             that will dispatch appropriately. C can be called multiple
57             times with the same C<$sub_name> to build a multi-dispatch method.
58              
59             I Before the method is actually dispatched,
60             a call to Data::Bind->sub_signature should be made to register the subroutine
61             signature.
62              
63             =cut
64              
65             sub add_multi {
66             my ($class, $name, $sub) = @_;
67             my $pkg = ((caller)[0]);
68             no strict 'refs';
69             my $subs = ${$pkg."::SUB_MULTI_REGISTRY"} ||= [];
70             push @$subs, $sub;
71             no warnings 'redefine';
72             *{$pkg."::$name"} = $class->new(@$subs);
73             }
74              
75             sub dispatch {
76             my $class = shift;
77             my $subs = shift;
78             my @compat;
79             for my $variant (@$subs) {
80             my $cv = Data::Bind::_get_cv($variant);
81             push @compat, $variant if *$cv->{sig}->is_compatible( [ @{$_[0]} ], { %{$_[1]} } );
82             }
83             die 'I hate vapour ware' unless @compat;
84             while (@compat != 1) {
85             die 'I hate ambiguous software';
86             }
87             goto $compat[0];
88             }
89              
90             1;
91              
92             =head1 SEE ALSO
93              
94             L
95              
96             B Add a good reference to Perl6 multiple dispatch here.
97              
98             =head1 AUTHORS
99              
100             Chia-liang Kao Eclkao@clkao.orgE
101              
102             =head1 COPYRIGHT
103              
104             Copyright 2006 by Chia-liang Kao and others.
105              
106             This program is free software; you can redistribute it and/or modify it
107             under the same terms as Perl itself.
108              
109             See L
110              
111             =cut