My requirement is as below. Inside the same hash the values of keys are dependent on other key value as shown below
my %test;
$test{map}{a} = 32;
$test{map}{b} = $test{map}{a}+10;
$test{ref}{r} = $test{map}{b};
So, when I do print Dumper(\%test); I get
$VAR1 = {
'ref' => {
'r' => 42
},
'map' => {
'a' => 32,
'b' => 42
}
};
If I change the hash value
$test{map}{a} = 42
I get
$VAR1 = {
'ref' => {
'r' => 42
},
'map' => {
'a' => 42,
'b' => 42
}
};
Instead, I should have the updated hash %test as shown below
$VAR1 = {
'ref' => {
'r' => 52
},
'map' => {
'a' => 42,
'b' => 52
}
};
How to achieve the above result? Any help is much appreciated
The semantics of the code you wrote is not what you imagined. In particular:
$test{map}{b} = $test{map}{a}+10;
$test{ref}{r} = $test{map}{b};
These are not -as I think you imagined- "rules" to obtain the value of $test{map}{b}
and $test{map}{b}
every time someone reads them, but instructions that when executed modify the value associated with the keys b
and r
. And that's it.
If you want the elements in your hash to be dynamic, one possible approach could be to use references to subroutines, plus a mechanism to evaluate these rules when the user asks for the values. But be advised that could get complicated: for example, what about circular references? Or rules that reference other rules, as the key r
in your example?
Anyway, here some code as a proof of concept:
use strict;
use warnings;
use v5.10;
my %test;
$test{map}{a} = 32;
$test{map}{b} = sub { evaluate( $test{map}{a} ) + 10 };
$test{ref}{r} = sub { evaluate( $test{map}{b} ) };
sub evaluate {
my $expr = shift;
if ( ref $expr eq 'CODE' ) {
# We need to execute the procedure indicated
# to obtain a value
return $expr->();
}
else {
# Otherwise, we just return what we found associated to the key
return $expr;
}
}
say evaluate( $test{ map }{ a } ); # 32
say evaluate( $test{ map }{ b } ); # 42
say evaluate( $test{ ref }{ r } ); # 42
$test{map}{a} = 42;
say evaluate( $test{ map }{ a } ); # 42
say evaluate( $test{ map }{ b } ); # 52
say evaluate( $test{ ref }{ r } ); # 52
Again, developing a general and solid solution is by no means a trivial project. If you're interested in these techniques from a Perl point of view a very good book is Higher Order Perl, also available online for free.