Thank you very much Brad!! Let's redirect all conversation on this particular issue here:
https://github.com/rakudo/rakudo/issues/3221 Best Regards, Bill. On Tue, Oct 8, 2019 at 10:53 AM Brad Gilbert <b2gi...@gmail.com> wrote: > > 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.