簡體   English   中英

為什么使用嚴格和警告?

[英]Why use strict and warnings?

在我看來,如果人們使用以下方法,Perl 標簽中的許多問題都可以解決:

use strict;
use warnings;

我認為有些人認為這些類似於訓練輪或不必要的復雜性,這顯然不是真的,因為即使是非常熟練的 Perl 程序員也會使用它們。

似乎大多數精通 Perl 的人總是使用這兩個 pragma,而那些從使用它們中獲益最多的人很少這樣做。 所以,我認為在鼓勵人們use strictwarnings時有一個問題鏈接是個好主意。

那么,為什么 Perl 開發人員應該use strictwarnings呢?

首先, use strict; (並在較小程度上use warnings; )有助於查找變量名稱中的拼寫錯誤。 即使是有經驗的程序員也會犯這樣的錯誤。 一個常見的情況是在清理或重構代碼時忘記重命名變量的實例。

使用use strict; use warnings; use strict; use warnings; 比其他方式更早地捕獲許多錯誤,從而更容易找到錯誤的根本原因。 根本原因可能是需要進行錯誤或驗證檢查,無論程序員技能如何,都可能發生這種情況。

Perl 警告的好處在於它們很少是虛假的,因此使用它們幾乎沒有成本。


相關閱讀:為什么使用my

顯然,當您想強制 Perl 正確編碼時,應該(必須) use strict ,這可能會強制聲明,在字符串和子項上顯式,即裸字或謹慎使用 refs。 注意:如果有錯誤, use strict會中止執行。

use warnings; 將幫助您找到程序中的輸入錯誤,例如您錯過了分號,您使用了“elseif”而不是“elsif”,您使用的是不推薦使用的語法或函數,諸如此類。 注意:使用警告只會提供警告並繼續執行,即不會中止執行...

無論如何,如果我們詳細說明會更好,我在下面指定

來自perl.com (我最喜歡的):

使用嚴格的“變量”;

這意味着您必須始終在使用變量之前聲明它們。

如果您不聲明,您可能會收到未聲明變量的錯誤消息:

全局符號“$variablename”需要在 scriptname.pl 第 3 行顯式包名

這個警告意味着 Perl 並不清楚變量的作用域是什么。 所以你需要明確你的變量,這意味着要么用my聲明它們,所以它們僅限於當前塊,要么用它們的完全限定名稱(例如:$MAIN::variablename)引用它們。

因此,如果您嘗試訪問至少不滿足以下條件之一的變量,則會觸發編譯時錯誤:

  • 由 Perl 本身預定義,例如@ARGV%ENV ,以及所有全局標點變量,例如$ $_

  • 用 our(對於全局)或 my(對於詞法)聲明。

  • 從另一個包導入。 use vars pragma 偽造了一個導入,但使用our代替。)

  • 使用其包名和雙冒號包分隔符進行完全限定。

使用嚴格的“subs”;

考慮兩個程序

# prog 1
   $a = test_value;
   print "First program: ", $a, "\n";
   sub test_value { return "test passed"; }
 Output: First program's result: test_value

# prog 2
   sub test_value { return "test passed"; }
   $a = test_value;
   print "Second program: ", $a, "\n";
 Output: Second program's result: test passed

在這兩種情況下,我們都有一個 test_value() sub 並且我們想將它的結果放入 $a 中。 然而,當我們運行這兩個程序時,我們得到了兩個不同的結果:

在第一個程序中,我們得到$a = test_value; , Perl 不知道任何 test_value() 子,並且 test_value 被解釋為字符串 'test_value'。 在第二個程序中,test_value() 的定義出現在$a = test_value;之前$a = test_value; 線。 Perl 認為 test_value 是子調用。

對於隔離的話猶如test_value這可能是潛艇,並且可能依賴於上下文字符串的技術術語,順便說一句,是裸字 Perl 對裸字的處理可能會令人困惑,並且可能導致程序中的錯誤。

這個 bug 就是我們在第一個程序中遇到的,記住 Perl 不會期待找到test_value() ,所以因為它還沒有看到 test_value(),它假設你想要一個字符串。 所以如果你use strict subs; ,它會導致這個程序因錯誤而死亡:

在 ./a6-strictsubs.pl 第 3 行使用“strict subs”時不允許使用裸詞“test_value”。

此錯誤的解決方案是

  1. 使用括號明確表示您正在調用 sub。 如果 Perl 看到 $a = test_value();,

  2. 在你第一次使用它之前聲明你的子

    使用嚴格; 子測試值; # 聲明稍后會有一個 test_value() ... my $a = test_value; # ...這樣 Perl 就會知道這行代碼沒問題。 ....... sub test_value { return "test_passed"; }

  3. 如果您打算將其用作字符串,請引用它。

因此,這種限制使 Perl 將所有裸詞都視為語法錯誤。 一個裸是任何裸名稱或標識符,沒有上下文強制的其他解釋。 (上下文通常由附近的關鍵字或標記或相關單詞的預先聲明強制。)因此,如果您打算將其用作字符串,請引用它;如果您打算將其用作函數調用,請預先聲明它或使用括號。

由於這種不可預測的行為,裸詞很危險。 use strict; (or use strict 'subs';) use strict; (or use strict 'subs';)使它們可預測,因為將來可能導致奇怪行為的裸詞將使您的程序在它們造成嚴重破壞之前死亡

有一個地方可以使用裸詞,即使您打開了嚴格的 subs:當您分配哈希鍵時。

$hash{sample} = 6;   # Same as $hash{'sample'} = 6
%other_hash = ( pie => 'apple' );

哈希鍵中的裸詞總是被解釋為字符串,所以沒有歧義。

使用嚴格的“參考”;

如果您有意或無意地使用符號引用,則會產生運行時錯誤。

不是硬引用的值然后被視為符號引用 也就是說,引用被解釋為表示全局變量名稱的字符串。

use strict 'refs';

$ref = \$foo;       # Store "real" (hard) reference.
print $$ref;        # Dereferencing is ok.

$ref = "foo";       # Store name of global (package) variable.
print $$ref;        # WRONG, run-time error under strict refs.

使用警告;

這個詞法范圍的 pragma 允許靈活控制 Perl 的內置警告,包括編譯器發出的警告和運行時系統發出的警告。

perldiag

因此,可以使用warnings編譯指示控制來自以下分類(即 W、D 和 S)的大多數警告消息。

(W) 警告(可選)
(D) 棄用(默認啟用)
(S) 嚴重警告(默認啟用)

我已經按分類列出了一些經常出現在下面的警告消息。 有關它們和其他消息的詳細信息,請參閱perldiag

(W) 警告(可選):

%s 中缺少參數
缺少 -%c 的參數
(你是說 &%s 嗎?)
(你的意思是“本地”而不是“我們的”?)
(你的意思是 $ 或 @ 而不是 %?)
“%s”不是代碼引用
%s 上使用的 length()
數字錯位 _

(D) 棄用(默認啟用):

已定義(@array)已棄用
已定義(%hash)已棄用
不推薦在 false 條件中使用 my()
不再支持 $#

(S) 嚴重警告(默認啟用)

elseif 應該是 elsif
%s 找到操作員預期的位置
(在 %s 之前缺少運算符?)
(前一行缺少分號?)
%s 從未介紹過
%s 之前缺少運算符或分號
優先級問題:open %s 應該是 open(%s)
原型不匹配:%s 與 %s
警告:不帶括號的“%s”的使用不明確
無法打開 %s: %s

這兩個 pragma 可以自動識別代碼中的錯誤。

我總是在我的代碼中使用它:

use strict;
use warnings FATAL => 'all';

FATAL使代碼在警告時死亡,就像strict一樣。

有關其他信息,請參閱:使用警告更嚴格 FATAL => 'all';

也......根據蘇斯的說法,這些限制

關於這個問題的perlmonks一個很好的線程

根本原因顯然是嚴格和警告可以大量幫助您發現錯誤並幫助調試。

來源:不同的博客

Use 將通過調用模塊 import() 函數將函數和變量名稱導出到主命名空間。

pragma 是一個模塊,它影響 Perl 的編譯時或運行時行為的某些方面。 Pragma 為編譯器提供提示。

使用警告 - Perl 會抱怨變量只使用一次以及將字符串不正確地轉換為數字。 嘗試寫入未打開的文件。 它發生在編譯時。 它用於控制警告。

使用嚴格 - 聲明變量范圍。 它用於在腳本中設置某種規則。 如果在代碼中使用了裸字,它們將被解釋。 所有變量都應該有作用域,比如 my、our 或 local。

“use strict”指令告訴 Perl 在你的代碼編譯期間做額外的檢查。 使用此指令將節省您調試 Perl 代碼的時間,因為它會發現您可能會忽略的常見編碼錯誤。

嚴格和警告確保您的變量不是全局變量。

能夠為各個方法擁有唯一的變量而不是必須跟蹤每個變量名稱要簡潔得多。

$_ 或某些函數沒有變量,也可用於更快地編寫更緊湊的代碼。

但是,如果您不使用嚴格和警告,則 $_ 將變為全局!

use strict;
use warnings;

嚴格和警告是 Perl 程序的模式。 它允許用戶更自由地輸入代碼,不僅如此,Perl 代碼將變得正式,其編碼標准將有效。

警告與 Perl shebang行中的-w含義相同,因此它將為您提供由 Perl 程序生成的警告。 它將顯示在終端中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM