2010-08-31 8 views
4

j'ai couru ce script de test:Pourquoi ne pas accepter accepter -MCarp = verbose?

use strict; 
use warnings; 
use Test::More tests => 3; 
use Carp; 

ok(1<2); 
pass(); 
fail(); 
croak "example"; 

en utilisant la ligne de commande prove -MCarp=verbose -v foo.pl, et a obtenu les erreurs suivantes:

Subroutine App::Prove::verbose redefined at /opt/ActivePerl-5.12/lib/App/Prove.pm line 407 
     App::Prove::_load_extension('App::Prove=HASH(0x683718)', 'Carp=verbose') called at /opt/ActivePerl-5.12/lib/App/Prove.pm line 419 
     App::Prove::_load_extensions('App::Prove=HASH(0x683718)', 'ARRAY(0x683850)') called at /opt/ActivePerl-5.12/lib/App/Prove.pm line 481 
     App::Prove::run('App::Prove=HASH(0x683718)') called at /opt/ActivePerl-5.12/bin/prove line 11 
Undefined subroutine &Carp::verbose called at /opt/ActivePerl-5.12/lib/App/Prove.pm line 484. 

Si je cours à l'aide perl -MCarp=verbose foo.pl il n'y a pas de problème. Qu'est-ce qui cause prove de rejeter la carpe prolixe? Comment puis-je obtenir une callstack complète de mes tests quand ils croak sans remplacer global croak à confess?

+1

utiliser Carp :: Toujours à la place? – jrockway

Répondre

10

prove -M ne semble pas être équivalent à perl -M. Il semble charger une extension de preuve, ne pas charger un module dans vos tests. Les docs ne sont pas clairs sur ce point, mais le code dans App :: Prove ne l'est pas. Donc prove -MCarp=verbose importe Carp :: verbose dans App :: Prove causant le problème ci-dessus. Un moyen simple de faire ce que vous voulez est d'utiliser la variable d'environnement PERL5OPT plus Carp::Always qui transformera tous les avertissements et les matrices (et les carpes et croassements) en traces de pile.

PERL5OPT=-MCarp::Always prove ... 

Ceci a l'avantage supplémentaire de fonctionner dans n'importe quelle situation, avec ou sans preuve.

+0

d'accord, vous avez raison, c'est aussi * vrai *. Manqué la partie où le '-M' de la preuve remplace la classe de harnais. Néanmoins, le bug que j'ai signalé semble exister. :) – hobbs

+0

hmm, l'enquête montre que vous avez raison. 'prouver -MMoose foo.pl' ne charge pas Moose (selon'% INC'), alors que le truc 'PERL5OPT' le fait. –

3

Preuve a un ensemble d'arguments de ligne de commande très différent de Perl, étant un programme complètement différent?

Preuve -M est, je crois, destiné à permettre des pragmas; En fait, Carp exporte une référence vers un sous-programme verbose() qui interfère avec le fonctionnement interne de la preuve.

Vous pouvez créer un petit module comme celui-ci:

# Verbme.pm 
use Carp; 
$Carp::Verbose = 1; 

et lui permettre de prouver:

prove -MVerbme -v foo.pl 

bien.

+0

Le code dans App :: Prouve les choses dans -M à App :: Prove -> _ load_extension() qui est utilisé pour charger les plugins ins. Toute importation est explicitement effectuée dans App :: Prove et il recherche même une méthode spéciale load(). C'est une fonctionnalité mal documentée. – Schwern

+0

@Schwern: mais -P est pour le chargement des plugins. Et je ne peux pas croire que c'est un accident que -M s'applique non seulement à prouver, mais aussi à faire des tests. Bien que je suppose que des accidents étranges sont arrivés. – ysth

+2

Après avoir fait des tests en imprimant '% INC', il semble que prouver -M ne * charge * pas les modules dans l'exécution des tests. –

2

carpe utilise un mécanisme EXPORT_FAIL de l'exportateur pour gérer la verbose « option » à import, ce qui est à peu près tort, comme Exporter::Heavy essayera encore d'attribuer *Carp::verbose à *{"$callerpkg::verbose"} en dépit du fait qu'il était « échoué ». Malheureusement, App::Prove a un sous-verbeux dont il dépend pour fonctionner, et votre option -M provoque l'importation à App::Prove. Je ne sais pas qui est à blâmer ici - pour Carp (ab) en utilisant EXPORT_FAIL de cette façon, ou Exporter::Heavy pour ne pas enlever des choses de @imports si elle est dans la liste @failed, mais ensemble, ils sont le casser :)

+1

Eh bien, le problème d'OP tel que posté est que Prove est en train de sauter parce que sa méthode 'verbose' a été saccagée. Bien que je suppose que si cela ne s'est pas produit, il aurait explosé différemment peu de temps après. – hobbs

+0

s'il n'a pas explosé, il n'aurait pas fonctionné en silence. Vous pouvez le voir avec, disons, «prouver -Moose» qui ne chargera tout simplement pas Moose et exécutera le test malgré tout. Donc j'ai eu de la chance que ça a explosé de façon spectaculaire plutôt que d'échouer silencieusement :) –

Questions connexes