2013-07-10 36 views
2

編程的新手。任務是從一個字符串中提取特定的數據,我選擇瞭如下編寫代碼 -更好的變量命名系統?

while ($line =<IN>) { 
    chomp $line; 
    @tmp=(split /\t/, $line); 
    next if ($tmp[0] !~ /ch/); 
    @[email protected][8..11]; 
    @[email protected][12..14]; 
    @[email protected][15..17]; 
    @[email protected][18..21]; 
    foreach (1..4) { 
      print @tgt($_), "\n"; 
      } 

我想@tgt($_)將被解釋爲@tgt1, @tgt2, @tgt3, @tgt4,但我仍然得到錯誤信息@tgt是一個全球性的符號( @ tgt1,@ tgt2,@ tgt3,@ tgt4`已被聲明)。

Q1。我誤解了foreach循環嗎? Q2302。爲什麼不能perl看到@tgt($_)作爲@ tgt1,@ tgt2 ..等等? Q2302。從經驗來看,這可能是命名變量的不好方法。命名具有相似特徵的變量的首選方式是什麼?

+3

始終使用'使用嚴格;使用警告;' – ikegami

+0

對不起,Ikegami,我確實使用嚴格和警告,但我只粘貼了部分我認爲相關的代碼(正如警告和錯誤所示)。 –

+0

@BChen - 令我驚訝的是,@ tgt($ _)'甚至編譯:) – DVK

回答

7
  • Q2。爲什麼不能像@ tgt1,@ tgt2 ..etc那樣看到@tgt($ _)?第二季度銷售價格下降,第二季度銷售價格下降。從經驗來看,這可能是命名變量的不好方法。命名具有相似特徵的變量的首選方式是什麼?

我一起asnswer兩者。

@tgt($_)並不意味着你希望是什麼意思

  • 首先,它是一個無效的語法(不能使用()數組名後,PERL interpeter會產生一個編譯錯誤)。

  • 你想要做什麼的通過導致它的名字(又名symbolic references)的表達式訪問變量是訪問不同的變量。這是可能的;但通常是一個糟糕的想法和糟糕的Perl風格(因爲你可以,但你不應該這樣做,沒有很好的理由)。

  • 要以您嘗試的方式訪問元素$ _,請使用@{"tgt$_"}語法。但我重複 - 不要那樣做,即使你可以。

  • 正確的慣用的溶液:使用arrayrefs的陣列,用你的1-4(或更確切地說0-3)索引外陣列:

    # Old bad code: @[email protected][8..11]; 
    
    # New correct code: 
    $tgt[0]=[ @tmp[8..11] ]; # [] creates an array reference from a list. 
    # etc... repeat 4 times - you can even do it in a smart loop later. 
    

    但這是什麼,它存儲一個將數組切片引用到單個@tgt數組的第零個元素中。

    最後,@tgt數組有4個元素,每個元素對包含其中一個切片的數組的數組引用。


  • Q1。我誤解了foreach循環嗎?

你的foreach循環(而不是它的內容 - 見上文)是正確的,有一個風格的警告 - 再次,雖然你可以使用默認的$_變量,你應該幾乎從來不使用它,而不是總是使用爲了可讀性命名變量。

您打印arrayrefs的上述排列如下(單獨詢問是否有任何語法不清 - 這是一箇中等水平的數據結構處理,不適合初學者):

foreach my $index (0..3) { 
    print join(",", @{ $tgt[$index]}) . "\n"; 
} 
+0

非常感謝!初學者的絕佳解釋! (你應該嘗試寫一本書/教程的排序!!)我讀了一些關於參考,但沒有得到我的頭在它對我的編碼有用。 –

+0

@BChen - [這是我的書](http://stackoverflow.com/users/119280/dvk?tab=answers&sort=votes):)並感謝你的客氣話。堅持下去,Perl是超級強大的,訣竅是知道什麼時候不要濫用權力,代價是無法讀取無法讀取的代碼,因爲沒有明顯的收益。通常有很多做事的方式,有些更適合不同的目標。 – DVK