为什么要使用严格和警告?

TLP*_*TLP 100 perl

在我看来,如果人们使用以下内容,可以解决Perl标签中的许多问题:

use strict;
use warnings;
Run Code Online (Sandbox Code Playgroud)

我认为有些人认为这些类似于训练轮子或不必要的并发症,这显然不是真的,因为即使是非常熟练的Perl程序员也会使用它们.

似乎大多数精通Perl的人总是使用这两个pragma,而那些从使用它们中获益最多的人很少这样做.所以,我认为这将是一个好主意,有一个问题联系起来,鼓励人们时至use strictwarnings.

那么,为什么一个Perl的开发use strictwarnings

ike*_*ami 80

对于初学者来说,use strict;(并且在较小程度上use warnings;)有助于找到变量名称中的拼写错误.即使是有经验的程序员也会犯这种错 常见的情况是在清理或重构代码时忘记重命名变量的实例.

使用use strict; use warnings;捕获很多错误的速度会比捕获它们更快,这使得更容易找到错误的根本原因.根本原因可能是需要进行错误或验证检查,这可能发生在任何情况下或程序员的技能.

Perl警告的好处在于它们很少是虚假的,因此使用它们几乎没有任何成本.


相关阅读:为什么要使用my

  • @Jean,向后兼容.请注意,如果您使用的是版本5.12或更新的语言(`use 5.012;`),则默认启用`use strict;`. (4认同)
  • @TLP,我不打算做一项研究来量化它有多大帮助.应该说它们无条件地帮助就足够了. (2认同)

小智 27

显然use strict应该(必须)在你想要强制perl正确编码时使用,这可能是强制声明,明确字符串和subs,即裸字或谨慎使用refs.注意:如果有错误,则使用strict将中止执行(如果使用).

虽然use warnings;会帮助你找到程序中的输入错误,比如你错过了分号,你使用'elseif'而不是'elsif',你使用的是不推荐的语法或函数,不管怎样.注意:使用警告只会提供警告并继续执行,即不会中止执行..

无论如何,如果我们详细介绍,我会在下面详细说明

来自perl.com(我最喜欢的):

使用严格的'vars';

这意味着在使用变量之前必须始终声明变量.

如果您没有声明,您可能会收到未声明变量的错误消息

全局符号"$ variablename"需要在scriptname.pl第3行显式包名

这个警告意味着Perl并不完全清楚变量的范围是什么.所以你需要明确你的变量,这意味着要么声明它们,my所以它们只限于当前块,或者用它们的完全限定名称引用它们(例如:$ MAIN :: variablename).

因此,如果您尝试访问至少满足以下条件之一的变量,则会触发编译时错误:

  • 由Perl本身预定义,例如@ ARGV,%ENV和所有全局标点变量,例如$.或$ _.

  • 用我们(对于全局)或我(对于词汇)声明.

  • 从另一个包导入.(使用vars pragma伪造了一个导入,但是请使用我们的.)

  • 使用其包名称和双冒号包分隔符进行完全限定.

使用严格的"潜艇";

考虑两个程序

# 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
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,我们都有一个test_value()子,我们希望将其结果放入$ a.然而,当我们运行这两个程序时,我们会得到两个不同的结果:

在第一个程序中,在我们得到的时候$a = test_value;,Perl不知道任何test_value()sub,并且test_value被解释为字符串'test_value'.在第二个程序中,test_value()的定义位于该$a = test_value;行之前.Perl认为test_value是子调用.

顺便说一下,像test_value这样的孤立词的技术术语可能是子词,可能是依赖于上下文的字符串,也就是单词.Perl对裸字的处理可能令人困惑,并且可能导致程序中的错误.

错误是我们在第一个程序中遇到的错误,请记住Perl不会期待找到test_value(),所以因为它还没有看到test_value(),所以它假定你想要一个字符串.所以,如果你use strict subs;,它将导致该程序死于一个错误:

在./a6-strictsubs.pl第3行使用"strict subs"时,不允许使用Bareword"test_value".

此错误的解决方案是
1.使用括号清楚地表明您正在调用sub.如果Perl看到$ a = test_value();,
2.在第一次使用它之前声明你的sub

use strict;
sub test_value;  # Declares that there's a test_value() coming later ...
my $a = test_value;  # ...so Perl will know this line is okay.
.......
sub test_value { return "test_passed"; }
Run Code Online (Sandbox Code Playgroud)

3.如果你的意思是将它用作字符串,请引用它.

因此,这种限制使得Perl将所有裸字视为语法错误.*裸是任何没有上下文强制的其他解释的裸名称或标识符.(上下文通常是由附近的关键字或令牌,或者有问题的话的predeclaration被迫的.)*所以,如果你的意思是把它作为一个字符串,引号,并且如果你的意思是把它当作一个函数调用,预先声明它或使用括号.

由于这种不可预测的行为,Barewords是危险的.use strict; (or use strict 'subs';)使它们可预测,因为将来可能导致奇怪行为的裸词会使你的程序在它们造成严重破坏之前死亡

有一个地方,即使你打开严格的潜艇,也可以使用裸字:当你分配哈希键时.

$hash{sample} = 6;   # Same as $hash{'sample'} = 6
%other_hash = ( pie => 'apple' );
Run Code Online (Sandbox Code Playgroud)

散列键中的Barewords始终被解释为字符串,因此没有歧义.

使用严格的"参考";

如果您有意或无意地使用符号引用,则会生成运行时错误.然后将不是硬引用的值视为符号引用.也就是说,引用被解释为表示全局变量名称的字符串.

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.
Run Code Online (Sandbox Code Playgroud)

使用警告;

这种词法范围的编译指示允许灵活地控制Perl的内置警告,包括编译器发出的警告以及运行时系统发出的警告.

来自perldiag:

因此,可以使用warnings编译指示来控制来自以下分类的大多数警告消息,即W,D和S.

(W)警告(可选)
(D)弃用(默认启用)
(S)严重警告(默认启用)

我已经列出了一些警告消息,这些消息通常在分类下面发生.有关它们和其他消息的详细信息,请参阅perldiag

(W)警告(可选):

在%s中
缺少参数 - 缺少参数 - %c
(您的意思是&%s而不是?)
(您的意思是"本地"而不是"我们的"?)
(您的意思是$或@而不是%?)
'%s '不是
在%s上使用的代码引用长度()
数字错位_

(D)弃用(默认启用):

已弃用定义(@array)已
定义(%hash)已
弃用
不再支持在false条件$#中不再 使用my()

(S)严重警告(默认启用)

ELSEIF应该ELSIF
找到%s,其中运营商预期的
(缺少%S之前操作?)
(在上一行缺少分号?)
%从未推出
运营商或分号之前%失踪了
优先级的问题:打开%s应该是开放的(%S)
原型不匹配:%s vs%s
警告:使用没有括号的"%s"是不明确的
无法打开%s:%s


too*_*lic 10

这两个pragma可以自动识别代码中的错误.

我总是在我的代码中使用它:

use strict;
use warnings FATAL => 'all';
Run Code Online (Sandbox Code Playgroud)

FATAL使代码死于警告,就像strict那样.

有关其他信息,请参阅:严格使用警告FATAL =>'all';

另外...... 根据苏斯的说法,这种限制

  • @tchrist:这对我来说一直都很有用,也有记录.如果您发现某个文档无法正常工作,请使用`perlbug`修补文档. (6认同)

moo*_*ody 9

关于这个问题,perlmonks一个很好的主题.

显而易见的基本原因是严格和警告大量帮助您发现错误并帮助调试.