簡體   English   中英

在 Perl 中更改哈希的引用

[英]Change ref of hash in Perl

我遇到了這個,找不到答案。 我想看看是否可以“更改”散列的引用。 換句話說,我有一個散列和一個返回散列引用的函數,我想讓散列指向此引用指定的內存中的位置,而不是復制它指向的散列的內容。 代碼如下所示:

%hash = $h->hashref;

我明顯的猜測是它應該是這樣的:

\%hash = $h->hashref;

但這給出了錯誤:

無法在標量賦值中修改引用構造函數

我嘗試了其他一些事情,但沒有任何效果。 我正在嘗試的實際上可能嗎?

Perl 5.21.5 中添加了一個實驗性功能,它似乎允許您完全按照您所描述的進行操作,這是一個開發版本(請參閱“通過參考使用別名”)。

聽起來你想要:

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::AliasLexical::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM