2009-12-30 3 views
2

I sais ce type de chose que je veux faire l'habitude de travailler en 5.8. Est-ce que je fais quelque chose de mal? Y a-t-il un moyen d'y retourner en Perl 5.10?Perl 5.10 at-il gâché quelque chose avec des prototypes?

est ici le module:

package TableMod; 
use base qw<Exporter>; 
our @EXPORT_OK = qw<mod_table>; 

use Data::Dumper; 
sub mod_table (\%@) { print Dumper(@_); } 

1; 

Et voici le script:

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

Tout ce que je dois faire est uncomment suivant la dernière ligne et je reçois:

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. 

Il ne se plaint pas du sous-marin local, mais il perd son esprit par rapport à l'importé. En plus de cela, malgré les tests me disant que j'ai importé 'mod_table', strict est maintenant confus que c'est un mot à mot!

Non seulement cela, mais malgré les essais qui me disent que les prototypes sont les mêmes, je ne peux pas passe %table comme hashref au sous importé. Pas même si j'utilise la syntaxe conventionnelle, montrée dans la dernière ligne.

Ce que je reçois est:

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

Il y avait l'ajout du prototype '(_)', mais je ne sais pas pense que c'est lié. –

Répondre

10

Son parce use_ok est appelé à l'exécution. Si vous ajoutez ce qui suit alors tout fonctionne très bien:

use TableMod 'mod_table'; 

Je garde normalement un fichier de test unique avec use_ok en (normalement 00-load.t ou 00-use.t). Je pense qu'Ovid a peut-être écrit un article sur ce sujet comme étant une bonne pratique?

Mise à jour: Trouvé Ovid's blog post Je faisais référence à.

/I3az/

+0

Je ne peux pas croire que je n'ai jamais essayé 'use' seul. Merci. – Axeman

+1

Ce n'est pas le use_ok() fourni avec 5.10. *, C'est un problème avec use_ok() dans toutes les versions.Si vous ne chargez pas le module avant que Perl n'ait à analyser le reste de la source, vous ne bénéficiez pas des avantages des prototypes ou des importations. –

+0

@brian - Absolument correct. Quand j'ai fait un test rapide avec 5.8.8, le code OP a fonctionné, mais je ne peux pas le répéter maintenant si clairement que j'avais mucké quelque chose en le faisant ;-(J'ai modifié la réponse en conséquence. – draegtun

7

Ceci est le résultat attendu. L'appel use_ok est à l'exécution, donc le sous-mod_table est seulement compilé et importé après "l'appel" à lui est rencontré pendant la compilation, donc l '"appel" à mod_table est interprété comme un bareword illégal.

Ce code produit les mêmes avertissements/erreurs, à la fois sur 5.8 et 5.10.

perl -e'use strict; use warnings; my %table; mod_table %table => (1,2,3,4)' 

En raison de l'absence d'importation de compilation peut affecter le code de test compilé de manière comme cela, il est une bonne idée d'utiliser use au lieu de use_ok dans tous les tests sauf un test dédié à faire exactement le use_ok (potentiellement avec un BAIL_OUT). (Mettre l'utilisation_ok dans un bloc BEGIN atténue ce genre de problèmes mais peut causer d'autres problèmes, donc ce n'est pas une bonne idée.)

Questions connexes