I want to hear what you think. I've got a module written called Tie::SortHash. I think it's something everyone can use. Observe:
# tie HASH, 'Tie::SortHash', ANON_HASH, SORT_EXPR tie my %hash, 'Tie::SortHash', { 'John Doe' => 25, 'Jane Doe' => 39, 'Jim Baker' => 30 }, q( my( $c, $d ) = ( $a, $b ); $c =~ s/\w+\s//; $d =~ s/\w+\s//; $c cmp $d || $hash{$b} <=> $hash{$ +a} );
Now, when you iterate over the hash, it will always come out in sorted order you've specified.
print "$_\t$hash{$_}\n" foreach keys %hash; <code> will <b>always</b> produce: <code> Jim Baker 30 Jane Doe 39 John Doe 20
This stops the annoying need to say:
foreach ( sort keys %hash ) { ... }
All the time.

I have also added the ability to update your sort block at any time:

(tied %hash)->newsortblock( q($b cmp $a) );
And the sort block must be passed as a non-interpolated string becuase it was the only way to allow complex sorts. ( ie. sort on value ). And inside the sort string, the variable %hash is generic, it would be the same for this example:
my %people = ( 'John Doe' => 25, 'Jane Doe' => 39, 'Jim Baker' => 30 ); my $sortblock = q( my( $c, $d ) = ( $a, $b ); $c =~ s/\w+\s//; $d =~ s/\w+\s//; $c cmp $d || $hash{$b} <=> $hash{$a} ); tie %people, 'Tie::SortHash', { %people }, $sortblock;
Feedback welcome, prefferably in the form of "Yeah, I like that" or "What tha...?"
--
Casey

Replies are listed 'Best First'.
RE: Module Proposal: Tie::SortHash
by KM (Priest) on Aug 18, 2000 at 23:36 UTC
    Well, I don't know why you are proposing it here and not the modules list, but since you are ... :)
    Personally, I would rather see that funtionality added to an existing module like Tie:IxHash, or Tie::LLHash which both already do some internal sorting. Maybe working with one of those authors (Sarathy and Ken Williams, respectively) to see if your methods will fit into their modules before adding another tied hash sorting module.

    Cheers,
    KM

      I had origionaly thought of doing that, however, they both have different symantics, and are fairly particular:

      Tie::IxHash attempts to give you more of an array like behavior and keeps the order that things were added to the hash, just like arrays. I'm not trying to do that.

      Tie::LLHash gives you the ability to poke and prod the hash, while keeping it's state of where and how things were entered into it. I'm also not looking to do that.

      The advantage is that there is no overhead or fluf with Tie::SortHash. It's designed to do one thing, rather transparently. I like the transparent part, you don't get that with the other two modules.

      Transparent meaning, for most cases, there's only two 'out of the ordinary' lines in your program. One usees Tie::SortHash, the other implements the tie.

      --
      Casey
      
        If your internals can't work with theirs (I would doubt that they can't work together), then it would be ok as it's own module. It just seems that this would fit nicely, at least into IxHash. It keeps the order of the entered keys, but also has some ordering/sorting methods (Reorder, SortByKey and SortByValue). With add something like SortByInput (off the top of my head) it seems you would only need to reorder the array IxHash keeps in parallel to the hash.
        Just my $.02, but I do like the idea. I would only want to make sure it wouldn't be more valuable in conjunction with another module, rather than stand alone. I suggest asking for any comments on the modules list.

        Cheers,
        KM

      Where is the modules list? I have a couple modules that are worth posting, but I couldn't find a good place to do it. The code catacombs seem ... not very well suited to posting modules.
        Go to here (or the 04pause.html page in your favorite mirror) and read how to become a CPAN contributor. A link to the modules list, and what to send to it, are on that page.

        Cheers,
        KM

RE (tilly) 1: Module Proposal: Tie::SortHash
by tilly (Archbishop) on Aug 19, 2000 at 00:06 UTC
    KM already mentioned a couple other alternatives.

    One I have used is DB_File. Just tie to a BTree and you can get keys back in sorted order. Custom sort functions and all. You can't sort on values, but I almost never would want to be able to do that, and if I did it would almost always be better to do it after the fact.

    Reminds me though, a fun gotcha I shocked both the author of DB_File and the authors of Berkeley DB with. Consider the following sort function:

    sub { use locale; $a cmp $b; }
    If you use this someone can store stuff in a locale sensitive order. Handy for those people in Europe with different alphabets.

    What happens if someone changes the locale on their machine? And then starts using the database?

    BOOM!
    Instantly corrupted database! Completely silent!

    So this is a handy sort sub to know about, but use with some caution. :-)

      Nice gotcha!

      I am aware of that method however, it doesn't seem so straight forward if you ask me... at first I would think... "What the heck do I need a DB_File for?"

      When I think, I want to have my hashes auto sort without doing (hardly) any work at all. I think: search.cpan.org searching for Hash and/or Sort... oh, ther it is (well, would be).

      --
      Casey
      
        Agreed it is not an obvious place to look. OTOH when I learned about tie, it was through DB_File. So from the time I learned that something like this was possible, I knew how to use it to autosort.

        YMMV of course.

RE: Module Proposal: Tie::SortHash
by chip (Curate) on Aug 20, 2000 at 14:02 UTC
    Surely you could accept a subroutine reference that takes the target hash as a parameter by reference ... ?

    And I've got to say that this is the longest distance I've ever seen anyone go to avoid typing one keyword.

        -- Chip Salzenberg, Free-Floating Agent of Chaos

(zdog) RE: Module Proposal (Is this the place for it?)
by zdog (Priest) on Aug 19, 2000 at 05:10 UTC
    I don't want to sound harsh, but here I go:

    Just think about it. Perl Monks Discussion is for things dealing directly with the web site. This section should almost never have the word "Perl" even mentioned here.

    I fail, however, to see how your post has anything to do with the web site. In my opinion, this post should go to Meditations.

    I'm just saying this for future reference. Anyway, good luck with your module.

    Zenon Zabinski | zdog | zdog7@hotmail.com