• Publicidad

Manejar varios ficheros de texto

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

Re: Manejar varios ficheros de texto

Notapor korsakof » 2016-04-14 03:25 @184

Hola.

Gracias por tu respuesta. Tengo varias listas, ¿crearías un módulo o varios?

¿A niveles de rendimiento se notaría? El tema es que tiene que leer bastantes GB de líneas.

Un saludo.
korsakof
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2016-03-02 03:20 @181

Publicidad

Re: Manejar varios ficheros de texto

Notapor explorer » 2016-04-14 16:13 @717

Yo no veo problemas.

Depende del flujo de información de esos GB :)

El cuello de botella es aplicar los patrones, por lo que hay que intentar optimizarlos lo máximo posible.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Manejar varios ficheros de texto

Notapor korsakof » 2016-04-22 03:04 @169

Hola.

Así quedó mi módulo pero tengo unos cuantos problemas a la hora de llamarlo ya que por cada lista tengo que tener un fichero de estos ya que accedo por el package (SecIP::getNumeroElementos(), por ej., para hacer uso de un método) y al tener varias listas tengo que ir cambiando el nombre al package SecIP1, SecIP2, etc... ya que cada package apunta a un fichero diferente. No sé cómo solucionar esto.

Paquete que uso:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. package SecIP;
  2. use strict;
  3. use warnings;
  4. require Exporter;
  5. our @ISA = qw(Exporter);
  6.  
  7. our $VERSION   = 1.00;
  8. our @EXPORT_OK = qw(build_ip_table %lista getNumeroElementos existeElemento getHash);
  9.  
  10. our %lista;
  11.  
  12. sub build_ip_table {
  13.     my ($ruta) = @_;
  14.     if ( !open( URL, $ruta ) ) {
  15.         return;
  16.     }
  17.     else {
  18.         my (@url) = <URL>;
  19.         chomp(@url);
  20.         close(URL);
  21.         %lista = map { $_ => 1 } @url;
  22.     }
  23. }
  24.  
  25. 1;
  26.  
  27. sub getNumeroElementos {
  28.     return keys %lista;
  29. }
  30. 1;
  31.  
  32. sub existeElemento {
  33.     my ($elemento) = @_;
  34.     return exists $SecIP::lista{$elemento};
  35. }
  36. 1;
  37.  
  38. sub getHash {
  39.     return \%lista;
  40. }
  41. 1;
  42.  
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4


Aparte, programando el módulo me han surgido un par de dudas de conceptos de Perl.

Duda 1: El siguiente código lo he visto en todos los módulos y no sé exactamente lo que realizan esas líneas. Me he leído varias veces la documentación de Perl y sigo sin entender por qué hay que usarlas.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. our @ISA = qw(Exporter);
  2. our $VERSION = 1.00;
  3. our @EXPORT_OK = qw(build_ip_table %lista getNumeroElementos existeElemento getHash);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Duda 2:
La siguiente es, qué diferencia hay entre las variable my, our, $, @... ¿por qué existen tantos tipos? ¿En qué se diferencian?

Muchas gracias por la ayuda. Un saludo.
korsakof
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2016-03-02 03:20 @181

Re: Manejar varios ficheros de texto

Notapor explorer » 2016-04-24 11:48 @533

Yo creo que lo estás complicando demasiado: no necesitas crear módulos para ir almacenando las URL que vas leyendo de los archivos. Todo eso lo puedes hacer desde el propio programa, metiéndolo todo en un único hash.

El array especial @ISA muestra la relación padre-hijo entre nuestro módulo y otros. En tu caso, estás heredando las funciones y métodos del módulo Exporter (ver secciones "Perl Classes y Perl Modules" en tu propio ordenador en perldoc perlmod, y en la Web (traducido al español)).

La variable $VERSION indica a la gente de fuera (otros programas y módulos) en qué versión está nuestro programa o módulo.

La variable @EXPORT_OK indica la relación de variables y funciones que, opcionalmente, otros programas y módulos pueden importar desde el nuestro.

Lo que las líneas 1 y 3 están haciendo es indicar que esto es un módulo del que podemos exportar una serie de variables y funciones, a otros programas y módulos, y así no es necesario poner el nombre completo para acceder a ellos.

Ejemplo, si en un programa ponemos

use SecIP qw(%lista);

entonces en ese programa podemos acceder a %lista de forma directa:

say $lista{$clave};

Si no lo hiciéramos así, estaríamos obligados a escribirlo así:

say $SecIP::lista{$clave};

my() y our() son dos funciones que declaran variables. my() declara variables en un ámbito léxico (local a un contexto), mientras que our() declara variables globales al paquete en donde nos encontremos. La diferencia entre los dos es que, mientras que my() declara nuevas variables, our() crea alias a variables globales preexistentes. Más información en perldoc -f my y perldoc -f our

'$' es el sigilo de las variables escalares. '@' es el sigilo de las variables array. '%' es el sigilo de las variables hash. Más información en tu propio ordenador en perldoc perldata, y en la Web (traducido al español).

Otro detalle: los '1' que aparecen repetidos en tu código.

Cuando Perl carga un módulo, lo ejecuta, por si resulta que dentro de él existe algún código de inicialización. Si, la última instrucción ejecutada dentro del módulo es 'verdadera', se dice entonces que la carga del módulo es correcta y se sigue adelante. Si no, se para con un error.

Como la mayoría de los módulos no tiene código de inicialización, o ese código no sabemos qué va a devolver o si no nos importa lo que haga, tenemos que asegurarnos que la carga del módulo devuelva siempre un valor 'verdadero'. Esa es la razón por la cual muchos módulos terminan con un '1;'. Como es una sentencia que se puede ejecutar, y estará hacia el final, estamos enviando ese valor 'verdadero' al módulo o programa que ha cargado nuestro módulo.

Por eso, en tu código... sobran todos los '1;', excepto el último :)

Otra forma, en lugar de usar módulos, es usar objetos:
Sintáxis: (SecIP.pm) [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2. package SecIP;
  3. use strict;
  4. use warnings;
  5. use autodie;
  6.  
  7. sub new {
  8.     my $clase = shift;
  9.     my $ruta  = shift;
  10.  
  11.     open my $URL, '<', $ruta;
  12.     my (@url) = <$URL>;
  13.     chomp(@url);
  14.     close $URL;
  15.  
  16.     my %lista = map { $_ => 1 } @url;
  17.     my $self  = \%lista;
  18.  
  19.     bless $self, $clase;
  20.  
  21.     return $self;
  22. }
  23.  
  24. sub getNumeroElementos {
  25.     my $self = shift;
  26.  
  27.     return scalar keys %{$self};
  28. }
  29.  
  30. sub existeElemento {
  31.     my $self     = shift;
  32.     my $elemento = shift;
  33.  
  34.     return exists $self->{$elemento};
  35. }
  36.  
  37. sub getHash {
  38.     my $self = shift;
  39.  
  40.     return {%{$self}};
  41. }
  42.  
  43. 1;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Sintáxis: (SecIP.pl) [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2. use v5.14;
  3. use Data::Dumper;
  4.  
  5. use SecIP;
  6.  
  7. for my $archivo (glob "lista*txt") {
  8.     my $secip = SecIP->new($archivo);           # creamos un objeto
  9.  
  10.     say $secip->getNumeroElementos();           # número de elementos leídos
  11.  
  12.     my $hash_ref = $secip->getHash();           # obtenemos el hash construido
  13.  
  14.     say Dumper $hash_ref;                       # lo volcamos en pantalla, para ver qué aspecto tiene
  15. }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Pero... para este problema, yo creo que no es necesario usar ni módulos ni objetos.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Manejar varios ficheros de texto

Notapor korsakof » 2016-04-26 01:58 @123

Hola.

¡¡¡Muchas gracias por la ayuda!!!

Sí que necesito que sean independientes entre sí ya que cada fichero almacena datos para una función. De esta forma podré crear objetos y usarlos a lo largo del código.

Por último, un par de líneas que no entendí.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  my $self  = \%lista; # --> ¿referencia a la lista creada?
  2.  
  3.     bless $self, $clase; # --> Asocia ese objeto a la clase desde la cual se está generado, ¿no?
  4.  
  5. #En la función get_Hash la orden en el return
  6.   return {%{$self}}; #--> ¿Referencia al hash o una copia?
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4



Gracias de nuevo. Un saludo.
korsakof
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2016-03-02 03:20 @181

Re: Manejar varios ficheros de texto

Notapor explorer » 2016-04-26 05:29 @270

korsakof escribiste:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  my $self  = \%lista; # --> ¿referencia a la lista creada? Sí
  2.  
  3.     bless $self, $clase; # --> Asocia ese objeto a la clase desde la cual se está generado, ¿no?
  4. # Más bien, es algo así: bautizamos el objeto $self con el nombre de $clase.
  5. # A partir de ese momento, $self es una instancia (un objeto) de la $clase
  6.  
  7. #En la función get_Hash la orden en el return
  8.   return {%{$self}}; #--> ¿Referencia al hash o una copia?
  9. # Bueno, esto es algo complicado... y un poco sucio. Seguro que se puede mejorar.
  10. # $self es un objeto de la $clase.
  11. # Como $self realmente es una referencia a un hash, pues lo desreferenciamos con %{...}.
  12. # El resultado es un hash (lista de elementos, pares de claves/valores).
  13. # Dentro de unas llaves, lo que estamos haciendo es crear un hash anónimo,
  14. # cuyos contenidos son los mismos que los que los del hash del objeto.
  15. # Como es un hash anónimo, return devuelve la referencia a ese hash.
  16.  
  17. # se pondría pensar que la línea equivale a
  18.    return $self;
  19. # ya que estamos devolviendo una referencia a un hash... pero no es del todo exacto.
  20. # Realmente estamos devolviendo una ref. a un hash, que está bautizada como $clase, así que
  21. # es una ref. a un objeto. Si le hacemos un Dump, saldrá el contenido del hash,
  22. # junto con una marca que indica que pertenece al espacio de nombres $clase
  23.  
  24. # En situaciones normales, valdría, pero si queremos ->exclusivamente<- el hash -los datos-
  25. # entonces una forma es sacarlos así. Otra hubiera sido crear un accesor más claro (recorrer el hash, por ejemplo).
Coloreado en 0.002 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: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Manejar varios ficheros de texto

Notapor korsakof » 2016-05-26 04:11 @216

Muchas gracias, creo que entendí todo.
korsakof
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2016-03-02 03:20 @181

Anterior

Volver a Básico

¿Quién está conectado?

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