[英]Change ref of hash in Perl
我遇到了這個,找不到答案。 我想看看是否可以“更改”散列的引用。 換句話說,我有一個散列和一個返回散列引用的函數,我想讓散列指向此引用指定的內存中的位置,而不是復制它指向的散列的內容。 代碼如下所示:
%hash = $h->hashref;
我明顯的猜測是它應該是這樣的:
\%hash = $h->hashref;
但這給出了錯誤:
無法在標量賦值中修改引用構造函數
我嘗試了其他一些事情,但沒有任何效果。 我正在嘗試的實際上可能嗎?
聽起來你想要:
use Data::Alias;
alias %hash = $h->hashref;
或者如果 %hash 是一個包變量,你可以改為:
*hash = $h->hashref;
但無論哪種方式,這幾乎總是應該避免的。 只需使用哈希引用。
對,但是…
Perl 中的引用是標量。 您正在嘗試為返回值設置別名。 這實際上是可能的,但你不應該這樣做,因為它涉及到符號表的混亂。 此外,這只適用於全局變量(用our
聲明):如果您將 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
報告,但是您不應該因為語法上的perlcritic
而污染包命名空間。 此外,它不適用於詞法變量(這是您在大多數情況下可能想要使用的,因為它們是詞法范圍的,而不是包范圍的)。
另一個問題是,如果$h->hashref
方法更改其返回類型,您將突然分配給另一個表條目! (因此,如果$h->hashref
將其返回類型更改為 arrayref,則分配給 @hash,祝您好運檢測到這一點)。 您可以通過檢查$h->hashref
真的返回帶有'HASH' eq ref
$h->hashref` 的 hashref 來規避這一點,但這會破壞目的。
只保留參考有什么問題? 如果你得到一個引用,只需將它存儲在一個標量中:
$hash = $h->hashref
要閱讀有關全局符號表的更多信息,請查看perlmod並考慮perlref用於*FOO{THING}
語法,遺憾的是它不適用於左值。
為了實現你想要的,你可以查看cpan 上的幾個別名模塊。 Data::Alias或Lexical::Alias似乎符合您的目的。 此外,如果您對tie
語義感興趣和/或不想使用XS
模塊, Tie::Alias可能值得一試。
這個問題真的很老了,但是 Perl 現在允許將這種事情作為實驗性功能:
use v5.22;
use experimental qw(refaliasing);
my $first = {
foo => 'bar',
baz => 'quux',
};
\my %hash = $first;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.