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 облегчает подобные проблемы, но может вызвать другие проблемы, поэтому не очень хорошая идея.)