use Data::Dumper; sub set : lvalue { @_ == 1 ? $_[0] : set($_[0]{$_[1]},@_[2..$#_]); } my $h = {foo => 1, bar => 2, baz => { troz => 3, zort => 4, poit => { qux => 5, quux => 6, }, }, }; print Dumper($h); set($h, qw/baz troz/) = 42; set($h, qw/baz poit qux/) = 17; print Dumper($h);