¿Por qué es válido este programa? Estaba tratando de crear un error de sintaxis


Estoy ejecutando ActiveState de 32 bits ActivePerl 5.14.2 en Windows 7. Quería perder el tiempo con un gancho de Git pre-commit para detectar programas que se están comprobando con errores de sintaxis. (De alguna manera me las arreglé para hacer un mal compromiso. Así que como un programa de prueba anoté al azar esto:

use strict;
use warnings;

Syntax error!

exit 0;

Sin embargo, compila y ejecuta sin advertencias, y errorlevel es cero al salir. ¿Cómo es válida esta sintaxis?

 472
Author: Peter Mortensen, 2012-07-28

5 answers

Perl tiene una sintaxis llamada "notación de método indirecto". Permite

Foo->new($bar)

Se escribirá como

new Foo $bar

Eso significa

Syntax error ! exit 0;

Es lo mismo que

error->Syntax(! exit 0);

O

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

No solo es una sintaxis válida, sino que no resulta en un error de tiempo de ejecución porque lo primero que se ejecuta es exit(0).

 518
Author: ikegami,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-27 20:36:00

No se por qué, pero esto es lo que Perl hace de ello:

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

Parece que el analizador piensa que estás llamando al método Syntax en el objeto error... Realmente extraño!

 107
Author: pavel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-06 13:48:57

La razón por la que no obtiene un error es que el primer código ejecutado es

exit(0);

Porque no tenías un punto y coma en la primera línea:

Syntax error!

El compilador adivinará (incorrectamente) que se trata de una llamada de subrutina con un operador not ! introducido. Luego ejecutará los argumentos a esta subrutina, que pasa a ser exit(0), en cuyo punto el programa sale y establece errorlevel a 0. No se ejecuta nada más, por lo que no hay más errores de tiempo de ejecución informar.

Notarás que si cambias exit(0) a algo como print "Hello world!" obtienes un error:

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

Y su nivel de error se establecerá:

> echo %errorlevel%
255
 50
Author: TLP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-11 16:19:03

Como se señaló anteriormente, esto es causado por el método indirecto que llama a la notación. Usted puede advertir sobre esto:

use strict;
use warnings;
no indirect;

Syntax error!

exit 0;

Produce:

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

Esto requiere el módulo CPAN indirecto .

También puedes usar no indirect "fatal"; para hacer que el programa muera (esto es lo que hago)

 32
Author: Mark Fowler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-03 14:07:28

Try Perl 6, parece cumplir con sus expectativas más fácilmente:

===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
 7
Author: moritz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-05 21:00:05