Perl Hash 引用同一哈希中的哈希值
Perl Hash references to the hash values inside same hash
我的要求如下。在同一个散列中,键的值依赖于其他键值,如下所示
my %test;
$test{map}{a} = 32;
$test{map}{b} = $test{map}{a}+10;
$test{ref}{r} = $test{map}{b};
所以,当我这样做的时候
打印转储程序(\%测试);
我得到
$VAR1 = {
'ref' => {
'r' => 42
},
'map' => {
'a' => 32,
'b' => 42
}
};
如果我更改哈希值
$test{map}{a} = 42
我明白了
$VAR1 = {
'ref' => {
'r' => 42
},
'map' => {
'a' => 42,
'b' => 42
}
};
相反,我应该有更新后的哈希 %test,如下所示
$VAR1 = {
'ref' => {
'r' => 52
},
'map' => {
'a' => 42,
'b' => 52
}
};
如何实现上面的结果?非常感谢任何帮助
你写的代码语义不是你想象的那样。特别是:
$test{map}{b} = $test{map}{a}+10;
$test{ref}{r} = $test{map}{b};
这些不是-我想你想象的-"rules"每次有人阅读时都获得$test{map}{b}
和$test{map}{b}
的值它们,而是在执行时修改与键 b
和 r
关联的值的指令。就是这样。
如果您希望散列中的元素是动态的,一种可能的方法是使用对子例程的引用,以及一种在用户请求值时评估这些规则的机制。但请注意,这可能会变得复杂:例如,循环引用呢?或者引用其他规则的规则,如示例中的键 r
?
无论如何,这里有一些代码作为概念证明:
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
同样,开发一个通用的、可靠的解决方案绝非易事。如果您从 Perl 的角度对这些技术感兴趣,一本非常好的书是 Higher Order Perl,也可以免费在线获得。
您可以做的不是分配值,而是分配一个子例程。例如:
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";
我的要求如下。在同一个散列中,键的值依赖于其他键值,如下所示
my %test;
$test{map}{a} = 32;
$test{map}{b} = $test{map}{a}+10;
$test{ref}{r} = $test{map}{b};
所以,当我这样做的时候 打印转储程序(\%测试); 我得到
$VAR1 = {
'ref' => {
'r' => 42
},
'map' => {
'a' => 32,
'b' => 42
}
};
如果我更改哈希值
$test{map}{a} = 42
我明白了
$VAR1 = {
'ref' => {
'r' => 42
},
'map' => {
'a' => 42,
'b' => 42
}
};
相反,我应该有更新后的哈希 %test,如下所示
$VAR1 = {
'ref' => {
'r' => 52
},
'map' => {
'a' => 42,
'b' => 52
}
};
如何实现上面的结果?非常感谢任何帮助
你写的代码语义不是你想象的那样。特别是:
$test{map}{b} = $test{map}{a}+10;
$test{ref}{r} = $test{map}{b};
这些不是-我想你想象的-"rules"每次有人阅读时都获得$test{map}{b}
和$test{map}{b}
的值它们,而是在执行时修改与键 b
和 r
关联的值的指令。就是这样。
如果您希望散列中的元素是动态的,一种可能的方法是使用对子例程的引用,以及一种在用户请求值时评估这些规则的机制。但请注意,这可能会变得复杂:例如,循环引用呢?或者引用其他规则的规则,如示例中的键 r
?
无论如何,这里有一些代码作为概念证明:
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
同样,开发一个通用的、可靠的解决方案绝非易事。如果您从 Perl 的角度对这些技术感兴趣,一本非常好的书是 Higher Order Perl,也可以免费在线获得。
您可以做的不是分配值,而是分配一个子例程。例如:
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";