2009-12-30 1 views
2

I знаю этот тип вещь я хочу использовать для работы в 5.8. Я делаю что-то неправильно? Есть ли способ вернуться в Perl 5.10?Сделал ли 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 как 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; 
+0

Было добавлено прототип '(_)', но я не думаю, что это связано. –

ответ

10

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

use TableMod 'mod_table'; 

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

Обновление: Найдено Ovid's blog post Я имел в виду.

/I3az/

+0

Не могу поверить, что я никогда не пробовал «использовать» в одиночку. Благодарю. – Axeman

+1

Это не use_ok(), который поставляется с 5.10. *, Это проблема с use_ok() во всех версиях.Если вы не загрузите модуль до того, как Perl проанализирует остальную часть источника, вы не получите преимущества прототипов или импорта. –

+0

@brian - Абсолютно правильно. Когда я сделал быстрый тест с 5.8.8, OP-код действительно сработал, но я не могу повторить, что теперь так ясно, что я что-то сработал, когда делаю это ;-(Я изменил ответ соответственно. – draegtun

7

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

 Смежные вопросы

  • Нет связанных вопросов^_^