class CaseInsensitiveHash does Associative does Iterable {
has %!keys is default(Str);
has %!values handles <elems list Seq iterator keys values pairs antipairs Str gist raku perl>;
method STORE(::?CLASS:D: Mu $topic is raw, |rest) is raw {
my %topic.STORE: $topic, |rest;
%!keys.STORE: %topic.keys.map({ $^k.lc => $^k }), |rest;
%!values.STORE: %topic, |rest
}
method AT-KEY(::?CLASS:D: Str(Any) $key, |rest) is raw {
%!values.AT-KEY: (%!keys.AT-KEY: $key.lc, |rest orelse $key), |rest
}
method EXISTS-KEY(::?CLASS:D: Str(Any) $key, |rest) is raw {
%!keys.EXISTS-KEY: $key.lc, |rest
}
method BIND-KEY(::?CLASS:D: Str(Any) $key, |rest) is raw {
self.DELETE-KEY: my $lc := $key.lc;
%!values.BIND-KEY: (%!keys.ASSIGN-KEY: $lc, $key), |rest
}
method ASSIGN-KEY(::?CLASS:D: Str(Any) $key, |rest) is raw {
self.DELETE-KEY: my $lc := $key.lc;
%!values.ASSIGN-KEY: (%!keys.ASSIGN-KEY: $lc, $key), |rest
}
method DELETE-KEY(::?CLASS:D: Str(Any) $key, |rest) is raw {
%!values.DELETE-KEY: (%!keys.DELETE-KEY: $key.lc, |rest orelse $key), |rest
}
}
my %received = bLa => 1, BLE => 2, bli => 3;
my %ci-hash is CaseInsensitiveHash = %received;
say %ci-hash<bla>;
say %ci-hash<ble>;
say %ci-hash<bla ble bli>;
say %ci-hash<BlA bLe BLI>;
dd %ci-hash;
%ci-hash<AAA> = 42;
%ci-hash<bBb> = 13;
%ci-hash<BBB> = 3.14; # overrides bBb
dd %ci-hash;
say %ci-hash.keys;
say %ci-hash.values;
say %ci-hash.pairs;
#`[OUTPUT:
1
2
(1 2 3)
(1 2 3)
(AAA BLE BBB bLa bli)
(42 2 3.14 1 3)
(AAA => 42 BLE => 2 BBB => 3.14 bLa => 1 bli => 3)
]