2014-11-06 97 views
6

我越來越:Perl的警告:未初始化值的使用在加入或串

"Use of uninitialized value in join or string at ./test_script.pl line 69, <fh> line 91." 

的代碼創建這個警告是在這裏:

# Write results of SQL execution to output file 
if ([email protected]) { print "\n DB Error : ", [email protected]; exit; } 
open(FH, ">$output_file") or 
     die "\n cannot write to the file $output_file. Check the file permissions"; 
while(my @row= $sth->fetchrow_array) { 
     print FH join($delimiter, @row). "\n"; 
} 

它是從「打印未來.. 。加入....「行中的」while「塊,但我不確定100%是什麼導致它以及如何糾正它。

$分隔符被初始化爲我的$ delimiter =「|」並且@row從前一行中的$ sth操作獲取它的值。

這是關於@row值的「計時」問題還是它正在處理的實際SQL查詢文件中的某些內容,如警告中的「< fh>第91行」部分所示?關於如何避免警告的任何想法? 順便說一句,該腳本工作正常,它只是產生一個警告,每個@row取值,這將產生大量的數據集拉的警告...

+0

您的查詢看起來像什麼或生成查詢的代碼是什麼? – SBH 2014-11-06 17:40:50

+1

向您自己證明$分隔符有一個值。在打印之前加上這個:'print'delimiter >>> $ delimiter <<< \ n「;' – toolic 2014-11-06 17:41:22

+4

如果我猜測,'@ row'中的一列是'NULL'。 – nandhp 2014-11-06 17:42:01

回答

11

@row可能包含一些元素有一個未定義的值,可能是因爲數據庫中填充@row的一列或多列爲NULL

perl -we 'my @array = ("Hello",undef,"world!"); print join("|",@array) . "\n";' 

,將產生的輸出是:

Use of uninitialized value $array[1] in join or string at -e line 1. 
Hello||world! 

之所以出現這種情況是因爲join試圖行爲可以同時還在一個簡單的Perl的一行像這樣使用join被模仿加入一個值,如果未從「未定義」升級到「已定義」,則不會進行字符串化。字符串化undef會生成此警告消息,提醒您可能正在做一些無意的事情,並且不正確。

一個更簡單的例子可能是這樣的:

$ perl -we 'my $scalar; print "$scalar\n";' 
Use of uninitialized value $scalar in concatenation (.) or string at -e line 1. 

再次,我們得到了警告,因爲我們要插一個未定義的值轉換成字符串。插值會導致字符串化,並且未定義值的字符串化通常會引發警告,讓您知道您可能犯了錯誤。遞給join()

print FH join($delimiter, map { defined ? $_ : '' } @row) . "\n"; 

這前處理@row

如果你不介意默默地undef的升級到一個空字符串,你可以這樣做。對於@row中的每個元素,如果元素具有未定義的值,則該值由空字符串替代,該字符串已定義,但視覺上很安靜。

另一種可能性是$delimiter未定義。通過打印進行測試,如果事實證明是這樣的話,那麼需要採取措施來解決這個問題就是確保它實際上包含一個值。

只要在緊密的詞彙範圍內使警告靜音也可以,儘管從哲學的角度來看,一種方法可以消除原因,另一種方法可以消除其中一種症狀。在其他地方描述的「no warnings 'uninitialized';方法就是這樣做的;沉默警告。當你知道自己正在做的事情完全正常時,你會這樣做,但你也知道Perl會警告你,因爲很多時候這是一個錯誤。這可能是這種情況;你可能會很滿意,只要讓join內部發生未定義值的沉默串化。如果是這種情況,請繼續並且禁止警告。最重要的是,你知道它是什麼意思,覈實是什麼造成的,然後做出明智的決定,該怎麼做。

+1

的值如果有人發現這種情況,則使用defined是明確的,如圖所示。它需要是map {defined $ _? $ _:''} – mark 2015-07-22 12:29:35

+0

'perl'在這裏沒有任何歧義,在'perldoc -f defined'中討論了'defined'在沒有其他參數的情況下回退到使用'$ _'作爲參數的事實。三元運算符的使用不是不明確的。並且記錄了'map'將'$ _'作爲它正在迭代的列表元素的別名。這歸結爲風格問題,可能在PBP中提到。 – DavidO 2015-07-22 15:13:54

+0

實際上,是的,這是一個PBP問題,放入* Iterator變量*標題,第105-107頁。這個PBP建議似乎沒有引用歧義,而是可讀性。如果可讀性是關注的話,我不會不同意。 – DavidO 2015-07-22 15:27:28

相關問題