2013-11-27 39 views
1

我剛剛接管了一個Perl系統的維護。它用來運行的機器已經死機,所以我不知道它使用的是哪個版本的Perl,但它工作正常。它包括以下行以ASCII文本

my $lcnt = $#{@{$page{'lines'}}}; 

在Perl 5.10.1的頁面計數線(現在我們在CentOS 6.3上運行此)上面的代碼將不再有效。我反而使用以下,它工作正常。

my @arr = @{$page{'lines'}}; 
my $lcnt = $#arr; 

我承認我的Perl是不是很大但是從我所看到的第一個版本不應該曾作爲它試圖尊重一個數組,而不是一個數組引用

第一個問題 - 是我猜爲什麼第一行代碼現在不能正確工作,其次是由於之前的Perl版本中現在已修復的錯誤而導致更早工作?

謝謝!

+0

$#爲您提供數組的最後一個索引...如果數組包含行,$#arr是行數-1。在這裏你應該考慮使用標量來返回數組中元素的數量。 – Pierre

+0

是'$ page {'lines'}'一個數組還是一個引用? –

+0

「不再有效」是什麼意思?原始代碼不是語法錯誤 - 它現在做了什麼(我猜它會返回-1),它曾經做過什麼,以及你怎麼知道的? – pilcrow

回答

3

第一個版本從來沒有工作。假設$page{'lines'}是一個數組引用,這是你想要什麼:

my $lcnt = $#{$page{'lines'}}; 

注意,這將會給你比你的arraref項數少一個。 $#運算符是最後一項的INDEX,而不是項目的數量。如果你想在$page{'lines'}項目的數量,你可能想這一點:

my $lcnt = scalar(@{$page{'lines'}}); 
+0

在標量分配中使用'scalar()'是多餘的。但+1正確的答案。 – TLP

+0

@TLP感謝您的評論。雖然你在技術上是正確的,但我選擇在這種情況下使用標量()來明確我的意圖。最好的祝福。 – codnodder

1

你的代碼中的一些東西。此:

my $lcnt = $#{@{$page{'lines'}}}; 

從來都沒有錯。看看這三個東西會在這裏

$page{'lines'} # presumably an array ref 
@{ ... }   # dereference into an array 
$#{ ... }  # get last index of an array ref 

這相當於(繼續在自己的代碼):

my @arr = @{$page{'lines'}}; 
my $foo = @arr;     # foo is now the size of the array, e.g. 3 
my $lcnt = $#$foo; 

如果使用

use strict; 
use warnings; 

,你應該總是做,毫無疑問(!),你會得到信息致命錯誤消息:

Can't use string ("3") as an ARRAY ref while "strict refs" in use 

(其中3將是你數組的大小)

正確的方式來獲得尺寸(元素數目)的陣列是把數組中的標量上下文:

my $size = @{ $page{'lines'} }; 

的方式來獲得最後一個元素的索引使用$#印記:

my $last_index = $#{ $page{'lines'} }; 

正如你會注意到,語法是一樣的,它只是一個使用@$#得到你想要什麼樣的事,一樣的使用規則陣列

my $size = @array; 
my $last = $#array; 

所以,當爲,回頭參考:使用@$#不是並且從不正確。

+0

實際上,它*在過去工作(在5.8.8上測試過),可能是通過使'@arr - > [2]'與'$ arr [2]'同義的奇特點。但它絕對沒有*正確*。 – hobbs

+0

確實很奇怪。 – TLP

+0

@hobbs既然你是OP最喜歡的答案之一,也許你應該發表一個他可以接受的答案。 – TLP