in reply to HOA with array slice?

my ($color, $fruit) = ( $hoa->{keytwo}->[$idx_color], $hoa->{keytwo}->[$idx_fruit] );

is equivalent to

my $aref = $hoa->{keytwo}; my ($color, $fruit) = ( ${$aref}[$idx_color], ${$aref}[$idx_fruit] );

Since you're dealing with one array (@{$aref}), yes, you can use a slice:

my $aref = $hoa->{keytwo}; my ($color, $fruit) = @{$aref}[$idx_color, $idx_fruit];

or back in one line:

my ($color, $fruit) = @{$hoa->{keytwo}}[$idx_color, $idx_fruit];

Notice I used <sigil>{$aref}. I did so because it parallels <sigil>array exactly. $aref->[] is a shortcut for ${$aref}[] exclusively, so it's useless when dealing with array slices.

Update: oh, I forgot to answer the second question! There's nothing wrong with HoA in general. In your situation, a hash would work nicely since you're naming your parameters anyway.

If you go with hashes, you can take hash slices:

my ($color, $fruit) = @{$hoa->{keytwo}}{'color', 'fruit'};

If you go with arrays, why not use constants to speed things up slightly:

sub IDX_COLOR () { 0 } sub IDX_FRUIT () { 1 } my ($color, $fruit) = @{$hoa->{keytwo}}[IDX_COLOR, IDX_FRUIT];

or

use constant IDX_COLOR => 0; use constant IDX_FRUIT => 1; my ($color, $fruit) = @{$hoa->{keytwo}}[IDX_COLOR, IDX_FRUIT];

The combination of the empty prototype and the constant value being returned makes IDX_COLOR and IDX_FRUIT constants rather than functions.