Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

How do I test the deep equality of two hash tables?

by acser (Novice)
on Oct 26, 2001 at 02:19 UTC ( #121559=perlquestion: print w/replies, xml ) Need Help??

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

See node: How to test equality of hashes?

Edit - Petruchio Tue Oct 30 17:35:05 UTC 2001: Corrected link format

  • Comment on How do I test the deep equality of two hash tables?

Replies are listed 'Best First'.
Re: How do I test the deep equality of two hash tables?
by cmeyer (Pilgrim) on May 22, 2005 at 03:24 UTC

    Another way to compare to arbitrarily complex data structures is to use canonical serialization. Storable is one module that provides this capability.

    For example:

    use Storable; sub deeply_equal { my ( $a_ref, $b_ref ) = @_; local $Storable::canonical = 1; return Storable::freeze( $a_ref ) eq Storable::freeze( $b_ref ); }
Re: How do I test the deep equality of two hash tables?
by fergal (Chaplain) on May 22, 2005 at 13:07 UTC
    Test::Deep provides deep comparisons of any data structures, including hashes. It is also capable of very advanced testing - what regular expressions do for strings, Test::Deep does for data structures.
    use Test::Deep; if (eq_deeply($hash1, $hash2)) { print "they match" }

    The fancy stuff comes in when you do something like

    $animals = set("cat", "dog"); $people = set("john", "mary"); $a_p = set($animals, $people); print eq_deeply($structure, $a_p);
    Ths is an example of testing set equality. It tests that $structure is an array with 2 elemenents (in any order) where each of those elements is an array with 2 elements, one containiing "cat" and "dog" (in any order) the other containing "john" and "mary" (in any order)

    When used as part of the Test::Builder framework it gives diagnostics on where the structures differed.

Re: How do I test the deep equality of two hash tables?
by Roy Johnson (Monsignor) on Nov 03, 2003 at 21:29 UTC
    This does all the straightforward tests, and warns and returns undef on stuff it can't reliably compare (like code refs). Would probably be better to use UNIVERSAL::isa rather than ref.
    sub deep_eq { my ($a, $b) = @_; if (not defined $a) { return not defined $b } elsif (not defined $b) { return 0 } elsif (not ref $a) { $a eq $b } elsif ($a eq $b) { return 1 } elsif (ref $a ne ref $b) { return 0 } elsif (ref $a eq 'SCALAR') { $$a eq $$b } elsif (ref $a eq 'ARRAY') { if (@$a == @$b) { for (0..$#$a) { my $rval; return $rval unless ($rval = deep_eq($a->[$_], $b->[$_ +])); } return 1; } else { return 0 } } elsif (ref $a eq 'HASH') { if (keys %$a == keys %$b) { for (keys %$a) { my $rval; return $rval unless ($rval = deep_eq($a->{$_}, $b->{$_ +})); } return 1; } else { return 0 } } elsif (ref $a eq ref $b) { warn 'Cannot test '.(ref $a)."\n"; un +def } else { return 0 } }

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (10)
As of 2023-02-07 20:41 GMT
Find Nodes?
    Voting Booth?
    I prefer not to run the latest version of Perl because:

    Results (40 votes). Check out past polls.