Perl 5.10是否与原型相混淆?

Axe*_*man 2 perl prototype perl5.10

知道我想做的这种事情曾经用于5.8.难道我做错了什么?在Perl 5.10中有没有办法回到那里?

这是模块:

package TableMod;
use base qw<Exporter>;
our @EXPORT_OK = qw<mod_table>;

use Data::Dumper;
sub mod_table (\%@) { print Dumper( @_ ); }

1;
Run Code Online (Sandbox Code Playgroud)

以下是脚本:

use strict;
use warnings;
use Data::Dumper;
use Test::More tests => 4;

sub mod_table_here (\%@) { 
    print Dumper( @_ );
}

use_ok( 'TableMod', 'mod_table' );
can_ok( __PACKAGE__, 'mod_table' );
is( prototype( \&mod_table_here ), '\\%@'
  , q/prototype( \&mod_table_here ) = '\%@'/ 
  );
is( prototype( \&mod_table ), prototype( \&mod_table_here )
   , 'prototypes ARE the SAME!' 
   );
my %table = qw<One 1>;
mod_table_here %table => ( 1, 2, 3, 4 );
#mod_table %table => ( 1, 2, 3, 4 );
mod_table( %table, 1, 2, 3, 4 );
Run Code Online (Sandbox Code Playgroud)

我所要做的就是取消注释到最后一行,我得到:

Useless use of modulus (%) in void context at - line 17.
Useless use of a constant in void context at - line 17.
Useless use of a constant in void context at - line 17.
Useless use of a constant in void context at - line 17.
Bareword "mod_table" not allowed while "strict subs" in use at - line 17.
Run Code Online (Sandbox Code Playgroud)

它没有抱怨当地的潜艇,但它对进口的潜艇失去了理智.最重要的是,尽管测试告诉我我已导入'mod_table',但严格现在却认为它是一个赤字!

不仅如此,尽管测试告诉我原型是相同的,我不能%table作为hashref 传递给导入的子.即使我使用传统语法,也不是最后一行.

我得到的是:

1..4
ok 1 - use TableMod;
ok 2 - main->can('mod_table')
ok 3 - prototype( \&mod_table_here ) = '\%@'
ok 4 - prototypes ARE the SAME!
$VAR1 = {
          'One' => '1'
        };
$VAR2 = 1;
$VAR3 = 2;
$VAR4 = 3;
$VAR5 = 4;
$VAR1 = 'One';
$VAR2 = '1';
$VAR3 = 1;
$VAR4 = 2;
$VAR5 = 3;
$VAR6 = 4;
Run Code Online (Sandbox Code Playgroud)

dra*_*tun 10

因为它use_ok是在运行时被调用的.如果您添加以下内容,那么一切正常:

 use TableMod 'mod_table';
Run Code Online (Sandbox Code Playgroud)

我通常只保留一个测试文件use_ok(通常为00-load.t00-use.t).我想Ovid可能写了一篇博文,说这是一个好习惯吗?

更新:找到我所指的Ovid的博客文章.

/ I3az /


yst*_*sth 7

这是预期的结果.该use_ok通话是在运行时,所以mod_table子只编译和进口的"呼"地是在编译过程中遇到的,因此,"呼"地mod_table被解释为非法裸字.

此代码在5.8和5.10上产生相同的警告/错误.

perl -e'use strict; use warnings; my %table; mod_table %table => (1,2,3,4)'
Run Code Online (Sandbox Code Playgroud)

因为缺少编译时导入会以这样的方式影响编译的测试代码,所以use在所有测试中使用而不是use_ok 是个好主意,除了专门用于执行use_ok的测试(可能带有BAIL_OUT).(将use_ok放在BEGIN块中可以缓解这些问题,但可能会导致其他问题,因此不是一个好主意.)