Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

Preserving order for nested hashes using Tie::IxHash

by ramya2005 (Scribe)
on Aug 19, 2005 at 21:04 UTC ( #485306=perlquestion: print w/replies, xml ) Need Help??

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

I am having trouble is preserving the order for nested hashes using IxHash. I have a nested Hash structure similar to the following example.
tie %data, "Tie::IxHash"; preserves only the outer hash order but not the inner one.
my %data = { '1' => { '6' => { 'width' => '53', 'len' => '16', 'width_arr' => [ '53' ], 'mems' => 1, 'rows' => 1, 'mux' => '4', 'len_arr' => [ '16' ], 'cols' => 1, } } };
Is it possible to preserve the order of nested hashes using this module.

Any suggestions will be much appreciated!

Replies are listed 'Best First'.
Re: Preserving order for nested hashes using Tie::IxHash
by tilly (Archbishop) on Aug 19, 2005 at 22:35 UTC
    The solution that I use is to write a function that returns a hash reference that is tied. Like this:
    use Tie::IxHash sub ordered_hash_ref { tie my %hash, 'Tie::IxHash', @_; return \%hash; } # time passes... tie my %data, 'Tie::IxHash', 1 => ordered_hash_ref( 6 => ordered_hash_ref( width => 53, len => 16, width_arr => [ 53 ], mems => 1, rows => 1 mux => 4, len_arr => [ 16 ], cols => 1, ), ), ;
    This is nice if you like having your nested data structures declared compactly, albeit at the cost of having to put the function calls in there.
Re: Preserving order for nested hashes using Tie::IxHash
by shemp (Deacon) on Aug 19, 2005 at 21:16 UTC
    You need to tie each of the hashes that you want order preserved in. When you do:
    tie (my %data, 'Tie::IxHash');
    That ties the hash %data as a Tie::IxHash, but never does anything about the values in %data. (keep in mind that ALL hash values are scalars).

    You'll need something like this:

    tie(my %data, 'Tie::IxHash'); while ( ... ) { # add info to %data if ( <working in a second tier> ) { if ( ! exists $data{$top_level_key) ) { $data{$top_level_key} = {}; tie ( %{$data{$top_level_key}}, 'Tie::IxHash' ); } ... } ... }
    Without knowing how you're creating these nested hashes, i can't give better insight, but hopefully my little framework will express the idea to you.

    The following suggestion already exists, as Borisz points out below.
    End update

    If you wanted to (if it suits your needs), you could cook up a more complicated version of Tie::IxHash (call it something else - like Tie::IxHash::MultiLevel), that checks if values being added to the hash are HASHREF's, and if they are, then tie them also.

    I don't particularly recommend this approach, because it could bite you later on. It will be automatically recursive down the levels though, because if a second tier hashref is tied as a Tie::IxHash::MultiLevel, then it will do checking on its values too.

    I use the most powerful debugger available: print!
Re: Preserving order for nested hashes using Tie::IxHash
by borisz (Canon) on Aug 19, 2005 at 22:02 UTC
Re: Preserving order for nested hashes using Tie::IxHash
by bart (Canon) on Aug 19, 2005 at 22:16 UTC

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://485306]
Approved by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (3)
As of 2022-11-29 01:58 GMT
Find Nodes?
    Voting Booth?