/ / Perl Hash fait référence aux valeurs de hachage dans le même hachage - perl, perl-hash

Perl Hash fait référence aux valeurs de hachage à l'intérieur du même hachage - perl, perl-hash

Mon exigence est comme ci-dessous. Dans le même hachage, les valeurs des clés dépendent d'une autre valeur de clé, comme indiqué ci-dessous

my %test;

$test{map}{a} = 32;
$test{map}{b} = $test{map}{a}+10;
$test{ref}{r} = $test{map}{b};

Alors, quand je fais imprimer Dumper (% test); Je reçois

$VAR1 = {
"ref" => {
"r" => 42
},
"map" => {
"a" => 32,
"b" => 42
}
};

Si je modifie la valeur de hachage

$test{map}{a} = 42

Je reçois

$VAR1 = {
"ref" => {
"r" => 42
},
"map" => {
"a" => 42,
"b" => 42
}
};

Au lieu de cela, je devrais avoir le test de hachage% mis à jour comme indiqué ci-dessous

$VAR1 = {
"ref" => {
"r" => 52
},
"map" => {
"a" => 42,
"b" => 52
}
};

Comment obtenir le résultat ci-dessus? Toute aide est très appréciée

Réponses:

1 pour la réponse № 1

La sémantique du code que vous avez écrit n'est pas celle que vous imaginiez. En particulier:

$test{map}{b} = $test{map}{a}+10;
$test{ref}{r} = $test{map}{b};

Celles-ci ne sont pas -comme je pense que vous l'imaginiez- "règles" pour obtenir la valeur de $test{map}{b} et $test{map}{b} chaque fois que quelqu'un les lit, mais des instructions qui, une fois exécutées, modifient la valeur associée aux clés b et r. Et c'est tout.

Si vous voulez que les éléments de votre hachage soientdynamique, une approche possible pourrait être d'utiliser des références à des sous-programmes, ainsi qu'un mécanisme pour évaluer ces règles lorsque l'utilisateur demande les valeurs. Mais sachez que cela pourrait se compliquer: par exemple, qu'en est-il des références circulaires? Ou des règles qui font référence à d'autres règles, comme clé r dans votre exemple?

Quoi qu'il en soit, voici du code comme preuve de 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

Encore une fois, le développement d'une solution générale et solide n'est en aucun cas un projet trivial. Si vous êtes intéressé par ces techniques du point de vue de Perl, un très bon livre est Perl d'ordre supérieur, également disponible en ligne gratuitement.


0 pour la réponse № 2

Ce que vous pouvez faire, c'est au lieu d'attribuer la valeur, attribuez un sous-programme. Par exemple:

my %test;

$test{map}{a} = 32;
$test{map}{b} = sub { return $test{map}{a}+10; };
$test{ref}{r} = sub { return $test{map}{b}(); };

print $test{ref}{r}() . "n";

$test{map}{a} = 42;

print $test{ref}{r}() . "n";