sub compare_hashtrees { my ($tree_1, $tree_2) = @_; my @tree_1_only; foreach my $tree_1_key (keys %$tree_1) { my $sub_arrays_not_in_tree2 = []; if ( ! exists $tree_2->{$tree_1_key} ) { # the subtree is missing from tree_2 - expand it $sub_arrays_not_in_tree2 = expand_tree_to_arrays($tree_1->{$tree_1_key}); } elsif ( ref $tree_1->{$tree_1_key} ) { # another level of hashing $sub_arrays_not_in_tree2 = compare_hashtrees($tree_1->{$tree_1_key}, $tree_2->{$tree_1_key}); } foreach my $sub_array (@$sub_arrays_not_in_tree2) { push @tree_1_only, [$tree_1_key, @$sub_array]; } } return \@tree_1_only; } sub expand_tree_to_arrays { my ($tree) = @_; if ( ref $tree ) { my @expanded; foreach my $key (sort keys %$tree) { my $sub_expanded = expand_tree_to_arrays($tree->{$key}); foreach my $path (@$sub_expanded) { push @expanded, [$key, @$path]; } } return \@expanded; } else { # return [ [$tree] ]; # its a scalar return [ [ ] ]; } }