perl更改hash的ref

时间:2014-10-26 16:02:07

标签: perl hash

我遇到了这个并且无法找到答案。我试图看看是否有可能改变"哈希的引用。换句话说,我有一个哈希,一个返回hashref的函数,我想让我的哈希指向这个引用指定的内存中的位置,而不是复制它指向的哈希的内容。代码看起来像这样:

%hash = $h->hashref;

我明显的猜测是它应该是这样的:

\%hash = $h->hashref;

但是会出错:

  

无法修改标量赋值中的引用构造函数

我尝试了其他一些东西,但没有任何效果。我真正想要的是什么?

4 个答案:

答案 0 :(得分:1)

听起来像你想要的那样:

use Data::Alias;
alias %hash = $h->hashref;

或者如果%hash是一个包变量,你可以改为:

*hash = $h->hashref;

但无论如何,这几乎总是应该避免;为什么不简单地使用哈希引用呢?

答案 1 :(得分:1)

是的,但是......

perl中的引用是Scalars。您要实现的是对返回值进行别名处理。这实际上是可行的,但你应该这样做,因为它涉及到弄乱符号表。此外,这仅适用于全局变量(使用我们声明):如果将hashref分配给glob *hash,它将分配给符号表条目%hash

#!/usr/bin/env perl

use warnings;
use strict;

sub a_hashref{{a => "one", b => "two"}}

our %hash;
*hash = a_hashref;

printf "%3s -> %s\n",$_,$hash{$_} foreach keys %hash;

这是不好的风格!它不是PBP(直接,但考虑第5.1节:“应避免使用非词汇”)并且不会被perlcritic报告但是你不应该污染包命名空间以获得一点语法上的优点。此外,它不适用于词法变量(这是你可能想要在大多数时候使用的变量,因为它们是词法范围的,而不是包广泛的)。另一个问题是,如果$h->hashref方法更改其返回类型,您将突然分配给另一个表条目! (因此,如果$h->hashref将其返回类型更改为arrayref,则分配给@hash,祝你好运()。您可以通过检查$h->hashref是否真的返回带有'HASH' eq ref $ h-> hashref`的hashref来规避这一点,但这样做会失败。

仅保留参考有什么问题?如果您获得参考,为什么不将它存储在标量中?

$ hash = $ h-> hashref

要阅读有关全局符号表的更多信息,请查看perlmod并考虑perlref *FOO{THING}语法,这对于左值非常不合适。

要实现您想要的效果,您可以查看多个别名modules on cpanData::AliasLexical::Alias似乎符合您的目的。此外,如果您对tie语义感兴趣和/或不想使用XS模块,Tie::Alias可能值得拍摄。

答案 2 :(得分:1)

一个实验性的功能,似乎可以让你完全按照你所描述的has been added来实现Perl 5.21.5,这是一个开发版本(参见"通过参考和#34进行别名;)

答案 3 :(得分:1)

这个问题真的很老了,但 Perl 现在允许这种事情作为实验性功能:

use v5.22;

use experimental qw(refaliasing);

my $first = {
    foo => 'bar',
    baz => 'quux',
    };

\my %hash = $first;