這是一個罕見的情況下,local
可能是一個對您有用:
my $hash => {
a => 123,
b => 234,
c => {
option1 => 123,
option2 => 235,
},
};
sub sub1 {
# We only need hash values a and b
delete local $hash->{c};
print "sub1: $_\n" for sort keys %$hash;
}
sub sub2 {
# sub2 needs all a, b and c.
print "sub2: $_\n" for sort keys %$hash;
}
sub1();
sub2();
的輸出將是
sub1: a
sub1: b
sub2: a
sub2: b
sub2: c
關鍵字「本地」局部化的密鑰,以便將其刪除被撤銷時的範圍退出。 Perl的文檔中最好的解釋是perlsub: Localized deletion of elements of composite types。
還有一點要提出的是,它通常是有益的參數傳遞到一個子程序,而不是從周邊範圍吸收他們:
my $hash = {
a => 'foo',
b => 'bar',
c => {baz => 'bang'},
};
sub sub1 {
my $href = shift;
delete local $href->{c};
print "sub1: $_\n" for sort keys %$href;
}
sub sub2 {
my $href = shift;
print "sub2: $_\n" for sort keys %$href;
}
sub1($hash);
sub2($hash);
即使使用這樣的變化,在$href
非本地化元素的修改將傳播回到$hash
,因爲你通過引用傳遞。但它仍然是一個很好的習慣,因爲它提高了可讀性,並將子程序從周圍範圍的命名中解耦出來,這有望爲更多的可重用子文件做出貢獻。
偶爾有用的另一種技術是對傳入的結構進行深度克隆,以至於您可以自由修改克隆而不必將更改傳播回傳遞給子例程的指示對象。然而,如果元素包含對象而不是普通的舊值或嵌套值,則這可能是昂貴的(甚至不可能)。儘管如此,完整性我會提到Storable'sdclone
功能,這可能會這樣使用:
use Storable qw(dclone);
my $hash = {
a => 123,
b => 234,
c => {option1 => 123, option2 => 235},
};
sub sub1 {
my $href = shift;
my $clone = dclone($href);
delete $clone->{c};
print "sub1: $_\n" for sort keys %$clone;
}
sub sub2 {
my $href = shift;
print "sub2: $_\n" for sort keys %$href;
}
sub1($hash);
sub2($hash);
dclone
不是克隆一個數據結構的唯一途徑。您可以編寫自己的解決方案,更適合您的具體情況,特別是如果您事先知道結構的形狀和組成。但作爲一個通用的解決方案,它非常有用。
但最終dclone
將創建一個全新的數據結構,而不是隻是暫時隱藏一個密鑰,這是delete local $href->{c}
做的。如果您可以使用local
來避免創建結構的副本,或者消除必須手動將值存入的錯誤和額外考慮的潛在來源(即my $temp = delete $href->{c}; ... $href->{c} = $temp;
),那麼您已經找到了一個那些時候它變成了這個工作的正確工具。
如果您可以提供您在每個子項目中嘗試完成的粗略示例,則可能會出現適當的解決方案。 –