in reply to Comparing all keys in a hash

I have to say that I really wonder about this node and thread. The code is interesting in its own way, and the discussion below has some merit I suppose, but I can't help but question a bunch of things.

First off what does this routine do? It "compares" two hashes. Presumably the hashes are of numbers? Its a litte unclear if they are because sort keys %$h1 sorts them lexicographically. I think you want sort {$a <=> $b} keys %$h1.

Next is the issue of what you return. You return the difference in the number of elements if they are different, otherwise you return which of the two has a lower element encoded ala <=>. What I wonder is why? Why is a hash that contains a single key, say 100000 smaller than a hash with two keys, say 1,2? Why is a hash with keys (0,1,100,200) smaller than a hash with (0,2,2,2)?

If I saw this code in production without considerable explanation as to its use and relevance I would earmark it for a rewrite as being misconceived. Either it should be renamed, or it should be refactored, or it should be redone. It just doesnt make sense...


---
demerphq

<Elian> And I do take a kind of perverse pleasure in having an OO assembly language...

Replies are listed 'Best First'.
Re: Re: Comparing all keys in a hash
by rinceWind (Monsignor) on Mar 21, 2003 at 10:00 UTC
    demerphq, I feel I should put you out of your misery.

    This code is part of an application process monitoring GUI, that uses Tk. The hash keys are process IDs, and this sub is used to decide whether anything has changed (hence whether to backtick a ps and poll the application's control files - which are expensive activities).

    In practice, the code only needs a zero or non-zero value, so the spaceship operator like return value is overkill. After writing the code, it seemed like an interesting exercise to see if the code could have been written better, hence my meditation on PM.

    Hope this answers your questions. Your post has prompted me to add some comments to the code.

      Ok. Now I get it. :-) Personally I would return very different results...

      # Determines if two hashes have different keys # If the hashes are different: # In list context returns two array refs, each # containing the missing elements from the other # In scalar context returns an AOA, with a similar # content as above # Otherwise # Returns the empty list or undef as appropriate. # Thus # A true return means they hashes are different, # a false means they have identical keys sub hash_key_diff { my ($x,$y)=@_; my (@x,@y); foreach my $k (keys %$x) { push @y,$k unless exists $y->{$k}; } foreach my $k (keys %$y) { push @x,$k unless exists $x->{$k}; } return @x||@y ? wantarray ? (\@x,\@y) : [\@x,\@y] : () }

      This seems like a much more reasonable return to me, and considering the use you put it to it would seem to be more convenient as well: this would give you a list of processes that have been removed, as well as processes that have started.

      BTW: You didnt overlook my point about the sort order did you?

      Anyway, thanks for the explanation.


      ---
      demerphq


Re: Re: Comparing all keys in a hash
by shotgunefx (Parson) on Mar 21, 2003 at 10:10 UTC
    Well I must say I did find this interesting, mainly because it seemed a fairly trivial problem with many seemingly equivalent solutions but was suprised how much of a difference in speed there was between the different approaches. (Though not likely to be an issue in most programs anyway) As far as my own code, I do find the return value odd but I was following the original.

    -Lee

    "To be civilized is to deny one's nature."