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


J'utilise 32 bits d'ActiveState ActivePerl 5.14.2 sur Windows 7. Je voulais déconner avec un crochet de pré-validation Git pour détecter les programmes en cours d'archivage avec des erreurs de syntaxe. (D'une façon ou d'une autre, j'ai juste réussi à faire un si mauvais commit.) Donc, en tant que programme de test, j'ai noté cela de manière aléatoire:

use strict;
use warnings;

Syntax error!

exit 0;

Cependant, il compile et s'exécute sans avertissements, et errorlevel est nul en sortie. Comment est cette syntaxe valide?


472
2017-07-27 20:19


origine


Réponses:


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 c'est une syntaxe valide, mais elle ne génère pas d'erreur d'exécution car la première chose à exécuter est exit(0).


518
2017-07-27 20:36



Je ne sais pas pourquoi, mais c'est 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 le error-object ... Etrange en effet!


107
2017-07-27 20:26



La raison pour laquelle vous n'obtenez 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 not opérateur ! jeté. Il va ensuite exécuter les arguments de ce sous-programme, qui se trouve être exit(0), à quel point le programme se termine et définit errorlevel à 0. Rien d'autre n'est exécuté, donc plus d'erreurs d'exécution sont signalées.

Vous remarquerez que si vous changez exit(0) à 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

50
2017-07-27 20:36



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

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"; pour faire mourir le programme (c'est ce que je fais)


32
2018-04-03 14:07



Essayer Perl 6, il semble plus facilement 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

8
2018-02-05 21:00