aboboras has asked for the wisdom of the Perl Monks concerning the following question:

Im doing this to keep the insert order of a hash:

use Tie::Autotie 'Tie::IxHash'; tie my(%hash1), 'Tie::IxHash';


It works great, but when i try this below, hash1 gets empty:

tie my(%hash2), 'Tie::IxHash'; $hash2{"a"} = $a; $hash2{"b"} = \%hash1;


If i don't tie hash2, hash1 is not empty. But i need both in the insert order.

Replies are listed 'Best First'.
Re: keep hash insert oder, hash inside hash
by Corion (Patriarch) on Apr 26, 2014 at 18:49 UTC

    I think the problem lies with Tie::Autotie. If you leave it out, things Just Work:

    #!perl -w use strict; use Tie::IxHash; tie my(%hash1), 'Tie::IxHash'; $hash1{ test }= 1; tie my(%hash2), 'Tie::IxHash'; $hash2{ foo }= 1; $hash2{ bar }= \%hash1; print "H2: $_ => $hash2{ $_ }" for keys %hash2; print "H1: $_ => $hash1{ $_ }" for keys %hash1; __END__ >perl -wl tmp.pl H2: foo => 1 H2: bar => HASH(0x378998) H1: test => 1

    Looking at Tie::Autotie, it mentions your situation as a bug. "Assigning a reference" does not work. That's what you do with $hash2{ "b" }= \%hash1.

Re: keep hash insert oder, hash inside hash
by Laurent_R (Canon) on Apr 26, 2014 at 21:53 UTC
    I do not know the modules you are using well enough to make comments on your code, but if the insertion order is important, then, maybe, a hash is not the best data structure, possibly an array (or maybe an array of hashes) would make more sense.

    Sometimes, a good solution is to maintain both an hash and an array in order to have the best of two worlds. The array keeps track of the right order and the hash makes it possible to access quickly to the real data. In this case, your main data structure can be either the hash (possibly HoH, or whatever) and the array (possibly AoH, or whatever), and the other data structure just acts as an auxiliary data structure to get the other property that you need. Writing a subroutine that maintains both structures synchronized is no big deal, perhaps just 3 or 4 code lines if you need insertions, possibly a couple of more if you also need to manage deletions.

    All this logics could also be encapsulated in objects, but this might be a bit of an overkill if what you described is all what you need. (OK, yes, I have been discovered, I am somewhat reluctant to OOP for simple problems; to me it is often over-engineering, I tend to prefer the KISS principle. I recently rewrote a 1000+line Java program into a Perl program having less than 75 lines of code. I do not see why I should shoot a bullet in my foot trying to do it the Java way. But this is just my own personal prejudiced opinion, do as you wish.)