Perl6 grammar actions: it is impossible to do anything without using $ /

I wrote a test program, and now it seems that if I do not use $/ in because I have to use .match inside the method, I can not do anything for a long time. What have I done wrong?

One more question: if .match sets $/ and $/ is read-only, then I cannot have $/ in the signature of the method containing the .match instruction, and I cannot have more than one .match inside the method, because each .match will try to set read-only $/ . This will be very inconvenient for programming.

Here is a test program with only one .match expression inside and results:

Testing program:

 grammar test { regex TOP { <foo><bar> } regex foo { :i \s* foo \s* } regex bar { :i \s bar \s* } } class actTest { method foo ($x) { # program fails if I use $/ in signature print "1 "; say $x; # how to combine the 2 and show $x as match? print "2 "; say $x.WHAT; my $newStr = $x.Str; print "3 "; say $newStr; my $newMatch = $newStr.match(/:i(f)(oo)/); # adverb cannot be outside? print "4 "; say $newMatch.WHAT; print "5 "; say $newMatch; print "6 "; say $/; my $oo = $newMatch[1].Str; print "10 "; say $oo; my $f = $newMatch[0].Str; print "11 "; say $f; my $result = $oo ~ $f; print "12 "; say $result; make $result; # now I cannot make anything; huh??? } method TOP ($/) { print "8 "; say $<bar>; print "9 "; say $<foo>.made; # failed, method 'foo' makes nothing make $<bar> ~ $<foo>.made; } } my $m = test.parse("Foo bar", actions => actTest.new); print "7 "; say $m; 

And the results:

 1 「Foo 」 2 (Match) 3 Foo 4 (Match) 5 「Foo」 0 => 「F」 1 => 「oo」 6 「Foo」 0 => 「F」 1 => 「oo」 10 oo 11 F 12 ooF 1 「Foo」 2 (Match) 3 Foo 4 (Match) 5 「Foo」 0 => 「F」 1 => 「oo」 6 「Foo」 0 => 「F」 1 => 「oo」 10 oo 11 F 12 ooF 8 「 bar」 9 (Any) Use of uninitialized value of type Any in string context. Methods .^name, .perl, .gist, or .say can be used to stringify it to something meaningful. in method TOP at matchTest.pl line 28 7 「Foo barfoo => 「Foobar => 「 bar 
+6
source share
1 answer

1) How to make without $/

make ... is just a shortcut to $/.make(...) .

If you want to influence a different Match object than the one stored in $/ , you need to use the form of the method directly, i.e. in your case $x.make($result) .

2) When and why $/ is read-only

By default, $/ bound to the container of a normal element (for example, a variable declared with my ), i.e. not just for reading. Therefore, there should be no problem using the .match method several times in a subroutine.

This is only when you explicitly declare $/ as a parameter in the signature routine, that $/ will be bound directly to the Match object passed to this procedure (not wrapped in an element container), and thus will be read-only inside the routine - due to how normal signature binding works.

You can use the is copy flag to override the standard binding of the parameter as read-only, and force $/ is the container of the variable element inside the procedure:

 method foo ($/ is copy) { ... } 

Thus, using .match inside the routine will work and will store the new Match object in $/ . But then you will no longer have access to the original Match object passed to the procedure, and therefore, it will not be able to affect it with make . So for the action method that .match should use, using the name of the custom parameter, as you did, is the way to go.

+6
source

Source: https://habr.com/ru/post/1012983/


All Articles