File Coverage

blib/lib/Sub/Multi/Tiny/Dispatcher/Default.pm
Criterion Covered Total %
statement 33 37 89.1
branch 6 8 75.0
condition n/a
subroutine 7 7 100.0
pod 1 1 100.0
total 47 53 88.6


line stmt bran cond sub pod time code
1             package Sub::Multi::Tiny::Dispatcher::Default;
2              
3 8     8   9917 use 5.006;
  8         41  
4 8     8   99 use strict;
  8         16  
  8         141  
5 8     8   32 use warnings;
  8         15  
  8         162  
6              
7             #use Data::Dumper; # DEBUG
8              
9 8     8   3683 use Guard;
  8         3269  
  8         427  
10 8         2434 use Sub::Multi::Tiny::Util qw(_hlog _line_mark_string _make_positional_copier
11 8     8   94 _complete_dispatcher);
  8         13  
12              
13             our $VERSION = '0.000012'; # TRIAL
14              
15             # Documentation {{{1
16              
17             =head1 NAME
18              
19             Sub::Multi::Tiny::Dispatcher::Default - Default dispatcher-maker for Sub::Multi::Tiny
20              
21             =head1 SYNOPSIS
22              
23             require Sub::Multi::Tiny::Dispatcher::Default;
24             my $dispatcher_coderef =
25             Sub::Multi::Tiny::Dispatcher::Default::MakeDispatcher({impls=>[]...});
26              
27             See L<Sub::Multi::Tiny> for more. This module does not export any symbols
28             (or even have the capability to do so!).
29              
30             This dispatcher currently only dispatches by arity.
31              
32             =head1 FUNCTIONS
33              
34             =cut
35              
36             # }}}1
37              
38             =head2 MakeDispatcher
39              
40             Make the default dispatcher for the given multi. See L</SYNOPSIS>.
41              
42             TODO expand. For now, only dispatches based on arity.
43              
44             =cut
45              
46             sub MakeDispatcher {
47 6     6 1 13 my $hr = shift; # Has possible_params and impls arrayrefs
48 6         12 my $code = '';
49 3     3   12 _hlog { require Data::Dumper;
50 6         34 "Making default dispatcher for: ", Data::Dumper->Dump([$hr], ['multisub']) };
  3         26  
51              
52             # Sort the candidates
53 6         31 my (%candidates_by_arity, %copiers_by_arity); # TODO make this cleaner
54 6         13 foreach my $impl (@{$hr->{impls}}) {
  6         22  
55 10         16 my $arity = @{$impl->{args}};
  10         26  
56             die "Two candidates of the same arity ($arity) - try D:TypeParams?"
57 10 100       200 if exists $candidates_by_arity{$arity};
58 9         22 $candidates_by_arity{$arity} = $impl->{code};
59             $copiers_by_arity{$arity} =
60 9         34 _make_positional_copier($hr->{defined_in}, $impl);
61              
62             # Die cleanly if we got something we can't handle
63 9         21 foreach my $arg (@{$impl->{args}}) {
  9         30  
64             die "Type constraint on $impl->{candidate_name}, arg $arg->{name}"
65 12 100       59 . '- try D:TypeParams?' if $arg->{type};
66             die "'where' clause on $impl->{candidate_name}, arg $arg->{name}"
67 11 100       230 . '- try D:TypeParams?' if $arg->{where};
68             } #foreach $arg
69              
70             } #foreach $impl
71              
72             # Make the dispatcher
73 3         18 $code .= _line_mark_string <<EOT;
74             # Find the candidate
75 0         0 my \$arity = scalar \@_;
76 0         0 \$candidate = \$data[0]->{\$arity};
77 0 0       0 die "No candidate found for $hr->{defined_in}\() with arity " .
78             (scalar \@_) unless \$candidate;
79 0         0 \$copier = \$data[1]->{\$arity};
80             EOT
81              
82 3         19 return _complete_dispatcher($hr, $code,
83             # @data used by $code
84             \%candidates_by_arity,
85             \%copiers_by_arity
86             );
87              
88             } #MakeDispatcher
89              
90             1;
91             __END__
92              
93             # Rest of documentation {{{1
94              
95             =head1 AUTHOR
96              
97             Chris White E<lt>cxw@cpan.orgE<gt>
98              
99             =head1 LICENSE
100              
101             Copyright (C) 2019 Chris White E<lt>cxw@cpan.orgE<gt>
102              
103             This library is free software; you can redistribute it and/or modify
104             it under the same terms as Perl itself.
105              
106             =cut
107              
108             # }}}1
109             # vi: set fdm=marker: #