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

First off, thanks and ++ to tye for offering and moving this node from QandA to Seekers of Perl Wisdom, and giving me the chance to clarify an incomplete question.   I should know better than to post right before collapsing to bed in exhaustion.

Anyway, I'm delving into (Lists|Hashes)of(Lists|Hashes) to improve this recent script.   With help from Petruchio, I've learned that (L|H)o(L|H)'s are really (L|H)'s of *references* to (L|H)'s.

So... can Tie::IxHash order the elements of a HoL, as well as the elements of hashes that are referenced by a LOH?   I've found Tie::IxHash to be quite useful in the past, but find no mention of using it with references in it's perldoc or in the excellent perlreftut and perldsc.

Keep in mind that I'm not a programmer by profession, and have reached Saint(10) only by the good graces of vroom and y'all.   so example code (or even scribbled pictures with colored lines) are quite welcome.   {grin}
    cheers,
    Don
    striving toward Perl Adept
    (it's pronounced "why-bick"

  • Comment on Can Tie::IxHash be used to order elements in a list or hash of hashes?

Replies are listed 'Best First'.
Re: Can Tie::IxHash be used to order elements in a list or hash of hashes?
by chipmunk (Parson) on May 22, 2001 at 20:32 UTC
    Tie:IxHash simply adds one feature to hashes; it keeps track of the order in which the keys are inserted into the hash, allowing you to get the keys out in the same order. Everything else is just like a regular hash, whether the values are references or plain old scalars.

    Note that if you wanted something like an order hash of ordered hashes, you would have to tie the outermost hash and each of the inner hashes to Tie::IxHash. If only the outermost hash needs to be ordered, you only need to tie the outermost hash, of course.

    Update: Here's a quick LoH example, with ordered hashes.

    use Tie::IxHash; my @Loh; for (1..5) { my %hash; tie %hash, 'Tie::IxHash'; push @LoH, \%hash; # a separate instance of the lexical %hash # is created each time through the loop }
    @LoH now contains references to 5 ordered hashes. You can treat this structure exactly like an ordinary list of hashes; plus you can use the special features of a Tie::IxHash hash whenever you want.
    for (qw/Just another Perl hacker/) { $LoH[0]{$_} = $_; } print join(' ', keys %{ $LoH[0] }), "\n";
    This will print 'Just another Perl hacker', because Tie::IxHash returns the keys in the same order they were created. Yay!

    Many thanks to tilly for help working out a frustrating problem I ran into with my example. Upshot: do not put the tied reference itself (the return value from tie) in the data structure! Instead, tie the hash first, and put a plain old reference to the hash in the data structure.

    Update: Tie::IxHash should be quoted in the call to tie. Thanks ybiC!

      Explanation on the upshot.

      Tie allows an object to masquerade as a native Perl data structure. Perl maps operations into method calls, and just makes the right method calls. The return value from tie is the object. It is just a regular object, some of whose methods have names that are special to Perl.

      The data structure is what gets tied, and what that means is that it has been replaced by a sort of facade. Accessing an element might do anything. Amazing, astounding, unbelievable - until you realize that this is nothing more than making Perl's native data structures look like method calls. An idea which some languages take much, much farther and integrate much better than Perl does.

      BTW you can get from the data structure to the object with tied. But the object knows nothing about the data structure that has been tied to it.

A reply falls below the community's threshold of quality. You may see it by logging in.