Perl: текст против анонимных проблем с переданными параметрами - PullRequest
2 голосов
/ 15 ноября 2010

Если вы прочитали о cmpthese в документации к Perl Benchmark , в нем говорится, что cmpthese или timethese можно использовать с кодом в текстовых или подпрограммных ссылках. Документация предполагает, что эти формы полностью взаимозаменяемы:

# 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? Я использовал все свои Google Foo, чтобы попытаться найти некоторые документированные различия между этими двумя формами, но я не могу.

Кто-нибудь знает причину, по которой мои простые примеры, приведенные выше, не работают должным образом? Комментарии в коде указывают на проблемы, с которыми я сталкиваюсь в OS X, Perl 5.10.0.

Ответы [ 2 ]

6 голосов
/ 16 ноября 2010

Текст, переданный cmpthese и timethese, распространяется в виде утверждения eval глубоко в недрах Benchmark.Если аргументы в тексте не являются литералами или глобальными переменными, они не будут находиться в области действия к моменту их оценки, и вы получите ошибку во время выполнения.

Используйте анонимную суб-версию аргументов дляобеспечьте лексическое завершение ваших аргументов, и все будет хорошо.

5 голосов
/ 16 ноября 2010

Я не слишком подробно рассмотрел это, но я предполагаю, что когда Benchmark превращает строки в код, лексическая переменная @array не попадает в область видимости. Возможно, все будет работать, если вы сделаете @array переменную our.

Но в целом я считаю, что проще использовать код ссылки.

...