当我注意到语法检查结果警告无用的常量(1)时,我正在编写一个模块作为我的应用程序的一部分。这是为什么?
常数是模块末尾的强制性1
,通常被警告忽略,因为perldoc perldiag
说:
对于等于0或1的数值常量,不会发出此警告,因为它们通常用在类似的语句中
1 while sub_with_side_effects();
(可能有一个更好的来源。毕竟文件末尾的1
是完全需要的,不要被警告。)
但是,即使是几乎空的模块,如果他们use bigint
,也会产生警告。
package Foo;
use bigint;
1;
对于这个简单的文件语法检查,会产生以下警告:
$> perl -Wc Foo.pm
Useless use of a constant (1) in void context at Foo.pm line 5.
Foo.pm syntax OK
除了bigint
之外,我找不到任何对Put long hex numbers in sqlite和警告信息的引用,但我认为这并没有真正解决我的问题。
我的Perl是Cygwin的v5.14.4,bigint是0.36。
这里有两个问题。
use bigint; 1;
在无效背景下发出警告?$ perl -c -we'1 while sub_with_side_effects();'
-e syntax OK
$ perl -c -we'use bigint; 1 while sub_with_side_effects();'
Useless use of a constant (1) in void context at -e line 1.
-e syntax OK
为什么use bigint; 1;
在无效背景下发出警告?
use bigint;
安装一个在解析器遇到常量文字时调用的回调,并且回调返回的值用作常量。因此,在use bigint;
下,1
不再仅仅是一个简单的0
或1
。
但是你没有做错什么,所以这个警告是虚假的。您可以使用()
或undef
而不是1
来解决它。
undef while sub_with_side_effects();
除非我需要在整个代码库中使用它,否则我赞成以下内容:
while ( sub_with_side_effects() ) { }
$ cat Module.pm
package Module;
use bigint;
1;
$ perl -c -w Module.pm
Useless use of a constant (1) in void context at Module.pm line 3.
Module.pm syntax OK
为什么常量在void上下文中执行?
当Perl执行模块时,Perl期望模块返回标量值,因此Perl应该在标量上下文中执行模块。
但是,你告诉Perl编译脚本Module.pm
。当Perl执行脚本时,Perl不需要返回任何值,因此Perl在void上下文中执行脚本。
使用模块作为脚本可能会导致虚假警告和错误,因此可以传递-W
。使用如下测试模块:
perl -we'use Module'
实际上,你甚至不需要-w
,因为你应该已经在模块中有use warnings;
。你真正需要的只是
perl -e'use Module'
-W而不是模块中的use warnings;
或使用-c而不是perl -MFoo -e0
检查模块可能会显示虚假错误。这是后者的一个例子。
正常加载模块时,它不在void上下文中,因为它检查结果是否为true。
(请注意,当我使用5.20.1进行尝试时,-W也会导致虚假的overload arg '..' is invalid at /usr/share/perl/5.20/Math/BigInt.pm line 155
。)
只需离开此处就可以避免出现警告:在使用1
之前使用值bigint
定义常量:
package Foo;
use strict;
use warnings;
use constant PACKAGE_END => 1;
use bigint;
PACKAGE_END;