Perl:cmp这些文本与传递参数的匿名子问题

Perl:cmp这些文本与传递参数的匿名子问题,perl,parameters,eval,subroutine,Perl,Parameters,Eval,Subroutine,如果您阅读了模块文档中的cmp这些,则说明cmp这些或time这些可与文本或子例程引用中的代码一起使用。文件似乎暗示这些表格完全可以互换: # Use Perl code in strings... timethese($count, { 'Name1' => '...code1...', 'Name2' => '...code2...', }); # ... or use subroutine references. timethese($count, { 'Name1' =>

如果您阅读了模块文档中的
cmp这些
,则说明
cmp这些
time这些
可与文本或子例程引用中的代码一起使用。文件似乎暗示这些表格完全可以互换:

# Use Perl code in strings...
timethese($count, {
'Name1' => '...code1...',
'Name2' => '...code2...',
});
# ... or use subroutine references.
timethese($count, {
'Name1' => sub { ...code1... },
'Name2' => sub { ...code2... },
});
我很难用字符串形式传递参数,而用
cmpthese
传递子程序引用形式传递参数。无法传递
@array
中的值,或者我有运行时错误

我有以下代码:

#!/usr/bin/perl
use strict; use warnings;
use Benchmark qw(:all);

my @array = qw( first second third );

sub target {
    my $str =  $_[0];
    print "str=$str\n";
}

sub control {
    print "control: array[0]=$array[0]\n";
}

my $sub_ref=\⌖
my $control_ref=\&control;

print "\n\n\n";

# ERROR: array does not get passed...
cmpthese(1, {
    'target text' => 'target(@array)',
    'control 1' => 'control()', 
});

# This is OK...
cmpthese(1, {
    'sub code ref' => sub { target(@array) },
    'control 2' => sub { control() },
});

# This is OK too...
cmpthese(1, {
    'target sub' => sub { $sub_ref->(@array) },
    'control 3' => sub { $control_ref->() },
});

# fixed paramenters work:
cmpthese(1, {
    'target text fixed' => 'target("one", "two", "three")',
    'control 4' => 'control()', 
});

# Run time error...
cmpthese(1, {
    'text code ref' => '$sub_ref->(@array)',
    'control 5' => '$control_ref->()',
});
我所有的表单都能正确使用
eval
,所以我认为这可能是Benchmark的问题?我用了我所有的GoogleFoo,试图找出这两种形式之间的差异,但我做不到


有人知道我上面的简单例子似乎没有达到预期效果的原因吗?代码中的注释表明了我在OS X、Perl 5.10.0上遇到的问题。

我没有详细研究过这一点,但我的猜测是,当
基准测试
将字符串求值为代码时,词法变量
@array
不在范围内。如果将
@array
设置为
我们的
变量,事情可能会成功


但总的来说,我发现只使用代码引用更容易。

传递给
cmp这些
times的文本将这些
传播到
eval
语句中,深入到基准测试的内部。除非文本中的参数是文本或全局变量,否则在计算它们时,它们将不在范围内,并且会出现运行时错误


使用参数的匿名子版本为您的参数提供词法闭包,一切都会好起来。

my
替换为
our
修复了第一个问题。谢谢你知道为什么“control 5”案例不起作用吗?你在使用我们的$control\u ref
<代码>我的$control\u ref
在评估时将超出范围。原因可能相同。由于ref位于词法变量中,因此基准使用的字符串eval无法使用它们
our
修复了所有“我的”问题。控件1和控件5都像我期望的那样工作。谢谢与这个问题无关,但是看看是否可以将perl升级到至少5.10.1,5.10.0中有许多bug已经修复。