2013-06-24 43 views
1

這似乎是一件很奇怪的事情,但如何在散列本身內部引用散列呢?這裏就是我想要做的事:perl如何引用散列本身

我有哈希散列,並在最後一分,如:

my $h = { A => [...], B => [...], ..., EXPAND => sub { ... } }; 

。我正在執行EXPAND以查看密鑰C是否存在於此散列中,如果存在,請插入另一個密鑰值對D

所以我的問題是,如何將引用傳遞給子,而不使用散列的變量名?我希望需要做到這一點幾個哈希值,我不想繼續改變子參考它目前在哈希的名稱。

+6

只是一個評論,但''''''''括號是數組而不是散列。 –

+0

此外,它似乎有一個*數組*的Hashrefs,而不是散列。 –

+0

@darch因爲這樣的散列數量散佈在一堆文件中,我希望添加這個子文件不會涉及到另一層對變量名稱的解析 – lzt

回答

4

你在那裏有一些嵌套數組引用,而不是哈希。讓我們假設你實際上意味着你有這樣的事情:

my $h = { A => {...}, B => {...}, ..., EXPAND() }; 

在這種情況下,你不能引用$h從自己的定義中,因爲$h不存在,直到表達完全評估。

如果你的內容,使其兩條線,那麼你可以這樣做:後EXPAND()運行

my $h = { A=> {...}, B => {...} }; 
$h = { %$h, EXPAND($h) }; 
+0

(即使它確實存在,也沒有任何東西被分配給它,因爲你仍然在構建分配給它的值。) – ikegami

0

哈希在建(可能)會發生。我可能會使用這樣的:

$h = EXPAND({ A=>... }) 

EXPAND(...)返回修改後的hashref或克隆如果原來需要保持不變。

3

一般的解決方案是編寫一個函數,給定一個散列和一個函數來展開該散列,然後返回該散列並添加擴展函數。我們可以在擴展函數中關閉散列,這樣就不需要在其中提及散列的名稱。這看起來是這樣的:

use strict; 
use warnings; 
use 5.010; 

sub add_expander { 
    my ($expanding_hash, $expander_sub) = @_; 

    my $result = { %$expanding_hash }; 
    $result->{EXPAND} = sub { $expander_sub->($result) }; 

    return $result; 
} 

my $h = add_expander(
    { 
     A => 5, 
     B => 6, 
    }, 
    sub { 
     my ($hash) = @_; 

     my ($maxkey) = sort { $b cmp $a } grep { $_ ne 'EXPAND' } keys %$hash; 
     my $newkey = chr(ord($maxkey) + 1); 
     $hash->{$newkey} = 'BOO!'; 
    } 
); 

use Data::Dumper; 
say Dumper $h; 
$h->{EXPAND}->(); 
say Dumper $h; 

請注意,我們正在創建$h但該add_expander調用包含沒有提及$h。相反,傳遞給調用的子進程希望散列作爲第一個參數展開。對子上的散列運行add_expander將創建一個閉包,該閉包將記住該擴展器與哪個散列關聯並將其合併到散列中。

該解決方案假設擴展散列時發生的情況可能因主題散列而異,因此add_expander需要一個任意子節點。如果您不需要這種自由度,則可以將擴展子集合到add_expander中。