• Publicidad

Globales, strict mode y subs

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

Globales, strict mode y subs

Notapor gerkrt » 2010-12-25 20:55 @913

Tengo un problema bastante raro, al menos por lo que creía saber:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. our %config = ('nv',0,
  2.                         'log',1,
  3.                         'az',0,
  4.                         'logfile','C:\Users\we\Desktop\GG\llistasele\log.txt');
  5.  
  6.  
  7. open FILE, $config('logfile') or die "Error. No se ha podido crear el archivo de log: $!";
  8. close FILE;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


La idea es usar un hash de configuración que debería ser accesible en todos lados. Uso el modo strict, así que uso el our(), pero me da error en el open file, diciendo que requiere el package explícito (?).

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. sub impMsg{
  2.         my $msg;
  3.         ($msg) = @_;
  4.         #use vars qw/$config/;
  5.         our $config;
  6.        
  7.         my $dir = $config('logfile');
  8.         #local our $config;
  9.         if (not $config{'nv'}) {
  10.                 print $msg;
  11.         }
  12.        
  13.         if ($config{'log'}) {
  14.  
  15.                 open(IN,">> $dir"  or die "Error. No se ha podido crear el archivo de log: $!" );
  16.         print IN "$msg"; ## will append to the end
  17.         }
  18.  
  19. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Esta es la función que he escrito por ahora. Lo que no tengo claro es cómo se declara para usar la variable global aquí. Tras buscar, decían use vars qw/$config/; pero tampoco me funciona.
Última edición por gerkrt el 2010-12-31 15:44 @697, editado 1 vez en total
gerkrt
Perlero nuevo
Perlero nuevo
 
Mensajes: 33
Registrado: 2010-11-22 21:43 @946

Publicidad

Re: Globales, strict mode y subs

Notapor explorer » 2010-12-25 21:58 @957

our() asocia un nombre con una variable de package, en el package actual, para ser usado en el ámbito actual (que normalmente será todo el fichero).

Supongamos que tenemos un único fichero así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. package configuracion;
  3. use strict;
  4.  
  5. our %config = (
  6.     nv          => 0,
  7.     'log'       => 1,
  8.     az          => 0,
  9.     logfile     => 'C:/Users/we/Desktop/GG/llistasele/log.txt',
  10. );
  11.  
  12. package main;
  13. use strict;
  14. use feature 'say';
  15.  
  16. say $config{'logfile'};
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Aquí, %config es conocida porque ha sido definida en el mismo fichero. Aunque esté declarada y definida en otro package, our() la hace visible a todo el fichero, sin tener que ser cualificada como %configuracion::config.

En cambio, si tenemos cada package en un fichero distinto, el package main no sabrá nada de %config. En ese caso necesitaremos, o bien referirnos a ella de forma completamente cualificada, o importamos su nombre a nuestro propio espacio de nombres.

Para el primer caso:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. package main;
  3. use strict;
  4. use configuracion;          # ahora Perl conoce el espacio de nombres configuracion::*
  5. use feature 'say';
  6.  
  7. say $configuracion::config{'logfile'};   # accedemos a %config
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Para el segundo caso deberíamos usar el módulo Exporter y luego hacer una importación, pero quizás es muy lioso para un propósito muy simple de tener la configuración en un módulo aparte.

Alternativas más sencillas. Hacer un alias de la variable:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. package main;
  3. use strict;
  4.  
  5. use configuracion;
  6. use feature 'say';
  7.  
  8. local *config = \%configuracion::config;   # Extraño y demasiado complicado para el novato
  9.  
  10. say $::config{'logfile'};                  # El $::config{} es la forma corta de $main::config{}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

O hacer una copia en un hash local:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. package main;
  3. use strict;
  4.  
  5. use configuracion;
  6. use feature 'say';
  7.  
  8. my %config = %configuracion::config;  
  9.  
  10. say $config{'logfile'};
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Esto es más interesante: hacemos una copia del %config del package a un %config propio del package en donde estamos. Funciona, pero... es un poco chapucero.

Lo mejor es... importar, directamente, el código de %config en nuestro propio espacio de nombres. Para ello, modificamos el package donde está %config, a:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. # Definición de la configuración general
  2. %config = (
  3.     nv          => 0,
  4.     'log'       => 1,
  5.     az          => 0,
  6.     logfile     => 'C:/Users/we/Desktop/GG/llistasele/log.txt',
  7. );
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
que, como ves, lo dejamos muy sencillo para que otra persona que no sepa mucho de Perl lo pueda modificar fácilmente. Y en el programa:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use feature 'say';
  4.  
  5. our %config;                    # necesario por la presencia del 'use strict'
  6.  
  7. do 'configuracion.pm';          # carga de la configuración
  8.  
  9. say $config{'logfile'};         # acceso a la variable
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Y ya está. El do() realiza la carga e interpretación del fichero de configuración, haciendo que las variables declaradas y definidas en él pasen a nuestro programa.

do() tiene sus desventajas, como por ejemplo, que cada vez que se ejecuta vuelve a cargar e interpretar el contenido. Pero para este caso de un fichero de configuración, viene muy bien.

Más información en perldoc -f our, perldoc perlmod, perldoc -f do (aquí viene un ejemplo completo de cómo realizar la carga de ficheros de configuración teniendo en cuenta todos los posibles valores que nos devuelva do(), en caso de fallo).

Por otra parte, use vars es obsoleto. En su lugar hay que usar our().
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Globales, strict mode y subs

Notapor gerkrt » 2010-12-27 10:45 @489

Me da error con el hash, al sacar el valor, igual:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Use of uninitialized value in say at C:\Users\we\Desktop\GG\perl2.pl line 65.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use warnings;
  2. use strict;
  3. use File::Copy::Recursive;
  4. use File::Basename;
  5. use Archive::Zip;  
  6. use feature 'say';
  7.  
  8. our %config;                    # necesario por la presencia del 'use strict'
  9.  
  10. do 'C:\Users\we\Desktop\GG\perl2config.pm';          # carga de la configuración
  11.  
  12. say $config{'logfile'};         # MI línea 65
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


He puesto la ruta completa por si acaso. Pero da error igual.

Y el pm es:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. # Definición de la configuración general
  2. %config = {
  3.     nv          => 0,
  4.     'log'       => 1,
  5.     az          => 0,
  6.     'logfile'     => 'C:/Users/we/Desktop/GG/llistasele/log.txt',
  7. };
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
gerkrt
Perlero nuevo
Perlero nuevo
 
Mensajes: 33
Registrado: 2010-11-22 21:43 @946

Re: Globales, strict mode y subs

Notapor explorer » 2010-12-27 15:07 @671

Eso es muy raro...

Prueba a sacar el valor de retorno de do():
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $do_retorna = do 'C:/Users/we/Desktop/GG/perl2config.pm';
  2. say "[$do_retorna]";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

En perldoc -f do tienes un código para tratar los distintos valores que devuelve do(), pero si es un entero positivo, indicaría que no ha tenido problemas en leer el fichero de configuración:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $file = 'C:/Users/we/Desktop/GG/perl2config.pm';
  2. unless (my $do_retorna = do $file) {
  3.     warn "couldn't parse $file: $@" if $@;
  4.     warn "couldn't do $file: $!"    unless defined $do_retorna;
  5.     warn "couldn't run $file"       unless $do_retorna;
  6. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Globales, strict mode y subs

Notapor gerkrt » 2010-12-27 18:40 @820

Pues probando ese código, no me sale ningún warn(). Porque digo yo que saldrá como un print o warning normal, ¿no?

Y el retorno corriente del do() me da [1].

P.D.: estoy en busca de algún buen libro sobre Perl, y hay bastantes en la red, pasa que supongo que habrá mejores o peores, ¿alguna sugerencia?
gerkrt
Perlero nuevo
Perlero nuevo
 
Mensajes: 33
Registrado: 2010-11-22 21:43 @946

Re: Globales, strict mode y subs

Notapor explorer » 2010-12-27 18:48 @825

Bien, si sale un [1] quiere decir que el do() hace su trabajo. Lo que queda por averiguar es qué es lo que lee.

Después del do(), agrega estas líneas:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use Data::Dumper;
  2. say Dumper \%config;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


En cuanto a libros, sí, hay un montón. Por aquí hicimos una recomendación, hace un tiempo.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Globales, strict mode y subs

Notapor explorer » 2010-12-27 19:02 @835

Ya he visto el error... es pequeño, y, sobre todo, si estamos usando fuente de letra pequeña, aún más :)

Resulta que mi fichero de configuración es
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. # Definición de la configuración general
  2. %config = (
  3.     nv          => 0,
  4.     'log'       => 1,
  5.     az          => 0,
  6.     'logfile'   => 'C:/Users/we/Desktop/GG/llistasele/log.txt',
  7. );
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
mientras que el tuyo es
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. # Definición de la configuración general
  2. %config = {
  3.     nv          => 0,
  4.     'log'       => 1,
  5.     az          => 0,
  6.     'logfile'   => 'C:/Users/we/Desktop/GG/llistasele/log.txt',
  7. };
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

¿A que ahora que están juntos ves las dos diferencias? :lol:
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Globales, strict mode y subs

Notapor gerkrt » 2010-12-31 15:43 @697

XDDDDD, sí, cierto, aunque creo que quizás es algo que cambié cuando me puse en plan "pruébalo todo".

Vale, eso es todo, gracias por las repuestas.
gerkrt
Perlero nuevo
Perlero nuevo
 
Mensajes: 33
Registrado: 2010-11-22 21:43 @946


Volver a Básico

¿Quién está conectado?

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