为什么使用严格和警告?
在我看来,如果人们使用Perl标签中的许多问题都可以解决:
use strict; use warnings;
我认为有些人认为这些与训练轮相似,或者是不必要的复杂性,这显然是不正确的,因为即使是非常熟练的Perl程序员也使用它们。
似乎大多数精通Perl的人总是使用这两个编译指示,而那些从中受益最多的人却很less使用这两个编译指示。 所以,我认为在鼓励人们use strict
和warnings
时候,有一个问题要联系起来是个好主意。
那么,Perl开发者为什么要use strict
和warnings
呢?
对于初学者来说,它有助于在variables名称中查找拼写错误。 即使有经验的程序员也会犯这样的错 常见的情况是在清理或重构代码时忘记重命名variables的实例。
这些编译指令很快就会捕捉到许多错误,从而更容易find错误的根本原因。 根本原因可能是需要进行错误或validation检查,这可能会发生,无论程序员的技能。
Perl警告的好处在于它们很less是虚假的,所以使用它们几乎没有成本。
相关阅读: 为什么使用my
?
显然use strict
应该(必须)当你要强制perl编码正确,可能是强制声明,明确的string和短语,即裸字或谨慎使用裁判。 注意:如果有错误,使用严格会中止执行。
在use warnings;
会帮助你在程序中发现input错误,比如你错过了一个分号,你使用了'elseif'而不是'elsif',你正在使用不赞成的语法或函数,无论如何。 注意:使用警告只会提供警告并继续执行,即不会中止执行。
无论如何,如果我们详细说明,我会在下面详细说明
来自perl.com (我的最爱):
使用严格的“变种”;
这意味着你必须在使用它们之前总是声明variables。
如果你没有声明你可能会得到未声明的variables的错误信息
全局符号“$ variablename”需要在scriptname.pl第3行显式包名称
这个警告意味着Perl不完全清楚variables的作用域是什么。 所以你需要明确你的variables,这意味着或者用my
声明来限制它们,或者用完全限定的名称(例如:$ MAIN :: variablename)引用它们。
因此,如果尝试访问至less未满足以下某个条件的variables,则会触发编译时错误:
-
由Perl本身预定义,比如@ARGV,%ENV和所有全局标点variables,如$。 或$ _。
-
用我们的(全球)或我的(词汇)声明。
-
从另一个包导入。 (使用variables编译指示导入,但使用我们。)
-
完全限定使用其包名称和双冒号分隔符。
使用严格的'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被解释为string'test_value'。 在第二个程序中,test_value()的定义在$a = test_value;
线。 Perl认为test_value是子调用。
像test_value这样的孤立词的技术术语可能是潜在的,也可能是取决于上下文的string,这是纯粹的词汇 。 Perl对裸字的处理可能会令人困惑,并且会导致程序中的错误。
这个错误是我们在第一个程序中遇到的问题,请记住,Perl不会期望findtest_value()
,因为它还没有看到test_value(),所以假定你需要一个string。 所以,如果你use strict subs;
,它会导致这个程序死了一个错误:
在./a6-strictsubs.pl第3行使用“strict subs”时,不允许使用“bareword”test_value。
解决这个错误的办法是
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.如果你的意思是把它作为一个string,引用它。
所以,这个限制让Perl将所有的裸词视为语法错误。 *裸词是没有上下文强制的其他解释的裸名或标识符。 (上下文通常是由附近的关键字或标记强制的,或者是通过对这个单词进行预先声明来实现的)。*所以,如果你的意思是把它作为一个string使用,那就引用它,如果你想把它作为一个函数调用,就要声明它或使用括号。
由于这种不可预知的行为,裸字是危险的。 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' );
散列键中的粗体字总是被解释为string,所以不存在歧义。
使用严格的'参考';
如果您有意或无意使用符号引用,则会生成运行时错误。 然后将不是硬引用的值视为符号引用 。 也就是说,引用被解释为表示全局variables名称的string。
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
:
所以大部分来自W,D&S分类的警告信息都可以使用warnings
编译指示来控制。
(W)警告(可选)
(D)弃用(默认启用)
(S)严重警告(默认启用)我已经列出了一些警告消息,这些消息经常被分类。 有关它们和其他消息的详细信息,请参阅perldiag
(W)警告(可选):
在%s中缺less参数
缺less参数 – %c
(你的意思是&%s吗?)
(你的意思是“本地”而不是“我们”?)
(你的意思是$或@而不是%?)
'%s'不是代码引用
在%s上使用的长度()
错位数_(D)弃用(默认启用):
定义(@array)已被弃用
定义(%散列)已被弃用
在假条件下弃用my()
$#不再支持(S)严重警告(默认启用)
elseif应该是elsif
find运营商预期的%s
(%s之前缺less运算符?)
(在前一行丢失分号?)
%s从来没有介绍过
在%s之前缺less运算符或分号
优先问题:打开%s应该打开(%s)
原型不匹配:%s vs%s
警告:使用不带括号的“%s”是不明确的
无法打开%s:%s
这两个编译指示可以自动识别代码中的错误。
我总是在我的代码中使用这个:
use strict; use warnings FATAL => 'all';
FATAL
就像strict
一样,致使代码死于警告。
有关更多信息,请参阅: 严格使用警告FATAL =>'all';
另外… 根据苏斯的说法
关于这个问题perlmonks有一个很好的线程 。
其根本原因显然在于,严格的警告和大量的警告大大地帮助你抓错,帮助debugging。
来源::不同的博客
使用将通过调用模块的import()函数将函数和variables名称导出到主名称空间。
一个pragma是一个模块,它影响perl.Pragmas的编译时间或运行时间行为的某些方面给编译器一些提示。
使用警告 – 关于variables的perl投诉只用了一次,不正确地将string转换为数字,尝试写入未打开的文件,这是在编译时发生的。它用于控制警告。
使用strict – 声明variables作用域。 它被用来设置脚本中的某种规则。如果在编码中使用了裸字,则它们被解释。所有的variables都应该被赋予作用域,比如我的,我们的或者本地的。
“use strict”指令告诉Perl在编译代码的时候进行额外的检查。 使用这个指令可以节省您debuggingPerl代码的时间,因为它find了常见的编码错误,否则您可能会忽略它们。
use strict;use warnings;
严格和警告是perl程序的模式,它允许用户更加自由地input代码,而且perl代码看起来是正式的,它的编码标准是有效的。
警告在perl shabang行中的意思就像“-w”一样,所以它会给你提供perl程序产生的警告,它会显示在terminal
严格和警告确保您的variables不是全球性的。
能够使各个方法具有唯一的variables而不必跟踪每个variables名是非常简单的。
$ _,或者某些函数没有variables,也可以用来更快地编写更紧凑的代码。
但是,如果您不使用严格和警告,$ _将成为全局!