Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception thrown when adding an element into a SetHash declared as "state %set is SetHash[Str]" inside a loop

Tags:

raku

sethash

Adding a Str element into a SetHash declared as state %set is SetHash[Str] inside a loop throws an exception:

Cannot resolve caller STORE(SetHash[Str]:U: SetHash[Str]:D); none of these signatures match:

(SetHash:D: *@pairs, *%_ --> SetHash:D)

(SetHash:D: \objects, \bools, *%_ --> SetHash:D)

(QuantHash:D: |)

When declared before the loop as my %set is SetHash[Str] the same code works just fine.

According to https://docs.raku.org/type/SetHash#Creating_SetHash_objects :

...

Since 6.d (2019.03 and later) it is also possible to specify the type of values you would like to allow in a SetHash.

This can either be done when calling .new:

#only allow Pairs

my $n = SetHash[Pair].new: "zero" => 0, "one" => 1, "two" => 2;

or using the masquerading syntax:

#only allow strings

my %sh is SetHash[Str] = <a b c>;

say %sh<a>; # True

say %sh<d>; # False

...

When the HashSet is declared the former way (%set = SetHash[Str].new) it works as expected (before or inside the loop). The problem emerges just with the latter.

What works:

use v6.d;

my @list = 'aaa' .. 'ddd';

my %set is SetHash[Str];

for @list {
    %set{$_}++ if m/a.*a/;

    LAST {
        put %set.elems;
    }
}
#outputs 10

What doesn't:

use v6.d;

my @list = 'aaa' .. 'ddd';

for @list {
    state %set is SetHash[Str];

    %set{$_}++ if m/a.*a/;

    LAST {
        put %set.elems;
    }
}
#outputs the exception

Why is that? Is this a bug?

(tested with the same results on Rakudo 2019.07.1 and 2019.03)

like image 949
850 Avatar asked Aug 08 '19 10:08

850


1 Answers

There's something up with is Foo on a state declaration.

See, for example [BUG] state with % is SetHash ends up with a type object on second entry to block.

I recall also having to write:

my @array is BigArray;
proto A(Int \𝑚, Int \𝑛) { @array[𝑚][𝑛] //= {*} }

instead of

proto A(Int \𝑚, Int \𝑛) { (state @array is BigArray)[𝑚][𝑛] //= {*} }

a while back, so I think there's something more general than just SetHashs.

like image 127
raiph Avatar answered Jan 03 '23 12:01

raiph