2017-07-19 296 views
1

我的要求如下。内相同的散列密钥的值是依赖于其它密钥值如下所示Perl哈希对同一哈希值内的哈希值的引用

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 
        } 
     }; 

相反,我应该有更新的散列%测试如下图所示

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

如何o达到上述结果?任何帮助,非常感谢

+0

谢谢larsen&Apoorv Joshi。您提供的解决方案帮助我以我想要的方式实现代码。 – Ajatasatru

回答

1

你写的代码的语义不是你想象的。特别是:

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

这些 -as我想你imagined-“规则”获得的每一次有人读他们$test{map}{b}$test{map}{b}的价值,但在执行时修改与关联的值指令钥匙br。就是这样。

如果希望散列中的元素是动态的,则可以使用对子例程的引用,以及在用户请求值时评估这些规则的机制。但请注意,可能会变得复杂:例如,循环引用是什么?或引用其他规则的规则,例如您的示例中的密钥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,也可以免费在线获得。

0

你可以做的是不分配值,分配一个子程序。例如:

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";