• Publicidad

Código que no entiendo

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Código que no entiendo

Notapor kaperu » 2009-04-16 11:24 @517

¡Buenas!

Estoy aprendiendo Perl a base de manuales y mirar códigos de otras personas.

Mirando un script me he encontrado con lo siguiente:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#... más código

$|=1;

  $datos_archivo = "$tmp_dir/$archivo";
  $tam_archivo = "$tmp_dir/$archivo"."tam";
1;

#... más código
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


El $|=1 me parece que equivale al flush con PHP... no sé si estoy en lo cierto.

Y ese 1; del final ¿¿qué significa??

Gracias de antemano.
kaperu
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2009-04-16 11:03 @502

Publicidad

Notapor explorer » 2009-04-16 12:20 @555

Bienvenido a los foros de Perl en Español, kaperu.

La sentencia $|=1 lo que hace es desactivar el buffer de salida de la salida estándar. Eso quiere decir que todas las salidas hacia la salida estándar serán inmediatas y completas, sin pasar por el buffer. Mas información en perldoc perlvar en tu ordenador.

Y el 1 final es porque, cuando se "carga" un módulo o paquete usando use o require, Perl exige que esa carga devuelva un valor positivo. Perl carga el módulo y lo interpreta e intenta inicializarlo como si fuera un programa normal. Se supone entonces que esa ejecución terminará con un valor positivo en su última sentencia. Pero... lo más normal es que los módulos no tengan código ejecutable en el momento de la carga inicial, por lo que nos encontramos con el problema de que no devolveríamos nada al programa que intenta usar ese módulo.

La solución es poner código ejecutable. Y que además devuelva un valor positivo. Así que ese 1 final hace esas dos cosas: es código ejecutable, y como es la última sentencia del código del módulo, se devuelve -su valor lógico- al programa llamante. Como el valor es positivo, el intérprete perl acepta la carga del módulo. Y el programa principal sigue.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor kaperu » 2009-04-17 11:03 @502

Muchas gracias por la respuesta.

El $|=1 me ha quedado claro, pero el 1; final no. Bueno, me ha quedado claro su funcionamiento, pero tengo unas dudas sobre los módulos en Perl.

En el trozo de script que he puesto más arriba tengo los siguientes módulos:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use CGI;
use CGI::Carp qw(fatalsToBrowser);
use Fcntl qw(:DEFAULT :flock);
use File::Temp qw/ tempfile tempdir /;
use LWP::UserAgent;
use HTTP::Request;
#...
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


La primera duda que tengo es qué significa el qw() con los diferentes parámetros. He estado leyendo en perldoc y otros manuales y por lo que he entendido el qw(fatalsToBrowser) por ejemplo, exporta la función fatalsToBrowser en concreto del módulo CGI::Carp. Pero en el caso de qw(:DEFAULT :flock) o qw/ tempfile tempdir / ¿cómo funciona?

La segunda duda es sobre el 1;, dices que se utiliza para que un módulo tenga código ejecutable y algún valor para devolver, pero ¿cómo sé yo de qué módulo viene ese 1; en el caso de tener varios módulos?

¡Un saludo!
kaperu
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2009-04-16 11:03 @502

Notapor kaperu » 2009-04-17 11:10 @507

Por cierto, he de decir que haces un excelente trabajo. Me he estado mirando un poco el foro y leyendo tus respuestas, y realmente ayudas mucho a la gente. Así da gusto aprender ;)


¡Muy buen trabajo!
kaperu
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2009-04-16 11:03 @502

Notapor explorer » 2009-04-17 13:04 @586

qw() es el operador que agrupa palabras y las devuelve como lista de valores. En el ejemplo, solo hay una palabra: fatalsToBrowser.

En el caso de las palabras :DEFAULT y :flock, lo más seguro es que no se refieran a funciones, sino a etiquetas, cada una de ellas representando a un conjunto de funciones. Podríamos pensar en que estamos importando algo así como un espacio de nombres, pero no es lo mismo. Cada etiqueta agrupa una serie de funciones y variables que importamos de golpe a nuestro programa. Así no hay que especificar cada función y cada variable/constante por separado.

Y para tempfile y tempdir, se ve que también son funciones, y se importan las dos. El uso de los delimitadores '/' en lugar de '()' es porque Perl permite que algunos operadores admitan distintos delimitadores. Cada programador usa los que le parecen más 'bonitos' (también hay algunos delimitadores con funciones especiales).

El 1; final se coloca al final de los módulos, para ser devuelto al programa principal, cuando en éste se usan los 'use'.

No entiendo porqué necesitas saber qué valores te devuelve cada módulo. Es un valor que ocurre solo en el momento de la carga, interpretación e inicialización del módulo.

Ejemplo. Tenemos un módulo así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
package MiModulo;
sub mi_funcion {
    my $argumento = shift;

    print "$argumento : ", $argumento*2, "\n";
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

y un programa que lo usa, así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

use MiModulo;

print MiModulo::mi_funcion(2);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Como ves, el módulo solo es un contenedor de funciones.

Si ejecutamos nuestro programa, sale:
Código: Seleccionar todo
MiModulo.pm did not return a true value at ./kk.pl line 6.
BEGIN failed--compilation aborted at ./kk.pl line 6 (#1)
    (F) A required (or used) file must return a true value to indicate that
    it compiled correctly and ran its initialization code correctly.  It's
    traditional to end such a file with a "1;", though any true value would
    do.  See perlfunc/require.

Uncaught exception from user code:
        MiModulo.pm did not return a true value at ./kk.pl line 6.
BEGIN failed--compilation aborted at ./kk.pl line 6.
 at ./kk.pl line 6
que quiere decir:
Código: Seleccionar todo
MiModulo.pm no devolvió un valor verdadero en ./kk.pl línea 6.
BEGIN falló--compilación abortada en ./kk.pl línea 6 (#1)
    (F) Un fichero requerido (o usado) debe regresar un valor verdadero para indicar que
    se compiló correctamente y se ejecutó su código de inicialización correctamente.  Es
    tradicional terminar un fichero así con un "1;", aunque cualquier valor verdadero
    servirá.  Ver perlfunc/require.

Excepción inesperada desde el código de usuario:
        MiModulo.pm no devolvió un valor verdadero en ./kk.pl línea 6.
BEGIN falló--compilación abortada en ./kk.pl línea 6.
 en ./kk.pl línea 6


Bueno, pues al módulo le ponemos un '1;' final, y ahora ya sale lo esperado:
Código: Seleccionar todo
2 : 4


Si en el módulo, en cambio, hubiera existido un bloque BEGIN{}, y, al ejecutarse, la última instrucción fuera positiva, también hubiera valido, por lo que sería necesario poner el 1; final.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor kaperu » 2009-04-20 09:39 @444

Gracias, ahora sí que lo entiendo :)
kaperu
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2009-04-16 11:03 @502


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados