8

当我注意到语法检查导致警告无用使用常量 (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

除了将长十六进制数字放入 sqlite之外,我找不到任何参考bigint和警告消息,但这并不能真正解决我的问题,我认为。

我的 Perl 是 Cygwin 上的 v5.14.4,带有 bigint 0.36。

4

3 回答 3

8

这里有两个问题。

  1. 为什么use bigint; 1;在无效上下文中发出警告?
  2. 为什么常量首先在 void 上下文中执行?

$ 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;安装一个在解析器遇到常量文字时调用的回调,并且将回调返回的值用作常量。因此,under use bigint;,1不再只是一个简单的0or 1

但是你没有做错任何事,所以这个警告是虚假的。您可以使用()orundef代替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'
于 2015-01-28T20:44:40.723 回答
6

-W 而不是use warnings;在您的模块中或使用 -c 而不是检查模块perl -MFoo -e0会显示虚假错误。这是后者的一个例子。

当您正常加载模块时,它不在void 上下文中,因为它正在检查结果是否为真。

(请注意,当我使用 5.20.1 进行尝试时,-W 也会导致虚假的overload arg '..' is invalid at /usr/share/perl/5.20/Math/BigInt.pm line 155.)

于 2015-01-28T20:01:32.013 回答
0

1在这里留下一个解决方法以避免警告:在使用之前定义一个带有值的常量bigint

package Foo;
use strict;
use warnings;
use constant PACKAGE_END => 1;
use bigint;

PACKAGE_END;
于 2019-04-12T12:23:12.413 回答