Pourquoi ce programme est-il valide? J’essayais de créer une erreur de syntaxe

J’utilise ActivePerl 5.14.2 32 bits d’ ActiveState sur Windows 7. Je voulais jouer avec un hook de pré-validation Git pour détecter les programmes en cours d’enregistrement avec des erreurs de syntaxe. (D’une certaine manière, j’ai juste réussi à faire un si mauvais engagement.) Alors, en tant que programme de test, j’ai écrit ceci au hasard:

use ssortingct; use warnings; Syntax error! exit 0; 

Cependant, il comstack et exécute sans avertissements, et errorlevel est à zéro en sortie. Comment est cette syntaxe valide?

Perl a une syntaxe appelée “notation de méthode indirecte”. Il permet

 Foo->new($bar) 

être écrit comme

 new Foo $bar 

Donc ça signifie

 Syntax error ! exit 0; 

est le même que

 error->Syntax(! exit 0); 

ou

 error->Syntax(!exit(0)); 

Non seulement cette syntaxe est-elle valide, mais elle ne provoque pas d’erreur d’exécution car la première chose exécutée est exit(0) .

Je ne sais pas pourquoi, mais c’est ce que Perl en fait:

 perl -MO=Deparse -w yuck BEGIN { $^W = 1; } use warnings; use ssortingct 'refs'; 'error'->Syntax(!exit(0)); yuck syntax OK 

Il semble que l’parsingur pense que vous appelez la méthode Syntax sur l’ error -object… en effet!

La raison pour laquelle vous ne recevez pas d’erreur est que le premier code exécuté est

 exit(0); 

Parce que vous n’aviez pas de point-virgule sur la première ligne:

 Syntax error! 

Le compilateur devinera (à tort) qu’il s’agit d’un appel de sous-programme avec un opérateur not ! Il exécutera ensuite les arguments de cette sous-routine, qui se trouve être exit(0) . À ce stade, le programme se ferme et définit errorlevel sur 0. Rien d’autre n’est exécuté, donc plus d’erreurs d’exécution ne sont signalées.

Vous remarquerez que si vous changez exit(0) en quelque chose comme print "Hello world!" vous obtenez une erreur:

 Can't locate object method "Syntax" via package "error" ... 

et votre niveau d’erreur sera défini:

 > echo %errorlevel% 255 

Comme indiqué ci-dessus, cela est dû à la notation d’appel de méthode indirecte. Vous pouvez avertir à ce sujet:

 use ssortingct; use warnings; no indirect; Syntax error! exit 0; 

Produit:

 Indirect call of method "Syntax" on object "error" at - line 5. 

Cela nécessite le module CPAN indirect .

Vous pouvez également utiliser no indirect "fatal"; faire mourir le programme (c’est ce que je fais)

Essayez Perl 6 , cela semble répondre plus facilement à vos attentes:

 ===SORRY!=== Error while compiling synerror.p6 Negation metaoperator not followed by valid infix at synerror.p6:1 ------> Syntax error!⏏ expecting any of: infix infix stopper