Perl 5.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;

А вот и скрипт:

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

Все, что мне нужно сделать, это раскомментировать следующую последнюю строку, и я получаю:

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.

Он не жалуется на местную субмарину, но сходит с ума по импортированной. Кроме того, несмотря на то, что тесты показали, что я импортировал 'mod_table', строгий теперь растерян, что это голое слово!

Не только это, но, несмотря на тесты, говорящие мне, что прототипы одинаковы, я не могу пройти %table в качестве хэш-функции к импортированному сабвуферу. Даже если я использую обычный синтаксис, показанный в последней строке.

Что я получаю это:

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;

2 ответа

Решение

Это потому что use_ok вызывается во время выполнения. Если добавить следующее, то все работает нормально:

 use TableMod 'mod_table';

Я обычно держу только один тестовый файл с use_ok в (обычно 00-load.t или 00-use.t). Я думаю, что Овидий, возможно, написал сообщение в блоге об этом, являющемся хорошей практикой?

Обновление: нашел сообщение в блоге Овидия, о котором я говорил.

/ I3az /

Это ожидаемый результат. Вызов 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)'

Поскольку отсутствие импорта во время компиляции может повлиять на скомпилированный тестовый код такими способами, рекомендуется использовать use вместо use_ok во всех тестах, кроме теста, предназначенного только для выполнения use_ok (возможно, с BAIL_OUT). (Помещение use_ok в блок BEGIN облегчает подобные проблемы, но может вызвать другие проблемы, поэтому не очень хорошая идея.)

Другие вопросы по тегам