2009-12-07 11 views
15

La práctica común en Perl es, por supuesto, finalizar los módulos con 1;, de modo que se pueda verificar el éxito de una llamada para requerirla. ¿Hay alguna razón por la cual el valor de retorno no podría ser otro valor verdadero? En mi prueba, no parece causar ningún problema, pero me gustaría saber si alguien ha encontrado algún problema (como algunos otros módulos o pragmas o cualquier cosa que espere que el valor realmente sea 1 y no solo cierto) .¿Cuáles son los valores válidos de devolución del módulo Perl?

Editar: Por opinión popular, y como solo funcionará una vez (buena sugerencia), el ejemplo del código se ha ido. Parece que el consenso es que es seguro devolver cualquier valor verdadero, pero nunca confiar en ese valor en el código de llamada desde require devolverá 1 después de la primera carga

+0

¿Por qué querrías hacer esto? – innaM

+3

odio escribir lo mismo dos veces. Estoy de acuerdo, tengo un problema de refactorización, he asistido a reuniones ... –

+7

La refabricación es una cosa, el golf es otra. ;) –

Respuesta

17

He estado poniendo cosas tontas al final de mis módulos por un tiempo. No hay daño y es un pequeño huevo de Pascua. uny2k útil termina con "Yes, this code is a joke."Class::Fields está lleno de ellos.

Yendo un paso más allá, a veces, cuando se documenta una función para devolver true y false, devolveré algo distinto de 1 para true. Esto es para castigar a las personas que escriben if foo() == 1 cuando quieren decir if foo(). Esto fue más o menos en el mismo período que estaba escribiendo use constant TRUE => 1==1; use constant FALSE => !TRUE;

He visto el valor de retorno de un módulo utilizado en el código de producción. No recuerdo exactamente por qué. La lógica del desarrollador fue ... torturada. Creo que fue algo así como no querer tener que escribir solo una línea en lugar de dos. No recuerdo por qué no solo lo exportó.

Este fue el mismo desarrollador que utiliza %_ para pasar argumentos en torno (el símbolo *_ es global través de paquetes) y escribió declaraciones mapa 150 dentro de la línea de declaraciones de mapas.

El peligro de usar el valor de retorno, además de la ofuscación, es que solo funciona una vez.

$ cat Foo.pm 
package Foo; 

return "Basset hounds got long ears"; 

$ cat test.plx 
#!/usr/bin/perl -w 

print require Foo, "\n"; 
print require Foo, "\n"; 

$ perl -I. test.plx 
Basset hounds got long ears 
1 

La primera llamada a require evalúa Foo.pm y devuelve el valor de retorno. La segunda llamada ya está en %INC y simplemente devuelve verdadero. Y ni siquiera puede estar seguro de que sea lo primero que necesita el código. Puede solucionar esto con do "Foo.pm" pero ahora está recargando el módulo cada vez con advertencias sobre rutinas redefinidas, problemas de rendimiento y posiblemente la reinicialización de globales. Que no vale la pena.

8

Creo que (1) no hay problema con devolver cualquier verdad arbitraria valor de su módulo, pero (2) hay un gran problema con el código oscuro, excesivamente inteligente que sugiere explotar los detalles de implementación del módulo. No hagas eso.

4

El propósito es que si su módulo devuelve falso, el requerimiento puede fallar en ese punto. A nadie le importa o confía en el valor más allá de ser verdadero o falso.

Deberías hacer lo mismo. Lo está haciendo para que sus módulos dependan del valor real más allá de si es verdadero o falso. En el ejemplo que proporcionó, por ejemplo, si su requerimiento resulta devolver 1, el requerimiento tendrá éxito, pero su constructor inteligente fallará.

7

Cualquier cosa es un valor de retorno válido. Si desea que el require tenga éxito, debe ser un valor verdadero. Si no desea que el require tenga éxito (por ejemplo, plataforma no compatible, biblioteca faltante), use un valor falso.

Para ver lo que otras personas han usado como valores devueltos, consulte Acme::ReturnValue.

Las personas no esperan utilizar el valor de retorno para nada, por lo que no confundiría a las personas al intentar hacerlo, sin importar lo inteligente que parezca en ese momento. :)

+0

¡Hola, Brian! Eres un TAN Dios. –

+0

Quería decir hola el otro día, pero era flojo. Parece que lo estás haciendo bien. :) –

6

Mark Dominus, autor de Higher-Order Perl, explica mi favorito:

muy rara vez he utilizado $flag = 'Cogito ergo sum'; que, como todo el mundo sabe es evidentemente cierto en todos los universos posibles. Esto asegura máxima portabilidad.

1

Una cosa que se encontrará con la require es que sólo devuelve el valor devuelto por el módulo de la primera vez que el módulo está cargado. Si el módulo ya estaba cargado, require returns 1 sin cargar el módulo nuevamente.

La instrucción do file volverá a cargar el archivo cada vez y devolverá el valor de retorno del archivo cada vez. Lo he usado para almacenar datos de configuración en un archivo en forma de hash anónimo.

+0

'do file'" funciona ", pero es realmente difícil realizar una comprobación de errores. Sería mucho mejor si almacenara datos de configuración en un formato de análisis definido como YAML, en lugar de llenar directamente las estructuras de datos en una biblioteca separada. – Ether

+0

@Ether puedo pensar en razones para no pegar información de configuración en una estructura de datos de Perl (es insegura e imposible de transportar) pero la comprobación de errores no es una de ellas. Perl hace la comprobación por ti. 'do $ file || morir' es suficiente. – Schwern

Cuestiones relacionadas