Skip Menu |
Report information
Id: 131599
Status: open
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: perl6 [at] mscha.org
Cc:
AdminCc:

Severity: (no value)
Tag: (no value)
Platform: (no value)
Patch Status: (no value)
VM: (no value)



From: Michael Schaap <perl6 [...] mscha.org>
Date: Sun, 18 Jun 2017 23:52:31 +0200
To: rakudobug [...] perl.org
Subject: [BUG] "my %hash is default([])" misbehaves
Download (untitled) / with headers
text/plain 704b
#!/usr/bin/env perl6 my %sum{Int} is default([]); %sum{4}.push: "1+3"; %sum{4}.push: "2+2"; say (1..10).grep(-> $i { %sum{$i} == 2 }); # Expected output: (4) # Actual output: (1 2 3 4 5 6 7 8 9 10) %sum{3}.push: "1+2"; say (1..10).grep(-> $i { %sum{$i} == 2 }); # Expected output: (4) # Actual output: () say %sum; # Expected output: {3 => [1+2], 4 => [1+3 2+2]} # Actual output: {} say %sum{4}; # Expected output: [1+3 2+2] # Actual output: [1+3 2+2 1+2] # Without "is default([])" it works fine, except that the "grep" complains # (rightly) about uninitialized values. # % perl6 --version # This is Rakudo version 2017.04.3 built on MoarVM version 2017.04-53-g66c6dda # implementing Perl 6.c.
From: Brad Gilbert <b2gills [...] gmail.com>
Date: Mon, 19 Jun 2017 11:30:12 -0500
Subject: Re: [perl #131599] [BUG] "my %hash is default([])" misbehaves
To: perl6-compiler [...] perl.org
Download (untitled) / with headers
text/plain 1.9k
There does appear to be a bug, but I'd argue that it is in your code. my %sum{Int} is default([]); That line of code sets the default for all elements when they are first accessed to the very same instance of an Array. Remove the `is default([])` To stop the warnings that would then happen you could use `andthen` say (1..10).grep(-> $i { %sum{$i} andthen $_ == 2 }); Or you could use `.elems` say (1..10).grep(-> $i { %sum{$i}.elems == 2 }); The way Moose in Perl 5 works around this is to give it a subroutine that will produce the value to set it to then rather than a value. (slight simplification) Basically Perl 6 dutifully did what you asked it to, and there currently isn't as far as I know, a way to do what you intended. So this isn't really a bug report, but a feature request. The new feature may very well use the same syntax you have provided. On Sun, Jun 18, 2017 at 4:52 PM, Michael Schaap <perl6-bugs-followup@perl.org> wrote: Show quoted text
> # New Ticket Created by Michael Schaap > # Please include the string: [perl #131599] > # in the subject line of all future correspondence about this issue. > # <URL: https://rt.perl.org/Ticket/Display.html?id=131599 > > > > #!/usr/bin/env perl6 > > my %sum{Int} is default([]); > %sum{4}.push: "1+3"; > %sum{4}.push: "2+2"; > > say (1..10).grep(-> $i { %sum{$i} == 2 }); > # Expected output: (4) > # Actual output: (1 2 3 4 5 6 7 8 9 10) > > %sum{3}.push: "1+2"; > > say (1..10).grep(-> $i { %sum{$i} == 2 }); > # Expected output: (4) > # Actual output: () > > say %sum; > # Expected output: {3 => [1+2], 4 => [1+3 2+2]} > # Actual output: {} > > say %sum{4}; > # Expected output: [1+3 2+2] > # Actual output: [1+3 2+2 1+2] > > # Without "is default([])" it works fine, except that the "grep" complains > # (rightly) about uninitialized values. > > # % perl6 --version > # This is Rakudo version 2017.04.3 built on MoarVM version > 2017.04-53-g66c6dda > # implementing Perl 6.c.
From: Michael Schaap <perl6 [...] mscha.org>
Date: Mon, 19 Jun 2017 20:35:59 +0200
To: perl6-bugs-followup [...] perl.org
Subject: Re: [perl #131599] [BUG] "my %hash is default([])" misbehaves
Download (untitled) / with headers
text/plain 2.2k
Thanks for explaining, I see why it does what it does now, more or less. Using .elems is an elegant workaround. But if not a bug, I'd say it's at least an LTA; Rakudo should warn that you're shooting yourself in the foot. On 19-Jun-17 18:30, Brad Gilbert via RT wrote: Show quoted text
> There does appear to be a bug, but I'd argue that it is in your code. > > my %sum{Int} is default([]); > > That line of code sets the default for all elements when they are first accessed > to the very same instance of an Array. > > Remove the `is default([])` > > To stop the warnings that would then happen you could use `andthen` > > say (1..10).grep(-> $i { %sum{$i} andthen $_ == 2 }); > > Or you could use `.elems` > > say (1..10).grep(-> $i { %sum{$i}.elems == 2 }); > > The way Moose in Perl 5 works around this is to give it a subroutine that will > produce the value to set it to then rather than a value. (slight simplification) > > Basically Perl 6 dutifully did what you asked it to, and there currently > isn't as far as I know, a way to do what you intended. > > So this isn't really a bug report, but a feature request. > The new feature may very well use the same syntax you have provided. > > On Sun, Jun 18, 2017 at 4:52 PM, Michael Schaap > <perl6-bugs-followup@perl.org> wrote:
>> # New Ticket Created by Michael Schaap >> # Please include the string: [perl #131599] >> # in the subject line of all future correspondence about this issue. >> # <URL: https://rt.perl.org/Ticket/Display.html?id=131599 > >> >> >> #!/usr/bin/env perl6 >> >> my %sum{Int} is default([]); >> %sum{4}.push: "1+3"; >> %sum{4}.push: "2+2"; >> >> say (1..10).grep(-> $i { %sum{$i} == 2 }); >> # Expected output: (4) >> # Actual output: (1 2 3 4 5 6 7 8 9 10) >> >> %sum{3}.push: "1+2"; >> >> say (1..10).grep(-> $i { %sum{$i} == 2 }); >> # Expected output: (4) >> # Actual output: () >> >> say %sum; >> # Expected output: {3 => [1+2], 4 => [1+3 2+2]} >> # Actual output: {} >> >> say %sum{4}; >> # Expected output: [1+3 2+2] >> # Actual output: [1+3 2+2 1+2] >> >> # Without "is default([])" it works fine, except that the "grep" complains >> # (rightly) about uninitialized values. >> >> # % perl6 --version >> # This is Rakudo version 2017.04.3 built on MoarVM version >> 2017.04-53-g66c6dda >> # implementing Perl 6.c.
RT-Send-CC: perl6-compiler [...] perl.org
Download (untitled) / with headers
text/plain 423b
On Mon, 19 Jun 2017 09:30:41 -0700, brad wrote: Show quoted text
> Or you could use `.elems` > > say (1..10).grep(-> $i { %sum{$i}.elems == 2 });
PS: note that, as a general usecase, you also need a `:v` there. Otherewise you're .elems'ing an Any, which follows the anything-is-a-1-item-list rule and you end up with .elems being 1 for keys without values: my %h; say %h<meows>.elems 1 my %h; say %h<meows>:v.elems 0


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org