use Carp qw/croak/; use List::Util qw/max/; sub max_depth { my $thing = shift; croak "too many arguments" if @_; my $children = do { if (ref $thing eq 'ARRAY') { $thing } elsif (ref $thing eq 'HASH') { [values %$thing] } else { undef } }; return 1 + max map { max_depth($_) } @$children if $children; return 0; } my $data = { foo => [1, 2, 3], bar => [4, 5, { quux => { quuux => 6 } }], baz => 7, }; print max_depth($data->{bar}[2]{quux}{quxux}) . "\n"; print max_depth($data->{bar}[2]{quux}) . "\n"; print max_depth($data->{bar}[2]) . "\n"; print max_depth($data->{bar}) . "\n"; print max_depth($data) . "\n"; __END__ 0 1 2 3 4