【问题标题】:Why does Perl warn about "useless constant 1" when using bigint?为什么 Perl 在使用 bigint 时会警告“无用常量 1”?
【发布时间】:2015-01-28 18:31:25
【问题描述】:

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

除了Put long hex numbers in sqlite 之外,我找不到对bigint 和警告消息的任何引用,但我认为这并不能真正解决我的问题。

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

【问题讨论】:

  • 有趣的发现。我猜这是因为它不再是“1”,因此可以忽略,而是一种特殊的“1”。

标签: perl perl-module bigint perlsyn


【解决方案1】:

这里有两个问题。

  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; 安装一个回调,当解析器遇到常量字面量时调用该回调,并且将回调返回的值用作常量。因此,在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'

【讨论】:

    【解决方案2】:

    -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。)

    【讨论】:

    • 讽刺的是,perl -MFoo -we0 在测试 bigint 时失败了。 perl -we'use bigint;' 在没有警告的情况下做同样的事情。
    • 啊,你的意思是-Mbigint;是的,这很讽刺。 perl -MFoo -we# 工作
    • Boggle ... 真正的 bug、buglet 或 QA 问题??
    • @G.Cito:不,这里没有错误
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2010-12-07
      • 1970-01-01
      • 1970-01-01
      • 2019-05-27
      • 2013-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多