cale2 asked a hard question
Today cale2 refused to asked an easy question. Let’s start with his hard question.
<cale2> I need a tutorial on * vs $_ vs $
What is a fairly good question to ask. Those three things are syntactic sugar that can help a great deal to keep lines from wrapping, allowing for less bugs because of context switching.
Let’s start with our good old friend the topic called $_
. In Perl 5 it just appeared out of nowhere in every sub
. In Perl 6 it appears out of a default for blocks.
my &block = { 'oi‽' }; &block.signature.say; # OUTPUT«(;; $_? is raw)»
The default signature for a block is one positional parameter called $_ So every block has one. There are further statements that set the topic without introducing a new block like with
and given
(given does introduce a block but it’s special and I wont provide details here).
say $_ with 42; # OUTPUT«42»
Since it’s the default Perl 6 will expect it at quite a few places. Most prominent is when
and the objectless method call.
$_ = 42; say 'oi‽' when 42; .say; # OUTPUT«oi‽42»
A lone $
is actually two (and a bit) things. In a Signature
it’s a marker for a positional parameter that we can never use (maybe because we don’t care) because it didn’t got a name and therefor doesn’t introduce a symbol in the Routine
it applies to. It is useful for protos and free floating Signatures
. It’s second use actually introduces a container, again without a symbol. It’s also a state variable whereby it’s initialiser (if there is one) is not handled as state and will be called more then once. We can use the anonymous state variable to count things.
my @a = <a b c d>; for @a { say @a[$++] }; # OUTPUT«abcd»
We can abuse an anonymous $
to skip values in list assignment. Quite handy when we got a short list returned from a routine.
my ($,$,$c) = <a b c d>; say $c; # OUTPUT«c»
I like the fact that I don’t have to come up with names for one-shot-variables. The less cognitive load the better.
The Whatever
* is the hard part of the question. At times it’s a syntactic sugar marker that we use to tell Perl 6 that we don’t care what will be picked. At other times it means Inf
in the sense of All Of Them.
my @a = <a b c d>; put @a.pick(*); # OUTPUT«c d b a»
If a lone * is used in an argument list it’s turned into the singleton Whatever
. Since we can asked for values in signatures we can provide interfaces for multies where the user can state a lack of care.
multi sub foo(Int $i){ $i * 42 }; multi sub foo(Whatever){ <42 oi‽ ♥>.pick }; say foo(*); # OUTPUT«♥» (your results may vary)
If we use * in a statement that involves operators or calls, it forms a block without a scope and acts like a placeholder variable, without losing the information that this block was spawned by a *. The type of the resulting Callable
is WhateverCode
and a routine could act on it differently then when provided with Sub
or Method
. Quite in contrast to a real placeholder variable Whatever
can be used in a where
-clause.
sub foo($a where * < 10){}
This is not a complete answer to his question and that’s why I would like to suggest to cole2 to read the *beep*ing docs.