Most operations with Junctions produce Junctions. > 1 + any(2, 3) any(3, 4)
> any(1, 2) + 3 any(4, 5) > any(<ab cd>) ~~ /./ any(「a」, 「c」) In the case of the following line, `$/` gets assigned a junction of the results. > if any(@genus) ~~ m/Hama/ { put "Matches at least one again"; }; The `m/Hama/` is executing early in the smartmatch `~~`. Really you should have been using `rx/Hama/` or `/Hama/` instead. > any(<ab cd>) ~~ m/./ False `m//` always executes against `$_`. While `rx//` always evaluates to the regex itself. (`/…/` will do one or the other depending on context.) So there are some places where `m//` appears to wait to execute like the following line. > 'abc' ~~ m/b/ It doesn't wait. It executes immediately. The reason is that smartmatch is actually a two step process. The above example is basically short for the following line: > (do given 'abc' { m/b/ }).ACCEPTS('abc') Now I am going to simplify it. The `m/b/` executes immediately. > (do given 'abc' { 「b」 }).ACCEPTS('abc') > ( 「b」 ).ACCEPTS('abc') Since `.ACCEPTS` on an instance of Match always returns itself, the above returns the Match object. It would operate differently, but come to the same result with `rx//`. > (do given 'abc' { rx/b/ }).ACCEPTS('abc') > ( rx/b/ ).ACCEPTS('abc') Since `rx/b/` does indeed accept 'abc' the end result of the above line is the Match object 「b」. In the case of a Junction, the `~~` applies to each part of the junction separately, and then combines the results. So `$/` gets assigned a Junction rather than the normal Match. (Which means `m//` and `rx//` do not come to the same result.) If the book says that `@genus ~~ m/Hama/` and `any(@genus) ~~ m/Hama/` are exactly the same, it is incorrect. The first sets $/ and returns the first value that returns a True value. While the second returns True and sets $/ to a Junction of all the results. Then later when you do just `m//` it tries to assign to each value in the Junction to the new result. Since the junction contains immutable values, that doesn't work. > $_ = 'abc'; > $/ = any 'def', 'ghi'; > m/abc/ Cannot modify an immutable Str (def) in block <unit> at <unknown file> line 1 Basically when `m//` tries to do `$/ = …` it threads through the Junction rather than just assigning directly to `$/`. It is a bug in the assignment code that m// uses. When submitting a bug report, it is best to reduce the problem to the simplest example that still produces the error. The last example here does just that. This is a compiler / runtime issue. The compiler's name is Rakudo, so the appropriate repository would be https://github.com/rakudo/rakudo. Since you found the issue, I think you should create the issue in the bug tracker. (Mainly because that is a common first stepping stone to getting involved.) On Tue, Oct 8, 2019 at 2:53 AM William Michels via perl6-users < perl6-us...@perl.org> wrote: > Greetings: > > I tried the following regular expression code, working generally from > "Learning Perl 6" by brian d foy (Chapter 15). Everything works fine > including the any() junction below, as long as the topic $_ variable > isn't defined beforehand. However specifically in combination with a > user-defined $_ topic variable, an any() junction returns the error, > "Cannot modify an immutable Match." See Perl6 REPL code below (also > checked with 6Pad (https://perl6.github.io/6pad/)) : > > mbook:~ homedir$ perl6 > To exit type 'exit' or '^D' > > $_ = 'Hamadryas'; > Hamadryas > > my @genus = < Hamadryas Sostrata Junonia >; > [Hamadryas Sostrata Junonia] > > say $_.WHAT, $/.WHAT; > (Str)Nil > > if @genus ~~ m/Hama/ { put "Matches at least one"; }; > Matches at least one > > say $_.WHAT, $/.WHAT; > (Str)(Match) > > say m/Hama/; > 「Hama」 > > say m/Hama/; > 「Hama」 > > say $_.WHAT, $/.WHAT; > (Str)(Match) > > if any(@genus) ~~ m/Hama/ { put "Matches at least one again"; }; > Matches at least one again > > say $_.WHAT, $/.WHAT; > (Str)(Junction) > > say m/Hama/; > Cannot modify an immutable Match (「Hama」) > in block <unit> at <unknown file> line 1 > > > say $*VM > moar (2019.07.1) > > > > I understood from the "Learning Perl 6" book that the two smart-match > lines of code are equivalent--the first one simply understands that > there is an 'implied' any() junction to check the array against the > match operator. But REPL reports back that in one case $/ returns a > match object type, while in the other case [with an explicit any() > junction], $/ returns a junction object type. So this feels > inconsistent, at the very least. > > Any explanation appreciated. If after triaging this issue, someone > would like me to open a Github issue, please point me towards the > correct repository. > > Thanks, Bill. > > W. Michels, Ph.D. >