为什么Perl在使用bigint时警告“无用常数1”?

时间:2015-01-28 18:31:26

标签: perl perl-module bigint perlsyn

当我注意到语法检查结果警告无用的常量(1)时,我正在编写一个模块作为我的应用程序的一部分。那是为什么?

常量是模块末尾的强制性1,通常会被警告忽略perldoc perldiag说:

  

对于等于0或1的数值常量,不会发出此警告,因为它们通常用于

等语句中
1 while sub_with_side_effects();

(可能有一个更好的来源。在文件末尾的所有1之后是完全需要的,不要被警告。)

但是,即使对于几乎空的模块{@ 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之外的警告信息,但我认为这并没有真正解决我的问题。

My Perl是Cygwin的v5.14.4,bigint为0.36。

3 个答案:

答案 0 :(得分:8)

这里有两个问题。

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

  3. $ 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不再仅仅是一个简单的01

    但是你没有做错任何事,所以这个警告是虚假的。您可以使用()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'
    

答案 1 :(得分: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。)

答案 2 :(得分:0)

只需在此处留下一种变通方法来避免警告:在使用1之前定义值为bigint的常量:

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

PACKAGE_END;