if(exists($coordinates->{$group})) { if(exists($coordinates->{$group}->{$id})) { if(exists($coordinates->{$group}->{$id}->{$stage})) { ... } } } #### my $result = do_stuff_in_hash_without_autovivifying( sub { my $hash_to_work_on = shift; # do stuff here }, $coordinates, # initial hash $group, $id, $stage, 'coords' # list of keys to traverse ); sub do_stuff_in_hash_without_autovivifying { my($sub, $hash, @keys) = @_; if(@keys && exists($hash->{$keys[0]}) { return do_stuff_in_hash_without_autovivifying( $sub, $hash->{$keys[0]}, @keys[1 .. $#keys] ); } else { return $sub->($hash); } } #### use Tie::Hash::Vivify; use Data::Dumper; my $hash = Tie::Hash::Vivify->new(sub { die("No auto-vivifying! Bad programmer! No bikkit!\n".Dumper(\@_)) });