use Data::Dump 'dd'; use strict; use warnings; dd my $h1 = { a => {b => {c => 1}, d=> 2}, e=>3,f=>4 }; dd my $h2 = { a => {b => {c => 1}, d=> 2}, e=>3,f=>4 }; sub gen { my $ref=shift; my @path=(); return sub { while (1) { while (my ($k,$v) = each %$ref) { if ( ref $v eq "HASH") { push @path,$ref; $ref =$v; next; } else { return $k,$v,scalar @path; } } return unless $ref = pop @path; } } } my $iter1=gen($h1); my $iter2=gen($h2); while ((my ($k1,$v1,$l1) = $iter1->()) + (my ($k2,$v2,$l2) = $iter2->()) ) { die "error $v1 != $v2" if $v1 ne $v2; print "$l1: $k1=> $v1\n"; }