How can you assign values to a Hash key without concomitant boxing (i.e. itemization)?

Assuming you don't need mutation afterwards, use a Map instead of a Hash.

my %syns-by-name is Map = Bq => ("Bq", "becquerel", "becquerels");
my Str @syns = %syns-by-name<Bq>;
say @syns; # [Bq becquerel becquerels]

Since there's no expectation that entries in a Map are assignable, it doesn't create Scalar containers for the values.


How about:

role deconting {
    method AT-KEY(\key) {
        callsame<>
    }
}
my %h does deconting = a => <a b c>;
dd $_ for %h<a>;  # "a"␤"b"␤"c"␤

This makes sure that the hash that does the "deconting" role will always return whatever is in the hash decontainerized.

Making it decontainerized on assignment can also be done, but is a lot more tricky as that would need tweaking of at least two methods: STORE and ASSIGN-KEY.


Despite the excellent answers from @Jonathan_Worthington and @Elizabeth_Mattijsen, I wanted to post the code below, which utilizes simple decontainerization:

~$ raku
Welcome to ™ v2020.10.
Implementing the ™ programming language v6.d.
Built on MoarVM version 2020.10.

To exit type 'exit' or '^D'
> my %syns-by-name =  Bq => ("Bq", "becquerel", "becquerels");
{Bq => (Bq becquerel becquerels)}
> my Str  @syns = %syns-by-name<Bq>;
Type check failed in assignment to @syns; expected Str but got List (("Bq", "becquerel", ...)
  in block <unit> at <unknown file> line 1

> my Str  @syns = %syns-by-name<Bq>[];
[Bq becquerel becquerels]
>

I gather there is an academic question here as to how the variable is defined versus how the values of the variable are accessed. However I don't want a casual reader to conclude that Raku is lacking functionality vis-à-vis hashes and lists.

> my %syns-by-name  = Bq => ("Bq", "becquerel", "becquerels");
{Bq => (Bq becquerel becquerels)}
> dd $_ for %syns-by-name<Bq>[]
"Bq"
"becquerel"
"becquerels"
Nil
> my $list = <C coulomb coulombs>;
(C coulomb coulombs)
> say $list.WHAT
(List)
> %syns-by-name<C> = $list
(C coulomb coulombs)
> dd $_ for %syns-by-name<C>[]
"C"
"coulomb"
"coulombs"
Nil
>

I hope this answer isn't superfluous and casual readers will benefit. Thank you.

Tags:

Syntax

Raku