Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re: Copy an hash modifying some selected values

by ikegami (Pope)
on Nov 07, 2018 at 17:23 UTC ( #1225369=note: print w/replies, xml ) Need Help??


in reply to Copy an hash modifying some selected values

Data::Diver comes in useful here.

use Data::Diver qw( Dive ); my @paths = ('key1', 'key2:key22', 'key2:key23'); for my $path (@paths) { my @path = split(/:/, $path); my $val = Dive(\%hash, map \$_, @path); ... }

It's not that hard to implement yourself, though.

sub dive { my $r = shift; $r = $r->{shift(@_)} while $r && @_; return $r; } my @paths = ('key1', 'key2:key22', 'key2:key23'); for my $path (@paths) { my @path = split(/:/, $path); my $val = dive(\%hash, @path); ... }

Replies are listed 'Best First'.
Re^2: Copy an hash modifying some selected values
by Anonymous Monk on Nov 07, 2018 at 18:03 UTC
    Thank you! The result for the code:
    use strict; use Data::Dumper; my %hash1 = ( key1 => 'relative_path', key2 => { key21 => 'another_relative_path', key22 => '/an_absolute_path', key23 => 'relative_path', }, key3 => '', key4 => 4 ); my @paths = ('key1', 'key2:key22', 'key2:key23'); for my $path (@paths) { my @path = split(/:/, $path); my $val = dive(\%hash1, @path); warn $val; } sub dive { my $r = shift; $r = $r->{shift(@_)} while $r && @_; return $r; }
    is:
    relative_path at test2.pl line 20. /an_absolute_path at test2.pl line 20. relative_path at test2.pl line 20.
    So I can get the values of interest to be checked, but how do I set them in the new %hash2?

      Did you look at the module I mentioned?

      use Data::Diver qw( DiveVal ); my @paths = ('key1', 'key2:key22', 'key2:key23'); for my $path (@paths) { my @path = split(/:/, $path); my $new_val = ...; DiveVal(\%hash, map \$_, @path) = $new_val; }

      or

      sub dive_val :lvalue { my $p = \shift; $p = \( $$p->{$_} ) for @_; $$p } my @paths = ('key1', 'key2:key22', 'key2:key23'); for my $path (@paths) { my @path = split(/:/, $path); my $new_val = ...; dive_val(\%hash, @path) = $new_val; }
        Thank you!
        I still get an error with your version of the routine so I will use Data::Diver.
        I would prefer your routine since it is pure Perl... just in case you would want to fix my example below.
        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 }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1225369]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2019-02-17 00:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I use postfix dereferencing ...









    Results (95 votes). Check out past polls.

    Notices?