[英]Deferencing hash of hashes in Perl
抱歉,這篇漫長的文章對Perl的資深人士來說,該代碼應該很容易理解。 我是Perl的新手,我試圖弄清楚這段代碼:
my %regression;
print "Reading regression dir: $opt_dir\n";
foreach my $f ( glob("$opt_dir/*.regress") ) {
my $name = ( fileparse( $f, '\.regress' ) )[0];
$regression{$name}{file} = $f;
say "file $regression{$name}{file}";
say "regression name $regression{$name}";
say "regression name ${regression}{$name}";
&read_regress_file( $f, $regression{$name} );
}
sub read_regress_file {
say "args @_";
my $file = shift;
my $href = shift;
say "href $href";
open FILE, $file or die "Cannot open $file: $!\n";
while ( <FILE> ) {
next if /^\s*\#/ or /^\s*$/;
chomp;
my @tokens = split "=";
my $key = shift @tokens;
$$href{$key} = join( "=", @tokens );
}
close FILE;
}
say
行是我添加到調試的內容。
我的困惑是子例程read_regress_file
的最后一部分。 看來href
是my $href = shift;
行中的引用my $href = shift;
。 但是,我試圖弄清楚如何首先引用傳遞的哈希。
%regression
是一個鍵為$name
的哈希。 代碼讀取的.regress
文件是簡單文件,包含變量及其值,形式為:
var1=value
var2=value
...
所以看起來像線
my $name = (fileparse($f,'\.regress'))[0];
正在將鍵創建為標量和線
$regression{$name}{file} = $f;
實際上使$name
成為一個哈希。
在我的調試行中
say "regression name $regression{$name}";
打印參考,例如
regression name HASH(0x7cd198)
但
say "regression name ${regression}{$name}";
打印一個名稱,例如
regression name {filename}
大括號內的文件名。
但是,使用
say "regression name $$regression{$name}";
什么都不打印。
根據我的理解, regression
似乎是一個實際的哈希,但是引用是嵌套的哈希name
。
為什么使用花括號的參考測試行有效,而另一種取消引用( $$
)無效?
另外,為什么在打印時該名稱仍用花括號括起來? 我不應該取消引用$name
嗎?
如果很難理解,對不起。 我很困惑實際引用了哪個哈希值,以及如果引用是嵌套哈希值時如何尊重它們。
這是困難的一個。 您已經找到了一些非常尷尬的代碼,這些代碼顯示了Perl中的錯誤,而對於取消引用Perl數據結構卻感到困惑。 標准Perl安裝包括完整的文檔集,我建議您看一下perldoc perlreftut
,也可以從perldoc.com在線獲得。
最明顯的是,您正在編寫非常老式的Perl。 使用符號&
調用Perl子還沒有考慮好做法,因為V5.8是十四年前發布
我認為,在第一個for
循環的開始時,沒有太多需要超越您明確的實驗行。 一旦您了解了這一點,其余的應該遵循
say "file $regression{$name}{file}";
say "regression name $regression{$name}";
say "regression name ${regression}{$name}";
首先,在字符串中擴展數據結構引用是不可靠的。 Perl嘗試執行您的意思,但是很容易寫出含糊不清的東西而沒有意識到。 通常最好使用printf
以便您可以分別指定嵌入值。 例如
printf "file %s\n", $regression{$name}{file};
也就是說,您有問題。 $regression{$name}
訪問其鍵等於$name
的哈希%regression
元素。 該值是對另一個哈希的引用,因此該行
say "regression name $regression{$name}";
打印類似
regression name HASH(0x29348b0)
你真的不想看到
您的第一次嘗試$regression{$name}{file}
訪問具有密鑰file
的輔助哈希的元素。 很好
但是${regression}{$name}
應該與$regression{$name}
。 在字符串外面,但是在字符串里面,就像${regression}
和{$name}
一樣
對於我來說,這里確實有太多問題,無法開始猜測您的卡住位置,尤其是在無法談論具體細節的情況下。 但是如果我這樣重寫初始代碼可能會有所幫助
my %regression;
print "Reading regression dir: $opt_dir\n";
foreach my $f ( glob("$opt_dir/*.pl") ) {
my ($name, $path, $suffix) = fileparse($f, '\.regress');
$regression{$name}{file} = $f;
my $file_details = $regression{$name};
say "file $file_details->{file}";
read_regress_file($f, $file_details);
}
我已經將哈希引用復制到$file_details
並像這樣將其傳遞給子例程。 您是否可以看到%regression
每個元素都由文件名鍵入read_regress_file
,並且每個值都是對另一個哈希的引用,該哈希包含由read_regress_file
填充的值?
我希望這有幫助。 這實際上不是講語言基礎的論壇,所以我認為我不能做得更好
我了解的是:
$regression{$name}
表示一個hashref,如下所示:
{ file => '...something...'}
因此,為了取消引用$regression{$name}
返回的hashref,您必須執行以下操作:
%{ $regression{$name} }
為了獲得完整的哈希值。
為了獲得哈希的文件屬性,請執行以下操作:
$regression{$name}->{file}
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.