Can I choose between Perl 6 multis that have no parameters?
Asked Answered
M

2

7

I can choose a multi based on some non-argument value but I have to have at least one argument so I can kludge the where in there:

our $*DEBUG = 1;
debug( 'This should print', 'Phrase 2' );

$*DEBUG = 0;
debug( 'This should not print' );

multi debug ( *@a where ? $*DEBUG ) { put @a }
multi debug ( *@a where ! $*DEBUG ) { True }

I seem to recall some trick someone used to dispatch among multis that took exactly no parameters. For example, I have a show-env routine I'd like to sprinkle around and that only does anything if I've set some debugging conditions. I could achieve it like I've shown but that's not very satisfying and it's not the clever thing I imagine I saw elsewhere:

our $*DEBUG = 1;
debug( 'This should print', 'Phrase 2' );
show-env();

$*DEBUG = 0;
debug( 'This should not print' );
show-env();

multi debug ( *@a where ? $*DEBUG ) { put @a }
multi debug ( *@a where ! $*DEBUG ) { True }

# use an unnamed capture | but insist it has 0 arguments
multi show-env ( | where { $_.elems == 0 and ? $*DEBUG } ) { dd %*ENV }
multi show-env ( | where { $_.elems == 0 and ! $*DEBUG } ) { True }

I could do something similar with optional named parameters but that's even less satisfying.

Of course, I could do just this in this simple example but this is no fun:

sub show-env () {
    return True unless $*DEBUG;
    dd %*ENV;
    }
Mcalister answered 1/1, 2018 at 19:49 Comment(0)
B
7

You could destructure the | with ().

my $*DEBUG = 1;
show-env();

$*DEBUG = 0;
show-env();

# use an unnamed capture | but insist it has 0 arguments by destructuring
multi show-env ( | ()   where ? $*DEBUG ) { dd %*ENV }
multi show-env ( | ()   where ! $*DEBUG ) { True }

show-env(42); # Cannot resolve caller show-env(42); …

Or you could have a proto declaration

proto show-env (){*}
multi show-env ( |      where ? $*DEBUG ) { dd %*ENV }
multi show-env ( |      where ! $*DEBUG ) { True }

show-env(42); # Calling show-env(Int) will never work with proto signature () …
Boomkin answered 1/1, 2018 at 20:9 Comment(0)
S
7

A more elegant way to insist that the capture is empty is to specify it with an empty sub-signature:

multi show-env ( | () where ? $*DEBUG ) { dd %*ENV }
multi show-env ( | () where ! $*DEBUG ) { True }
Solifidian answered 1/1, 2018 at 20:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.