In Perl to Raku guide - functions§
See primary documentation in context for wantarray.
wantarray
There is no wantarray
in Raku; however, there are very easy ways to cover many of the use cases which wantarray filled.
First, since Raku does not need special reference syntax to contain a List
or Array
in a Scalar
, simply returning a list may be all that is needed:
sub listofstuff { return 1, 2, 3; } my $a = listofstuff(); print $a; # OUTPUT: «1 2 3» print join("<", listofstuff()) # OUTPUT: «1<2<3»
One of the most common use cases is to provide either an array of lines or elements, or a prettier string than would be produced by simply printing the array. One can mix in a custom .Str
method for this purpose:
sub prettylist(*@origlist) { @origlist but role { method Str { self.join("<") } } } print prettylist(1, 2, 3); # OUTPUT: «1<2<3» print join(">", prettylist(3, 2, 1)); # OUTPUT: «3>2>1»
In the above example, the returned list may be lazy, and the .Str
method is not called until stringification happens, so no extra work is done to generate something which is not asked for.
Another use case is to create methods which are mutators when called in void context but produce copies during assignment. It is generally considered better form in Raku not to do so, even more so because void context does not exist in Raku, with the closest equivalent being sink context, since users can quite easily turn any copy-producing method into a mutator using the .=
operator:
my $a = "foo\n"; $a.ords.say; # OUTPUT: «(102 111 111 10)» $a .= chomp; $a.ords.say; # OUTPUT: «(102 111 111)»
However if you have your heart set on using the same function name for both operations, you can get most of the way there by mixing in a .sink
method, which will be called when the result finds itself in sink context. There are some caveats however, so again, this is not advised:
multi increment($b is rw) { ($b + 1) does role { method sink { $b++ } } } multi increment($b) { $b + 1 } my $a = 1; increment($a); say $a; # OUTPUT: «2» my $b = increment($a); say "$a $b"; # OUTPUT: «2 3» # ...users will just have to be aware that they should not accidentally # sink a stored value later, though this requires some effort to # actually do: sub identity($c is rw) { $c }; $a = 1; $b = increment($a); identity($b); $a.say; # OUTPUT: «2»