2011-11-05 53 views
1

我期待在別人的代碼,並且它們打開一個文件作爲例如:如何在Perl中跟蹤全局變量?

(open (FILEHANDLE,'/homedirectory/textfile.txt')) 

它們然後把每行的內容到一個變量進行處理(該文件的每一行包括由分離的數據的選項卡):

while(<FILEHANDLE>) { 
($var1, $var2, $var3, $var4) = split (/\t+/, $_); 

然後他做一樣的東西:

$index = join('_', $var1, $var2, $var3); 

,然後做到這一點(在那裏我抓我的頭的部分)

$contents = $filehandle{"$index"}; 

我嘗試打印出$contents,看上去就像是的$var1$var2$var3所有由分號分隔的值(例如「value1;value2;value3」)。此外,我將FILEHANDLE的名稱更改爲FILEHANDLE2,對$filehandle也做了同樣的處理,我得到了完全相同的結果,所以這讓我相信它們是相關的。另外,當單獨離開FILEHANDLE並將$filehandle更改爲$filehandle2時,沒有任何顯示。任何幫助將不勝感激,因爲我已經停留了很長一段時間。另外,我是perl n00b ...(我主要用Python編程)。

按要求,這裏是代碼的更完整的版本:

sub myfn{ 
    $filename = "home/textfile.txt"; 
    open(FILEHANDLE, $filename) || die "Can't find filename\n"; 
    while (<FILEHANDLE>) { 
     ($var1, $var2, $var3) = split (/\t+/, $_); 
     $used_index = join ('_', $var1, $var2, $var3); 
     $tmp_index = uc ($used_index) 
     $contents = $filehandle{"$tmp_index"}; 

要清楚,$filehandle在這個節骨眼上出現的第一次......也可能是注意到的東西用類似的名字被先前設置,但它是這樣的:

abcd_filehandle{"$randomvar} = "VALUEX;VALUEY;VALUEZ"; 
+3

您是否可以發佈完整的代碼段? – FailedDev

+0

當然,給我幾個。 – deweyredman

+0

這看起來並不像正確的語法。你能否複製/粘貼代碼而不是鍵入它? (例如,你確定它是'$ filehandle('而不是'$ filehandle {'或'$ filehandle ['? – DVK

回答

0

perldoc perlopentut。無論

open FILEHANDLE, '<', 'filename' or die $!; 
while (<FILEHANDLE>) { 
    # do something with $_ 
} 
close FILEHANDLE; 

open $filehandle, '<', 'filename' or die $!; 
while (<$filehandle>) { 
    # do something with $_ 
} 
close $filehandle; 

是有效的方法來打開和讀取文件,但裸字FILEHANDLE和標量$filehandle無關彼此(除非您之前設置$filehandle = \*FILEHANDLE或類似的東西)。你甚至可以做

open my $filehandle, '<', 'filename' or die $!; 
while (<$filehandle>) { 
    # do something with $_ 
} 
# file is closed automatically when $filehandle goes out of scope 

實際上,有些人會認爲這是在現代Perl中打開文件的推薦方式。

+0

事情似乎是$ filehandle是某種散列......它沒有使感覺t我也是這樣,並且這個人根本沒有評論他們的代碼,所以很難通讀:( – deweyredman

+0

@ user1030592:'$ filehandle {$ index}'指的是散列'%filehandle中由'$ index'索引的條目'。它與標量變量'$ filehandle'沒有任何關係(除非生活在同一個符號表項中,如果它是一個包變量)。我同意這可能會令人困惑(顯然,拉里沃爾也是如此);有關詳細信息,請參見[perldoc perldata](http://perldoc.perl.org/perldata.html)。 –

7

簡短的回答:由於Karonen先生提到,標識符filehandle(在你的情況,考慮使用$filehandle{$key},標識符是散列%filehandle)無關與裸字FILEHANDLE。它們恰好被命名爲相似的(但完全不同,因爲Perl區分大小寫)。

最有可能的是,散列%filehandle - 由於它的值看起來實際上並不是文件句柄,所以名稱非常糟糕 - 在代碼中的其他位置填充。爲了驗證這一點,你需要做兩件事情:

  • 運行一個grep命令你的文件,如下所示:grep filehandle your_file.pl

  • 檢查什麼散列的內容是當子程序調用,通過啓動你的方法用:

    sub myfn{ 
        use Data::Dumper; 
        print Data::Dumper->Dump([\%filehandle]); 
    
  • 看到該變量是在代碼通過Perl調試改變,以通過運行腳本(拍攝當前命令行並用perl -d預PEND它)。當在調試器,通過發出命令w %filehandle設置監視表達式,然後通過c執行腳本(繼續)

看代碼發佈,它似乎已經在使用全局變量的形式非常差被寫入。你理解它的問題是爲什麼在任何語言中使用全局變量都是非常糟糕的想法的完美例子。將此代碼與我爲此編寫的代碼進行對比(前提是我的猜測對於%文件句柄的含義是正確的):

# Caller code 
my %file_data = (1=>2); # What the original code called %filehandle hash 
myfn(\%file_data); # Pass by reference 

sub myfn { 
    my($file_data) = @_; # A hashref, passed from caller code 
    my $filename = "home/textfile.txt"; 
    open(my $filehandle, "<", $filename) || die "Can't find filename. Error: $!\n"; 
    while (<$filehandle>) { 
     my ($var1, $var2, $var3) = split (/\t+/, $_); 
     my $used_index = join ('_', $var1, $var2, $var3); 
     my $uc_index = uc($used_index); 
     my $contents = $file_data->{$uc_index}; # Using -> to dereference hashref 
+0

謝謝我將使用perl調試器!就像我說的我是Perl的新手,所以:( – deweyredman

+0

)另外,在調試器中,您可以通過'myfn'來設置myfn上的斷點;執行'c'去到那個斷點,然後通過' x%filehandle' – DVK

+0

即使它們有相同的大小寫,'FILEHANDLE'(簡寫爲「* FILEHANDLE」)與'%FILEHANDLE'不是同一個變量。 – ikegami