我遇到了这个并且无法找到答案。我试图看看是否有可能改变"哈希的引用。换句话说,我有一个哈希,一个返回hashref的函数,我想让我的哈希指向这个引用指定的内存中的位置,而不是复制它指向的哈希的内容。代码看起来像这样:
%hash = $h->hashref;
我明显的猜测是它应该是这样的:
\%hash = $h->hashref;
但是会出错:
无法修改标量赋值中的引用构造函数
我尝试了其他一些东西,但没有任何效果。我真正想要的是什么?
答案 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 cpan。 Data::Alias或Lexical::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;