On Fri, Nov 19, 2021 at 1:19 AM Marc Chantreux <e...@phear.org> wrote:
>
>     method col:sym<quoted> ($/) { make S:g/'""'/'"'/ with ~$/ }
>
>     Cannot assign to a readonly variable or a value
>
> why isn't it working?

1. Even though `S` politely leaves "the current topic" (`$_`)
alone, it still generates a match object, and then binds that
to "the current match object" (`$/`).

2. In your method's signature you include `$/` as a parameter.
Like all such parameters, it defaults to being a read-only one.

See also:

* https://stackoverflow.com/questions/40970080/
perl6-rakudo-2016-11-match-tries-to-assign-to-read-only-variable-why-not-in-201

* https://github.com/rakudo/rakudo/issues/1235

> how to fix it

I'm not saying the following is how to fix it. But I'll show
code that works for your example.

The key thing is that, if you're going to use `S///`, you
need to deal with the fact it will overwrite `$/`.

Note that the answer is NOT to make the `$/` parameter
writable using `is copy` or `is rw`. The first argument that
is passed to a method in an actions class is the match
object that's just been matched. And you need that so
you can hang some data off of it using `make`. You do
not want it clobbered!

Here's what I suggest you consider:

    method col:sym<quoted> ($_) { .make: S:g/'""'/"/ }

What I've done here is to switch from `$/` to `$_`. This:

* Frees up `$/`. So the `S///` can now clobber it.

* Means I have to write `.make:` instead of `make`.

I could have changed the `with ~$/` to `with ~$_` but
it's already the topic (and gets coerced to a string).

> am I right when i feel there is a way to do this
> substitution inside the grammar

As I've shown, yes. But it draws you into the `$/` dance.

> is it a good idea?

First, in a comment in the issue I linked above, jnthn writes:

> using subst [ or `S///`] inside of an action method would
imply re-parsing, which one should think twice about anyway.

Second, I've no idea where the `$/` that `S///` clobbers comes from.

If we could confirm what I wrote is safe, then perhaps it's one
appropriate idiomatic response to the issue.

If not, the following clumsy solution might be the way to go:

    method col:sym<quoted> ($_) { my $/; .make: S:g/'""'/"/ }

--
love, raiph

Reply via email to