Sub::Multi::Tiny - Multisubs/multimethods (multiple dispatch) yet another way!
{ package main::my_multi; # We're making main::my_multi() use Sub::Multi::Tiny qw($foo $bar); # All possible params sub first :M($foo, $bar) { # sub's name will be ignored, return $foo ** $bar; # but can't match the one we're making } sub second :M($foo) { return $foo + 42; } } # Back in package main, my_multi() is created just before the run phase. say my_multi(2, 5); # -> 32 say my_multi(1295); # -> 1337
The default dispatcher dispatches solely by arity, and only one candidate can have each arity. For more flexible dispatching, see Sub::Multi::Tiny::Dispatcher::TypeParams.
Sub::Multi::Tiny is a library for making multisubs, aka multimethods, aka multiple-dispatch subroutines. Each multisub is defined in a single package. Within that package, the individual implementations ("impls") are subs tagged with the :M attribute. The names of the impls are preserved but not used specifically by Sub::Multi::Tiny.
sub
:M
Within a multisub package, the name of the sub being defined is available for recursion. For example (using where, supported by Sub::Multi::Tiny::Dispatcher::TypeParams):
where
{ package main::fib; use Sub::Multi::Tiny qw(D:TypeParams $n); sub base :M($n where { $_ <= 1 }) { 1 } sub other :M($n) { $n * fib($n-1) } }
This code creates function fib() in package main. Within package main::fib, function fib() is an alias for main::fib(). It's easier to use than to explain!
fib()
main
main::fib
main::fib()
Sets up the package that uses it to define a multisub. The parameters are all the parameter variables that the multisubs will use. import creates these as package variables so that they can be used unqualified in the multisub implementations.
import
A parameter D:Dispatcher can also be given to specify the dispatcher to use --- see "CUSTOM DISPATCH".
D:Dispatcher
Also sets "$VERBOSE" in Sub::Multi::Tiny::Util if the environment variable SUB_MULTI_TINY_VERBOSE has a truthy value. If the SUB_MULTI_TINY_VERBOSE value is numeric, $VERBOSE is set to that value; otherwise, $VERBOSE is set to 1.
SUB_MULTI_TINY_VERBOSE
$VERBOSE
This module includes a default dispatcher (implemented in Sub::Multi::Tiny::Dispatcher::Default. To use a different dispatcher, define or import a sub MakeDispatcher() into the package before compilation ends. That sub will be called to create the dispatcher. For example:
MakeDispatcher()
{ package main::foo; use Sub::Multi::Tiny; sub MakeDispatcher { return sub { ... } } }
or
{ package main::foo; use Sub::Multi::Tiny; use APackageThatImportsMakeDispatcherIntoMainFoo; }
As a shortcut, you can specify a dispatcher on the use line. For example:
use
use Sub::Multi::Tiny qw(D:Foo $var);
will use dispatcher Sub::Multi::Tiny::Dispatcher::Foo. Any name with a double-colon will be used as a full package name. E.g., D:Bar::Quux will use dispatcher Bar::Quux. If Foo does not include a double-colon, Sub::Multi::Tiny::Dispatcher:: will be prepended.
Sub::Multi::Tiny::Dispatcher::Foo
D:Bar::Quux
Bar::Quux
Foo
Sub::Multi::Tiny::Dispatcher::
For extra debug output, set "$VERBOSE" in Sub::Multi::Tiny::Util to a positive integer. This has to be set at compile time to have any effect. For example, before creating any multisubs, do:
use Sub::Multi::Tiny::Util '*VERBOSE'; BEGIN { $VERBOSE = 2; }
To be able to use multisubs in pre-5.14 Perls with only built-in language facilities. This will help me make my own modules backward compatible with those Perls.
To learn how it's done! :)
I looked at these but decided not to use them for the following reasons:
I wanted a syntax that used normal sub definitions as much as possible. Also, I was a bit concerned by LPALMER's experience that it "does what you don't want sometimes without saying a word" ("Semantics" in Class::Multimethods::Pure).
Other than that, I think this looks pretty decent (but haven't tried it).
Same desire for sub syntax. Additionally, the last update was in 2007, and the maintainer hasn't uploaded anything since. Other than that, I think this also looks like a decent option (but haven't tried it).
This is a full object system, which I do not need in my use case.
This one is fairly clean, but uses a source filter. I have not had much experience with source filters, so am reluctant.
Requires Perl 5.14+.
I am not ready to move to full Moose!
As above.
The original inspiration for this module, whence this module's name. Sub::Multi uses coderefs, and I wanted a syntax that used normal sub definitions as much as possible.
Sub::Multi
This one looks very interesting, but I haven't used smartmatch enough to be fully comfortable with it.
You can find documentation for this module with the perldoc command.
perldoc Sub::Multi::Tiny
You can also look for information at:
GitHub: The project's main repository and issue tracker
https://github.com/cxw42/Sub-Multi-Tiny
MetaCPAN
Sub::Multi::Tiny
This distribution
See the tests in the t/ directory distributed with this software for usage examples.
t/
It's not as tiny as I thought it would be!
This isn't Damian code ;) .
Chris White <cxw@cpan.org>
Copyright (C) 2019 Chris White <cxw@cpan.org>
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
To install Sub::Multi::Tiny, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Sub::Multi::Tiny
CPAN shell
perl -MCPAN -e shell install Sub::Multi::Tiny
For more information on module installation, please visit the detailed CPAN module installation guide.