NAME

Tie::MultiKeyInsertOrderHash

DESCRIPTION

Store multiple keys in a hash in insertion order

SYNOPSIS

tie my %hash => 'Tie::MultiKeyInsertOrderHash';
$hash{Say}="Hello World";
$hash{Do}="wave";
$hash{Say}="Good-Bye";
$hash{Do}="leave";

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";

Or:

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

Notes

To complete overwrite a value use:

delete $hash{Value}
$hash{Value}="newvalue";

$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.
}

BUGS

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
}

AUTHOR

Marc-Sebastian Lucksch

perl@maluku.de