'Substitution in grammar action code throwing bizarre "P6opaque" error

I have this action which overrides an action in another action class:

        method taskwiki-prefix($/ is copy) {
            my $prefix = $/.Str;
            $prefix ~~ s:g!'|'!!;
            make $prefix;
        }

The substitution throws this error:

P6opaque: no such attribute '$!made' on type Match in a List when trying to bind a value

If I comment out the substitution, the error goes away. dd $prefix shows:

Str $prefix = " Tasks ||"

So it's just a plain string.

If I remove the :g adverb, no more error, but doing that makes the made value Nil and nothing shows up in the output for $<taskwiki-prefix>.made.

Looks to me like there is some bad interaction going on with the matches in the substitution and the action, if I were to guess.

Any fix?



Solution 1:[1]

This is another case of your previous question, Raku grammar action throwing "Cannot bind attributes in a Nil type object. Did you forget a '.new'?" error when using "make". As there, the make function wants to update the $/ currently in scope.

Substitutions update $/, and:

  • In the case of the :g adverb, a List ends up in $/, and make gets confused. I've proposed an improved error.
  • In the case of no :g, there is a Match in $/ and it is attached to that - however, it's no longer the Match object that was passed into the method

I recommend to:

  1. Always have the signature of your action methods be ($/), so there's no confusion about the target of make.
  2. When possible, avoid reparsing (which was the achieved solution mentioned in your own answer).
  3. If you can't avoid doing other matches or substitutions in your action method, put them in a sub or private method instead and then call it.

Solution 2:[2]

Problem was solved by changing the the grammar to give me a cleaner output so I did not have to manipulate the $/ variable.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jonathan Worthington
Solution 2 StevieD