StevieD
StevieD

Reputation: 7443

How do I mutate captures in a Grammar object?

I'm trying to modify the values in a parsed Grammar object with this:

method mutate(Match:D $match --> Match:D) {
    for $match.values -> $line {
        when $line<content><header-toc><header><taskwiki-content><taskwiki-divider> {
            say 'here';
            $line<content><header-toc><header><taskwiki-content><taskwiki-divider>.replace-with('');
            say $line; # has not been modified;
        }
    };
    return $match;
}

I'm not getting any errors but the $match object is not affected by the replace-with method I'm running.

Upvotes: 3

Views: 125

Answers (1)

raiph
raiph

Reputation: 32414

How do I mutate captures in a Grammar object?

You can't. (Well, you can hang data off them via make, but you can't do what you're thinking you can do.)


A Match object stores the result of a match against some string, and any captures are just .from, .to indexes into that original string.

For example, if you write "bar".match(/a/), the resulting Match object stores the .match method's invocant "bar", and has a .from of 1 and a .to of 2 which represents the captured "a" substring.

The original string remains immutable, and the captured substrings are "virtual" as it were, with nothing you can mutate.


foo.replace-with('');

replace-with does not modify its invocant. It just returns a value (a new string).

Quoting the replace-with doc, with my added bold emphasis:

Returns the invocant string where the Match object is replaced by $replacement.

Note that it's not "the invocant Match object".

The .replace-with method is returning a new string that's a copy of the original input string that was matched against to produce the Match object, with the bit that was matched replaced by the string supplied as the .replace-with method's argument.

Upvotes: 4

Related Questions