取消引用哈希而不创建本地副本

nam*_*ame 3 perl hash dereference

我在第9行的代码中创建了一个哈希的本地副本.对%d的任何更改都不会对全局%h变量(行:5)进行更改.我必须使用reference(第8行)来提供对%h的更改.

有没有办法在不创建本地副本的情况下取消引用子哈希?我问,因为我有许多参考文献的复杂记录,并且通过解引用导航它会更容易.

  1 #!/usr/bin/perl -w
  2 use strict;
  3 use warnings;
  4 
  5 my %h;
  6 sub a {
  7 
  8     my $href = shift;
  9     my(%d) = %{$href};   # this will make a copy of global %h
 10     
 11     $$href{1}=2;     # this will make a change in global %h
 12     $d{2}=2;         # this will not a change in global %h
 13 }   
 14 a(\%h);
 15 print scalar (keys %h) . "\n";
Run Code Online (Sandbox Code Playgroud)

----------------

谢谢你的回复.

问题是我可以在sub中对%h进行某种"别名/绑定".我想在%d中改变%h中的%h的上下文.每当我创建%d时,他都会制作%h的本地副本 - 是否有任何方法可以避免这种情况,或者我是否必须始终使用引用?

----------------

再一次:)我知道$ href是如何工作的.我阅读了教程/手册/文档等.我没有找到答案 - 我认为这是不可能的,因为它没有写在那里,但谁知道.

我想完成这样的行为:

  6 sub a {
  7     $h{"1"}=2;
  8 }
Run Code Online (Sandbox Code Playgroud)

这相当于:

  6 sub a {
  8      my $href = shift;
  11     $$href{1}=2;     # this will make a change in global %h
  11     $href->{1}=2;    # this will make a change in global %h
Run Code Online (Sandbox Code Playgroud)

现在如何在%d的帮助下做到这一点 - 实际上可能吗?

6 sub a {
7        my %d = XXXXXXXXX
.. }
Run Code Online (Sandbox Code Playgroud)

如果不创建本地副本,我应该在XXXXXXXXX下指向%h?

Eri*_*rom 6

要创建值的本地别名,您需要使用Perl的包变量,这些变量可以使用typeglob语法进行别名(以及local范围别名):

#!/usr/bin/perl -w
use strict;
use warnings;

my %h;

sub a {
    my $href = shift;

    our %alias; # create the package variable (for strict)

    local *alias = $href;
        # here we tell perl to install the hashref into the typeglob 'alias'
        # perl will automatically put the hashref into the HASH slot of
        # the glob which makes %alias refer to the passed in hash.
        # local is used to limit the change to the current dynamic scope.
        # effectively it is doing:  *{alias}{HASH} = $href

    $$href{1}=2;     # this will make a change in global %h
    $alias{2}=2;     # this will also make a change in global %h
}
a(\%h);
print scalar (keys %h) . "\n";  # prints 2
Run Code Online (Sandbox Code Playgroud)

这是一种相当先进的技术,因此请务必阅读Perl文档local,typeglobs以便您准确了解正在发生的事情(特别是,在a子例程中调用的任何子函数local也将%alias在范围内,因为它local表示动态范围.本地化将在a退货时结束.)

如果您可以安装Data::Alias或从其中一个其他别名模块,CPAN可以避免包变量并创建词法别名.没有附加模块,上述方法是唯一的方法.