Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl: How to push key/value pair onto hashref and still retain reference

Tags:

perl

hashref

$a = {b=>{c=>1}};   # set up ref
$b = $a->{b};       # ref the ref
$b .= (d=>1,e=>1);  # where we want to assign multiple key/val at once

At the end of it $a should look like:

  • {
      'b' => {
               'c' => 1,
               'd' => 1,
               'e' => 1
             }
    };
    

At the end of it $b should look like:

  • {
      'c' => 1,
      'd' => 1,
      'e' => 1
    }
    

Note: it would be the same as doing:

$b->{d} = 1;
$b->{e} = 1;

$b = { %$b, d=>1, e=>1 }; Is not desired because it creates a copy of $a and loses the reference.

like image 353
vol7ron Avatar asked Aug 09 '12 22:08

vol7ron


2 Answers

%{$b} = ( d => 1, e => 1 );

You simply de-reference the anonymous hash-ref so it looks like a hash to the assignment operator.

You could even do this:

%{$b} = ( %{$b}, d => 1, e => 1 );

In these cases %{$b} is just really a visual convenience (though in some cases can be a syntactic disambiguation) for %$b.

...or you could do...

foreach ( qw/ d e / ) {
    $b->{$_} = 1;
}

Obviously you're probably not intending to assign the value of '1' to everything. So how about a slice:

@{$b}{ qw/ d e / } = ( 1, 1 );

Slices are discussed in perldoc perldata, but there's not really a good perldoc description of taking a slice of an anonymous hash. For that, you have to come to terms with all of the Perl documentation on references, and then extrapolate how to apply that to slice syntax. ...or check anonymous hash slices at PerlMonks.

like image 190
DavidO Avatar answered Nov 15 '22 06:11

DavidO


Use the hash slice notation.

 @$b{"d","e"} = (1,1);

 %newdata = (d => 1, e => 1);
 @$b{keys %newdata} = values %newdata;
like image 31
mob Avatar answered Nov 15 '22 06:11

mob