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

时间:2011-11-05 23:04:23

标签: perl

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

use strict;
use warnings;

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

似乎大多数精通Perl的人总是使用这两个pragma,而那些从使用它们中获益最多的人很少这样做。所以,我认为在鼓励人们use strictwarnings时,有一个问题可以链接到。

那么,为什么Perl开发人员use strictwarnings

8 个答案:

答案 0 :(得分:78)

首先,use strict;(在较小程度上,use warnings;)可帮助查找变量名称中的拼写错误。即使是有经验的程序员也会犯错。一个常见的情况是在清理或重构代码时忘记重命名变量的实例。

使用use strict; use warnings;会比其他方式捕获更多错误,这样可以更容易地找到错误的根本原因。根本原因可能是需要进行错误或验证检查,而且无论是程序员还是程序员技能都可能发生这种情况。

Perl警告的好处在于它们很少是虚假的,因此使用它们是免费的。


相关阅读:Why use my?

答案 1 :(得分:27)

当你想要强制perl正确编码时,{必须} use strict应该被使用,这可能是强制声明,明确表示字符串和sub,即裸字或谨慎使用refs。 注意:如果有错误,使用严格将中止执行(如果使用)。

虽然use warnings;会帮助您在程序中找到输入错误,例如您错过了分号,但您使用了' elseif'而不是' elsif',您正在使用已弃用的语法或函数,无论如何。 注意:使用警告只会提供警告并继续执行,即不会中止执行..

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

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

使用严格的';

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

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

  

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

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

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

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

  • 宣布与我们(为全球)或我(对于词汇)。

  • 从其他包导入。 (使用vars pragma伪造了一个导入,但请使用我们的。)

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

使用严格的' 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()子,我们希望将其结果放入$ a。然而,当我们运行这两个程序时,我们得到两个不同的结果:

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

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

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

  

Bareword" test_value"不允许的时候"严格的潜艇"在使用中   ./a6-strictsubs.pl第3行。

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

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"; }

3。如果您的意思是将其用作字符串,请引用它。

因此,这种限制使得Perl将所有裸字视为语法错误。 * bareword 是任何没有上下文强制的其他解释的裸名称或标识符。 (上下文通常由附近的关键字或标记强制执行,或者通过预先声明相关单词来强制执行。)*所以如果你的意思是将它用作字符串,引用它并且如果你的意思是将它用作函数调用,则预先声明它或使用括号。

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

即使您已经开启了严格的潜艇,也可以使用裸字:当您分配哈希键时,可以使用裸字。

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

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

使用严格' refs';

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

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.

使用警告;

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

来自perldiag

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

  

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

     

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

     

(W)警告(可选):

     

%s中缺少参数
  缺少参数 - %c
  (你的意思是&%s代替吗?)
  (你的意思是"本地"而不是"我们的"?)
  (你的意思是$或@而不是%?)
  '%S'不是代码参考
  %s上使用的length()   错位_在数字

     

(D)弃用(默认情况下启用):

     

已定义(@array)已弃用   已弃用定义的(%哈希)   在虚假条件中不推荐使用my()   $#不再受支持

     

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

     

elseif应该是elsif
  找到运营商预期的%s   (在%s之前缺少操作员?)
  (前一行缺少分号?)
  %s从未介绍过   %s之前缺少运算符或分号   优先问题:打开%s应该打开(%s)
  原型不匹配:%s vs%s
  警告:使用"%s"没有括号的是模棱两可的   无法打开%s:%s

答案 2 :(得分:10)

这两个编译指示可以自动识别代码中的错误。

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

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

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

有关其他信息,请参阅:Get stricter with use warnings FATAL => 'all';

另外...... The strictures, according to Seuss

答案 3 :(得分:9)

关于这个问题有a good thread on perlmonks

显然,基本原因是严格和警告会大量帮助您发现错误并帮助调试。

答案 4 :(得分:3)

来源::不同的博客

  

使用将函数和变量名称导出到主命名空间   调用模块import()函数。

     

pragma是一个影响编译时某些方面的模块   或运行时perl.Pragmas的行为给编译器提示。

     

使用警告 - perl投诉变量只使用一次,不正确的字符串转换为数字,。写入   未打开的文件。在编译时发生。它习惯了   控制警告。

     

使用严格 - 声明变量范围。它用于设置某种类型   脚本中的纪律。如果在代码中使用了裸词   解释。所有变量都应该给出范围,比如我的,我们的或者   本地

答案 5 :(得分:1)

“use strict”指令告诉Perl在编译代码期间进行额外的检查。使用此指令将节省您调试Perl代码的时间,因为它会发现您可能忽略的常见编码错误。

答案 6 :(得分:0)

严格和警告确保您的变量不是全局变量。

能够为各个方法设置唯一的变量,而不是必须跟踪每个变量名称,这是非常简洁的。

$ _,或者某些函数没有变量,对于更快地编写更紧凑的代码也很有用。

但是,如果您不使用严格和警告,$ _将变为全局!

答案 7 :(得分:0)

use strict;
use warnings;

严格和警告是perl程序的模式。它允许用户更自由地输入代码,而且更多,perl代码看起来正式,其编码标准将是有效的。

警告意味着与perl shebang行中的-w相同,所以它会 为您提供perl程序生成的警告,它将显示在终端