(jeffa) Re: re-using a hash reference (was: Mar)
by jeffa (Bishop) on Jun 08, 2002 at 15:25 UTC
|
Depending upon your needs, sometimes you can get by with
just:
$hash2->{'bob'} = $hash1->{'a'}->{'b'}->{'c'};
If you check for a defined key named 'bob' in $hash2, you
will get a false value - however, if you check for a key
named 'bob' that exists in $hash2, you will get a true
value. So if you can get by with keys that have no values
then don't bother with an if expression. If you can't,
then do what vladb suggests (with Juerd's
modification, of course).
Keep in mind that even checking for the presence of a hash
key that does not exist will auto-vivify it into
existence. Run the following code to see an example:
use strict;
use Data::Dumper;
my ($hash1,$hash2);
$hash2->{'bob'} = $hash1->{'a'}->{'b'}->{'c'};
print Dumper $hash1, $hash2;
jeffa
L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
B--B--B--B--B--B--B--B--
H---H---H---H---H---H---
(the triplet paradiddle with high-hat)
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
perl -MData::Dumper -we 'print Dumper $h1 unless $h1->{a}->{b}->{c}'
$VAR1 = {
'a' => {
'b' => {}
}
};
In order to test for $h1->{a}->{b}->{c} there must exist a hash for 'c' to be a key in, so Perl auto-vivifies the data structure up to that point. But notice that 'b' points to an empty hash; 'c' is not a key in it! Perl sees that 'c' is not in {'b'}, and that is all that it needs to evaluate the unless.
perl -MData::Dumper -we 'print Dumper $h1 for $h1->{a}->{b}->{c}'
$VAR1 = {
'a' => {
'b' => {
'c' => undef
}
}
};
Here, we asked Perl to actually *obtain* the value stored in 'c', so Perl went one step further to create the hash key 'c', which holds 'undef', which it returns to the for statement.
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Mar
by vladb (Vicar) on Jun 08, 2002 at 15:09 UTC
|
Whenever I have to deal with deeply nested hashes, I normally save a reference to a nested hash into a separate 'temporary' variable and work with it instead. Just like here:
my $hash_b = $hash1->{'a'}->{'b'};
if ($hash_b->{c}) {
$hash2->{bob} = $hash_b->{c};
}
UPDATE: to the editors, I guess someone has to fix the title of this node and making it anything other than 'Mar' ;).
_____________________
$"=q;grep;;$,=q"grep";for(`find . -name ".saves*~"`){s;$/;;;/(.*-(\d+)
+-.*)$/;
$_=["ps -e -o pid | "," $2 | "," -v "," "];`@$_`?{print"+ $1"}:{print"
+- $1"}&&`rm $1`;
print$\;}
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Whenever I have to deal with deeply nested hashes, I normally save a reference to a nested hash into a separate 'temporary' variable and work with it instead.
To avoid the reference being there longer than you need, you could wrap it in a block. The array will exist as long as references to it exist.
- Yes, I reinvent wheels.
- Spam: Visit eurotraQ.
| [reply] [Watch: Dir/Any] |
Idiom: Localize with 'for'
by Util (Priest) on Jun 08, 2002 at 19:50 UTC
|
A fairly common Perl idiom is:
# Localize expression into $_ using a single-value 'for'.
# $_ is default for many Perl functions.
for ($some_very_long_expression_you_will_use_more_than_once) {
die unless defined;
die unless /^expected/;
do_something($_);
do_something_else($_);
}
Your code becomes:
for ( $hash1->{'a'}->{'b'}->{'c'} ) {
$hash2->{'bob'} = $_ if defined;
}
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] [d/l] |
Re: re-using a hash reference (was: Mar)
by George_Sherston (Vicar) on Jun 08, 2002 at 17:13 UTC
|
Or you could put it in a temp variable:
my $temp;
$temp = $hash1->{'a'}->{'b'}->{'c'};
$hash2->{'bob'} = $temp if defined $temp;
... which probably saves time digging around in your hash if it's a big'un.
§ George Sherston | [reply] [Watch: Dir/Any] [d/l] |