use strict; use Data::Dumper; use Data::Diver qw( DiveVal ); use Storable 'dclone'; my %hash1 = ( key1 => 'relative_path', key2 => { key21 => 'another_relative_path', key22 => '/an_absolute_path', key23 => 'relative_path', }, key3 => '', key4 => 4 ); my $hash2 = dclone \%hash1; my $hash3 = dclone \%hash1; my $home = '/home'; my @paths = ('key1', 'key2:key22', 'key2:key23'); for my $path (@paths) { my @path = split(/:/, $path); my $val = dive(\%hash1, @path); my $new_val = (substr($val,0,1) eq '/') ? $val : "$home/$val"; DiveVal($hash2, map \$_, @path) = $new_val; # dive_val($hash3, map \$_, @path) = $new_val; } die Dumper \@paths,\%hash1,$hash2; sub dive { my $r = shift; $r = $r->{shift(@_)} while $r && @_; return $r; } sub dive_val :lvalue { my $p = \shift; my $r = \( $$p->{$_} ) for @_; $$p }