J'utilise la version 32 bits d'ActiveState ActivePerl 5.14.2 sous Windows 7. Je voulais manipuler un crochet de pré-validation Git pour détecter les programmes en cours d'enregistrement comportant des erreurs de syntaxe. (D'une manière ou d'une autre, j'ai juste réussi à faire un tel commit.) Donc, en tant que programme de test, j'ai noté au hasard ceci:
use strict;
use warnings;
Syntax error!
exit 0;
Cependant, il compile et exécute sans avertissements et errorlevel est égal à zéro à la 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 valide, mais elle ne génère pas d'erreur au moment de l'exécution, car la première chose exécutée est exit(0)
.
Je ne sais pas pourquoi, mais voici ce que Perl en fait:
Perl -MO=Deparse -w yuck
BEGIN { $^W = 1; }
use warnings;
use strict 'refs';
'error'->Syntax(!exit(0));
yuck syntax OK
Il semble que l'analyseur pense que vous appelez la méthode Syntax
sur l'objet error
- ... Etrange 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 devine (à tort) qu'il s'agit d'un appel à un sous-programme avec un opérateur not
!
. Il exécutera ensuite les arguments de ce sous-programme, qui se trouve être exit(0)
, moment auquel le programme se ferme et définit le niveau d'erreur sur 0. Aucune autre opération n'est exécutée. Aucune autre erreur d'exécution n'est signalée.
Vous remarquerez que si vous remplacez exit(0)
par 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 sur ceci:
use strict;
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 aussi utiliser no indirect "fatal";
provoquer la mort du programme (c'est ce que je fais)
Essayez Perl 6 , il semble mieux répondre à vos attentes:
===SORRY!=== Error while compiling synerror.p6
Negation metaoperator not followed by valid infix
at synerror.p6:1
------> Syntax error!⏏<EOL>
expecting any of:
infix
infix stopper