The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.




Store multiple keys in a hash in insertion order


        tie my %hash => 'Tie::MultiKeyInsertOrderHash';
        $hash{Say}="Hello World";

        while (my ($key, $value) = each (%hash)) {
                print "Action: $key Option: $value\n";
        print "I said: '", join ("' and '",@{$hash{Say}}),"'\n";
        print "I did: '", join ("' and '",@{$hash{Do}}),"'\n";

        print "The first thing I said was $hash{Say}->[0]\n";
        print "The last thing I said was $hash{Say}->[-1]\n";


        tie my %hash => 'Tie::MultiKeyInsertOrderHash',A,1,B,2,A,3,B,4; #Initial values.


To complete overwrite a value use:

        delete $hash{Value}

$hash{Value} will return an array of all values of that key; This won't work as you expect:

        foreach my $key (keys %hash) {
                print $key; #This will work and print the key in the right order, but the key will be printed multiple times.
                print $hash{$key}; #This will print "ARRAY(......)";
                print $hash{$key}->[0]; # This will print the first value multiple times.
                print join(@{$hash{$key}}); #This will print all values of that key multiple times.

Better use: while (my ($key, $value) = each (%hash)) { print $key; print $value; #This will print every value only once and in the right order. }

OR maybe:

        my %seen;
        foreach my $key (grep !$seen{$_}++,keys %hash) {
                print $key;
                print join(@{$hash{$key}}); #This will print the keys in the right order, but the values grouped by keys.


values() and scalar each() won't work do what you expect at all, because they call values(%hash) calls $hash{key} for each key, so it will return and array of arrayrefs scalar each() works, but there is no way to find out in which context each was called, so it will screw up the next $hash{key} request.

Better only use ONLY this for iterating over this hash

        while (my ($key, $value) = each (%hash)) {
                #do something with $key and $value


Marc-Sebastian Lucksch