in reply to Multiple Unordered Hash Keys

It's certainly interesting. What, exactly, though, does all that tie'ing buy you that's so much better than the following?

$hash{ 'keyA' }{ 'keyB' } = "Some Value"; print $hash{ 'keyA' }{ 'keyB' };

Yes, having the keys unordered could theoretically be nice, but in what situations do you find it's an issue?

If it's really necessary, you could in the exact case you need it do this:

@foo = ( 'keyB', 'keyA' ); $hash{ join '', sort @foo } = "Some Value\n"; print $hash{ join '', sort @foo };

Replies are listed 'Best First'.
Re^2: Multiple Unordered Hash Keys
by neosamuri (Friar) on Mar 26, 2008 at 23:29 UTC

    In the problem I had, I had 2 references that I needed to know if I had already tested them, and what the result is. The first thing that came to mind was using the hash. The problem is that you don't know if refA or refB is the first key into the hash, so you have to test both.

    if( $tests{ $refA, $refB } or $tests{$refB, $refA} ) { # some stuff } # as opposed to if( $tests{ $refA, $refB} ) { # order not important # some stuff }

    The reason for using the tied interface instead of verbosely writing out the sort join, is so that you don't have to see that extra code, which doesn't add to the understanding of the code, but instead clouds it.

      sub mk { join '', sort @_ } $hash{ mk 'a', 'b' } = 'Some Value'; print $hash{ mk qw{ b a } };

      It's still a little bit of extra typing, I'll admit. It doesn't involve modifying how the hash code works, though. I don't think having a few extra characters obfuscates the hash usage at all.

      You might also notice that by joining with an empty string, you're able to use arrays as well as lists. That's one of the benefits of Hash::MultiKey over standard Perl multi-keyed hashes, but without the tie.

      Another advantage is that in many cases you can do the sort and join once, saving the result into a simple scalar for later use. It may be frowned upon as a premature optimization, but it could help the clarity of the code over a tied hash.

      In your example, I'm not quite certain why you'd be storing the results of two tests as one entry in the hash in the first place. Are you specifically testing pairs of mutually dependent items?

      if ( $tests{ $refA } && $tests{ $refB } ) { # This checks two hash entries very cleanly, but falls down # if the results are dependent on whether A and B are tested together +. # some stuff }

      With something like Hash::MultiKey, I'm not sure from the top of my head when I'd use the fact that each() and keys() return an arrayref of strings instead of the concatenated string, but surely someone's found a use for that feature because it's all over the examples. If I thought of a solid reason I'd want that, then using a module which does that would probably be worthwhile.

      I'm not trying to discourage you from publishing your module; I'm just giving you the feedback you requested. I, personally, probably won't use your module. If you find your module useful enough to put it on CPAN, other people will probably find it useful enough to download from CPAN.