¿Por qué usar estricto y advertencias?


Me parece que muchas de las preguntas en la etiqueta Perl podrían resolverse si la gente usara:

use strict;
use warnings;

Creo que algunas personas consideran que estos son similares a las ruedas de entrenamiento, o complicaciones innecesarias, lo que claramente no es cierto, ya que incluso los programadores Perl muy expertos los utilizan.

Parece como si la mayoría de las personas que son competentes en Perl siempre utilizan estos dos pragmas, mientras que aquellos que se beneficiarían más de usarlos rara vez lo hacen. Así que pensé que sería una buena idea tener una pregunta a la que enlazar cuando se anima a la gente a use strict y warnings.

Entonces, ¿por qué un desarrollador de Perl use strict y warnings?

 94
Author: Peter Mortensen, 2011-11-06

8 answers

Para empezar, use strict; (y en menor medida, use warnings;) ayuda a encontrar errores tipográficos en los nombres de variables. Incluso los programadores experimentados cometen tales errores. Un caso común es olvidar cambiar el nombre de una instancia de una variable al limpiar o refactorizar código.

Usando use strict; use warnings; detecta muchos errores antes de lo que se detectarían de otra manera, lo que hace que sea más fácil encontrar las causas raíz de los errores. La causa raíz podría ser la necesidad de un error o verificación de validación, y eso puede suceder independientemente o habilidad de programador.

Lo bueno de las advertencias de Perl es que rara vez son espurias, por lo que no hay casi ningún costo para usarlas.


Lectura relacionada: ¿Por qué usar my?

 72
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
2018-01-25 15:36:02

Aparentemente use strict debería(debe) usarse cuando se quiere forzar a perl a codificar correctamente, lo que podría estar forzando la declaración, siendo explícito en cadenas y subs, es decir, barewords o usando refs con precaución. Nota: si hay errores use strict abortará la ejecución si se usa.

Mientras que use warnings; te ayudará a encontrar errores de escritura en el programa, como si te hubieras perdido un punto y coma, usaste 'elseif' y no 'elsif', estás usando una sintaxis o función obsoleta, lo que sea. Nota: usar advertencias solo proporcionará advertencias y continuará la ejecución, es decir, no abortará la ejecución..

De todos modos, sería mejor si entramos en detalles, que estoy especificando a continuación{[17]]}

De perl.com (mi favorito):

Use estrictos 'vars';

Lo que significa que siempre debe declarar variables antes de usarlas.

Si no declara, probablemente recibirá un mensaje de error para la variable no declarada

El símbolo global "vari variablename" requiere un nombre de paquete explícito en scriptname.pl línea 3

Esta advertencia significa que Perl no está exactamente claro cuál es el alcance de la variable. Por lo tanto, debe ser explícito sobre sus variables, lo que significa declararlas con my para que estén restringidas al bloque actual, o referirse a ellas con su nombre completo (por ejemplo: MAIN MAIN::variablename).

Por lo tanto, se activa un error en tiempo de compilación si intenta para acceder a una variable que no ha cumplido al menos uno de los siguientes criterios:

  • Predefinido por el propio Perl, como @ARGV, % ENV y todas las variables de puntuación globales como $. o $_.

  • Declarado con nuestro (para un global) o mi (para un léxico).

  • Importado de otro paquete. (El uso vars pragma falsifica una importación, pero usa nuestro en su lugar.)

  • Totalmente calificado usando su nombre de paquete y el doble de dos puntos separador de paquetes.

Usar subs estrictos';

Considere dos programas

# prog 1
   $a = test_value;
   print "First program: ", $a, "\n";
   sub test_value { return "test passed"; }
 Output: First program's result: test_value

# prog 2
   sub test_value { return "test passed"; }
   $a = test_value;
   print "Second program: ", $a, "\n";
 Output: Second program's result: test passed

En ambos casos tenemos un sub test_value() y queremos poner su resultado en $a. Y sin embargo, cuando ejecutamos los dos programas, obtenemos dos resultados diferentes: {[17]]}

En el primer programa, en el punto que llegamos a $a = test_value;, Perl no sabe de ningún sub test_value (), y test_value se interpreta como la cadena 'test_value'. En el segundo programa, la definición de test_value() viene antes de la línea $a = test_value;. Perl piensa test_value como sub llamada.

El término técnico para palabras aisladas como test_value que podrían ser subs y podrían ser cadenas dependiendo del contexto, por cierto, es bareword. El manejo de Perl de barewords puede ser confuso, y puede causar errores en el programa.

El error es lo que hemos encontrado en nuestro primer programa, Recuerde que Perl no esperamos encontrar test_value(), por lo que aún no ha visto test_value(), se supone que quieres una cuerda. Así que si use strict subs;, causará que este programa muera con un error:

Bareword "test_value" no está permitido mientras "strict subs" esté en uso en ./a6-strictsubs.pl línea 3.

La solución a este error sería
1. Usa paréntesis para dejar claro que estás llamando a un sub. Si Perl ve $a = test_value ();,
2. Declare su sub antes de usarlo por primera vez

use strict;
sub test_value;  # Declares that there's a test_value() coming later ...
my $a = test_value;  # ...so Perl will know this line is okay.
.......
sub test_value { return "test_passed"; }

3. Y si quieres usarlo como una cadena, cítalo.

So, Esta restricción hace que Perl trate todos los barewords como errores de sintaxis. * A bareword es cualquier nombre desnudo o identificador que no tiene otra interpretación forzada por el contexto. (El contexto es a menudo forzado por una palabra clave o token cercano, o por predeclaración de la palabra en cuestión.) * Así que si quieres usarla como una cadena, comítala y si quieres usarla como una llamada a una función, predeclárela o usa paréntesis.

Las palabras vulgares son peligrosas debido a este comportamiento impredecible. use strict; (or use strict 'subs';) los hace predecible, porque las palabras a pelo que podrían causar un comportamiento extraño en el futuro harán que su programa muera antes de que puedan causar estragos

Hay un lugar donde está bien usar barewords incluso cuando has activado subs estrictos: cuando estás asignando claves hash.

$hash{sample} = 6;   # Same as $hash{'sample'} = 6
%other_hash = ( pie => 'apple' );

Las palabras sin palabras en las claves hash siempre se interpretan como cadenas, por lo que no hay ambigüedad.

Usar referencias estrictas';

Esto genera un error de tiempo de ejecución si utiliza referencias simbólicas, intencionalmente o de otra manera. Un valor que no es una referencia dura se trata entonces como una referencia simbólica . Es decir, la referencia se interpreta como una cadena que representa el nombre de una variable global.

use strict 'refs';

$ref = \$foo;       # Store "real" (hard) reference.
print $$ref;        # Dereferencing is ok.

$ref = "foo";       # Store name of global (package) variable.
print $$ref;        # WRONG, run-time error under strict refs.

Use advertencias;

Este pragma de alcance léxico permite un control flexible sobre las advertencias integradas de Perl, tanto las emitidas por el compilador como las del sistema en tiempo de ejecución.

De perldiag:

Así Que El la mayoría de los mensajes de advertencia de las clasificaciones siguientes, es decir, W, D y S, se pueden controlar utilizando el pragma warnings.

(W) Una advertencia (opcional)
(D) Una obsolescencia (habilitada por defecto)
(S) Una advertencia grave (habilitada por defecto)

He enumerado algunos de los mensajes de advertencia que ocurren a menudo a continuación por clasificaciones. Para obtener información detallada sobre ellos y otros mensajes consulte perldiag

(W) Una advertencia (facultativo):

Argumento faltante en %s
Falta el argumento to - % c
(¿Quiso decir & % s en su lugar?)
(Quiso decir "local" en lugar de "nuestro"?)
(¿Quisiste decir @ o @ en vez de %?)
"%s " no es una referencia de código
length () utilizado en %s
Fuera de lugar _ en número

(D) Una obsolescencia (habilitada por defecto):

Definido (@array) está en desuso
definido (%hash) está en desuso
Uso obsoleto de my() en falso condicional
$# ya no es compatible

(S) Una advertencia severa (habilitada por defecto)

Elseif debe ser elsif
%s encontrado donde el operador esperaba
(Falta el operador antes de %s?)
(Falta punto y coma en la línea anterior?)
%s nunca introducido
Falta el operador o punto y coma antes de %s
Problema de precedencia: open %s debe ser open (%s)
Desajuste del prototipo: %s vs % s
Advertencia: Uso de " % s" sin paréntesis es ambiguo
No se puede abrir %s: % s

 27
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
2016-01-29 17:47:24

Estos dos pragmas pueden identificar automáticamente errores en su código.

Siempre uso esto en mi código:

use strict;
use warnings FATAL => 'all';

FATAL hace que el código muera en las advertencias, al igual que lo hace strict.

Para obtener información adicional, consulte: Hágase más estricto con las advertencias de uso FATAL = > 'all';

También... Las restricciones, según Seuss

 10
Author: toolic,
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
2011-11-05 23:50:31

Hay un buen hilo en perlmonks sobre esta pregunta.

La razón básica obviamente es que las advertencias estrictas y masivas le ayudan a detectar errores y ayudan a la depuración.

 9
Author: moodywoody,
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
2015-12-12 11:02:48

Fuente:: Diferentes blogs

Use exportará funciones y nombres de variables al espacio de nombres principal mediante llamando a la función modules import ().

Un pragma es un módulo que influye en algún aspecto del tiempo de compilación o comportamiento en tiempo de ejecución de perl.Pragmas dar pistas al compilador.

Use warnings - perl complaints about variables used only once, improper conversions of strings into numbers,.Tratando de escribir a archivos que no se abren. sucede en compilar time.It se utiliza para advertencias de control.

Utilice el ámbito de las variables strict - declare. Se utiliza para establecer algún tipo de disciplina en el guión.Si se utilizan palabras sin valor en el código, son interpretar.Todas las variables deben tener un alcance, como mi, nuestro o local.

 3
Author: Rahul Reddy,
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-07-02 08:03:20

La directiva "use strict" le dice a Perl que haga comprobaciones adicionales durante la compilación de su código. El uso de esta directiva le ahorrará tiempo depurando su código Perl porque encuentra errores de codificación comunes que podría pasar por alto de otra manera.

 1
Author: MikasaAckerman,
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
2015-06-29 13:43:06

Estricto y advertencias asegúrese de que sus variables no son globales.

Es mucho más ordenado poder tener variables únicas para métodos individuales en lugar de tener que realizar un seguimiento de todos y cada uno de los nombres de las variables.

{_, o ninguna variable para ciertas funciones, también puede ser útil para escribir código más compacto más rápido.

Sin embargo, si no se utiliza estricto y advertencias, $ _ se convierte en global!

 0
Author: Andreas Ährlund,
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
2015-06-25 08:16:48
use strict;
use warnings;

Estricto y advertencias son el modo para el programa perl. Está permitiendo que el usuario ingrese el código más liberalmente y más que eso, ese código perl se verá formal y su estándar de codificación será efectivo.

Advertencias significa lo mismo que -w en la línea de perl shebang,por lo que será proporcionar las advertencias generadas por el programa perl, se mostrará en el terminal

 0
Author: dhana govindarajan,
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
2017-11-30 10:59:59