Skip to content
Multisub/multimethod (multiple-dispatch subroutine) implementation for Perl
Perl
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
lib
support
t
xt
.editorconfig
.gitignore
.mailmap
.travis.yml
Build.PL
Changes
LICENSE
META.json
README.md
cpanfile
minil.toml

README.md

Build Status

NAME

Sub::Multi::Tiny - Multisubs/multimethods (multiple dispatch) yet another way!

SYNOPSIS

{
    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

Limitation: At present, dispatch is solely by arity, and only one candidate can have each arity. This limitation will be removed in the future.

DESCRIPTION

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.

Within a multisub package, the name of the sub being defined is available for recursion. For example (using where, not yet implemented):

{
    package main::fib;
    use Sub::Multi::Tiny qw($n);
    sub base  :M($n where { $_ eq 0 })  { 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!

FUNCTIONS

import

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.

A parameter D:Dispatcher can also be given to specify the dispatcher to use. If Dispatcher includes a double-colon, it will be used as a full package name. Otherwise, Sub::Multi::Tiny::Dispatcher:: will be prepended.

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.

CUSTOM DISPATCH

This module includes a default dispatcher (implemented in Sub::Multi::Tiny::DefaultDispatcher. 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:

{
    package main::foo;
    use Sub::Multi::Tiny;
    sub MakeDispatcher { return sub { ... } }
}

or

{
    package main::foo;
    use Sub::Multi::Tiny;
    use APackageThatImportsMakeDispatcherIntoMainFoo;
}

DEBUGGING

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; }

RATIONALE

  • 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! :)

SEE ALSO

I looked at these but decided not to use them for the following reasons:

  • Class::Multimethods

    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).

  • Class::Multimethods::Pure

    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).

  • Dios

    This is a full object system, which I do not need in my use case.

  • Logic

    This one is fairly clean, but uses a source filter. I have not had much experience with source filters, so am reluctant.

  • Kavorka::Manual::MultiSubs (and Moops)

    Requires Perl 5.14+.

  • MooseX::MultiMethods

    I am not ready to move to full Moose!

  • MooseX::Params

    As above.

  • Sub::Multi

    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::SmartMatch

    This one looks very interesting, but I haven't used smartmatch enough to be fully comfortable with it.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc Sub::Multi::Tiny

You can also look for information at:

BUGS

This isn't Damian code ;) .

AUTHOR

Chris White cxw@cpan.org

LICENSE

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.

You can’t perform that action at this time.