use strict; sub hash_equality (\%\%) { my %hash1 = %{shift()}; my %hash2 = %{shift()}; my %done; foreach my $key (keys %hash1, keys %hash2) { next if $done{$key}++; if (!ref($hash1{$key})) { return if $hash1{$key} ne $hash2{$key}; } elsif (ref($hash1{$key}) eq "ARRAY") { my ($e, %union, %isect); foreach $e (@{$hash1{$key}}, @{$hash2{$key}}) { $union{$e}++ && $isect{$e}++; } return if scalar(keys %union) != scalar(keys %isect); } else { # handle other reference types if needed? return; } } # ok return 1; } my %A = ( one => 1, two => [ qw{ t w o } ] ); my %B = ( one => 1, two => [ qw{ t r e } ] ); my %C = ( one => 1, two => [ qw{ t w o } ] ); print "Mismatch!\n" unless hash_equality(%A, %B); print "OK!\n" if hash_equality(%A, %C);