use warnings; use strict; sub dive { my $r = shift; $r = ref $r eq 'HASH' && exists $$r{$_} ? $$r{$_} : return for @_; return $r } use Test::More; my $h = { a => { b => { c => { d => 'e' } } } }; is dive($h, qw/ a /), $h->{a}; is dive($h, qw/ a b /), $h->{a}{b}; is dive($h, qw/ a b c /), $h->{a}{b}{c}; is dive($h, qw/ a b c d /), 'e'; is dive($h, qw/ a b c d e /), undef; is dive($h, qw/ a x /), undef; is dive($h, qw/ a b x /), undef; is dive($h, qw/ a x y /), undef; is dive($h, qw/ a b x y /), undef; is dive($h, qw/ x /), undef; is dive($h, qw/ x y /), undef; is dive($h, qw/ x y z /), undef; is_deeply $h, { a => { b => { c => { d => 'e' } } } }; done_testing;