03:48 runesicle joined 03:57 runesicle left 07:06 sibl joined 07:48 sibl left, sibl joined 08:03 dakkar joined 08:04 sibl left, sibl joined 13:05 sibl left, sibl joined 14:21 sibl left 16:31 dakkar left 17:14 runesicle joined 18:24 david7832 joined 18:27 sibl joined 19:48 sibl left
david7832 I have two multis. One multi accepts a Scalar parameter, the other a Positional. When the argument is a Positional in Scalar context (e.g. $[1,2,3]), it is still the "positional" multi that gets called, even though I would like the scalar multi to be called instead. How can I achieve this? In other words: The "positional" sub should only be called 20:21
for a listy argument in listy context.
multi sub e($a) { # scalar };
multi sub e(@a) { # positional }
m: multi sub e($a) { say "scalar" }; multi sub e(@a) { say "positional" }; say e($[1,2,3]) 20:23
camelia positional
True
librasteve_ david7832: please can you offer a code example of what you are trying to do? 20:46
david7832 I'm building some routines for to escape strings/add quotes. For lists, I want the option to either have each element wrapped in its own pair of quotes, or have the entire list stringified as one thing and wrapped in a single pair of quotes. The container type (Array vs Scalar) might be one way to decide between these options. 20:54
multi sub esc($a) { '"' ~ $a ~ '"' }
multi sub esc(@a) { do '"' ~ $_ ~ '"' for @a}
esc([1,2,3])  # should return ("1", "2", "3") and does so
esc($[1,2,3]) # should return "(1, 2, 3)" but also returns ("1", "2", "3")
librasteve_ tx 21:01
david7832 Seems that making the second signature `@a is raw` could be a solution. It doesn't change the multi that's called, that's still the @a-multi for either argument, but it makes this multi treat $[1,2,3] as a single element: 21:16
m: multi sub esc(@a is raw) { say "got @"; return do '"' ~ $_ ~ '"' for @a};  say esc([1,2,3]); say esc($[1,2,3])
camelia got @
("1" "2" "3")
got @
("1 2 3")
disbot2 <librasteve> hmm - I admit to being stumped - I guess is raw sidesteps some of the confusion between containers and var binding in a capture 21:29
<librasteve> best I can do is #multi sub esc($a is raw where $a.VAR.^name eq 'Scalar') { 'scalar' } 21:30
<librasteve> not very impressive (although I think you are swimming against the stream of containers being invisible in general code) 21:31
<librasteve> I suspect someone will come along shortly and tell me what I missed
david7832 Thank you very much for your efforts, though. I'll ask folks in the main channel to also look at this 22:01
22:05 [Coke] joined
[Coke] m: $[1,2,3].WHAT.say 22:06
camelia (Array)
disbot2 <librasteve> =b 22:10
david7832 As for why things work as they do, with the multis above, I guess the description goes like:
A multi with signature (@a) has higher priority than that with ($a), and it will match any thing doing Positional role; if it's in a scalar container, it will just be forced into @a and thereby made positional. For example, $[1,2,3] becomes [1,2,3].
In contrast, the signature (@a is raw) keeps the original container, so that within the function body, the argument $[1,2,3] will still be $[1,2,3] (i.e. [1,2,3] in a scalar context), while the argument [1,2,3] will still be [1,2,3] (i.e. [1,2,3] in an array context).
For convenience when reading the logs: timo suggested in #raku to use a slurpy with signature (*@a), which works out very well – irclogs.raku.org/raku/2026-04-02.html#22:02 23:40
23:40 david7832 left 23:53 runesicle left