A hash, by default, converts all keys to strings. This causes issues when your keys are numbers which may be close:
> my %h; %h{1/3} = 1; %h{0.333333} = 2; dd %h;
Hash %h = {"0.333333" => 2}
This can, of course, be fixed as follows:
> my %h{Real}; %h{1/3} = 1; %h{0.333333} = 2; dd %h;
Hash[Any,Real] %h = (my Any %{Real} = 0.333333 => 2, <1/3> => 1)
But now I need a hash of hashes of numbers, e.g. { 1/3 => { 2/3 => 1, 0.666667 => 2 } }
.
> my %h{Real}; %h{1/3}{2/3} = 1; %h{1/3}{0.666667} = 2; dd %h;
Hash[Any,Real] %h = (my Any %{Real} = <1/3> => ${"0.666667" => 2})
How do I fix that?
Best I can figure out is the following workaround:
> my %h{Real}; %h{1/3} //= my %{Real}; %h{1/3}{2/3} = 1; %h{1/3}{0.666667} = 2; dd %h;
Hash[Any,Real] %h = (my Any %{Real} = <1/3> => $(my Any %{Real} = <2/3> => 1, 0.666667 => 2))
but that's just annoying.
The following works:
my Hash[Real,Real] %h{Real};
%h{1/3} .= new;
%h{1/3}{2/3} = 1;
Which is not great.
The following also works as a work-around.
my Hash[Real,Real] %h{Real};
%h does role {
method AT-KEY (|) is raw {
my \result = callsame;
result .= new unless defined result;
result
}
}
%h{1/3}{2/3} = 1;
say %h{1/3}{2/3}; # 1
If you have more than one such variable:
role Auto-Instantiate {
method AT-KEY (|) is raw {
my \result = callsame;
result .= new unless defined result;
result
}
}
my Hash[Real,Real] %h{Real} does Auto-Instantiate;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With