• Publicidad

Bucle infinito

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

Bucle infinito

Notapor Eowyn » 2013-03-11 06:26 @309

Hola, tengo un problema con esta parte de un programa. No me da ningún error, pero no hace lo que pretendo que haga:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $fitxkopia;
  2. open( my $FITX, $fitxategia );
  3. {
  4.     local $/;
  5.     $fitxkopia = <$FITX>;
  6.  
  7.     #    $fitxkopia;
  8. }
  9. close $FITX;
  10. &Hash_Taula_Kargatu($fitxkopia);
  11.  
  12. sub Hash_Taula_Kargatu {
  13.     my @term_arraya1;
  14.     my @term_arraya2;
  15.  
  16.     my %Moten_Hash_Taula = (
  17.         "N.IZE-ARR" => \@term_arraya1,
  18.         "G.ADJ-ARR" => \@term_arraya2
  19.     );
  20.     my $fitxategia2 = $fitxkopia;
  21.     chomp($fitxategia2);
  22.     my $FITXkop = XML::XPath->new( filename => $fitxategia2 );    #irakurri fitxategia;
  23.  
  24.     my $nodeset = $FITXkop->find('/KAF/terms/term');              # bilatu "term" paragrafoak kaf fitxategian.
  25.     my $gakoa;
  26.  
  27.     foreach my $node ( $nodeset->get_nodelist ) {
  28.         my $term = XML::XPath::XMLParser::as_string($node);       #Nodo horren informazioa string moduan gorde.
  29.  
  30.         ($gakoa) = $term =~ /pos="(.*?)"/;
  31.         push( @{ $Moten_Hash_Taula{"$gakoa"} }, $term );
  32.         my @array = @{ $Moten_Hash_Taula{"N.IZE-ARR"} };
  33.  
  34.         #
  35.         print(@array);
  36.     }
  37.  
  38. }
  39.  
  40.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Quiero que coja el archivo, lo lea y cargue algunas partes (las que tienen N.IZE-ARR) en una tabla hash en la clave "N.IZE_ARR". Para comprobar si lo carga hago print(@array), pero en lugar de eso lo que hace es sacarme por pantalla todo el archivo. He probado quitando el "print" pero no afecta. Si ejecuto la subrutina por su lado (es decir, de la línea 16 en adelante), lo hace bien, es decir, sólo imprime lo que quiero, pero no para nunca (bucle infinito). ¡Qué lío! :oops:
Eowyn
Perlero nuevo
Perlero nuevo
 
Mensajes: 45
Registrado: 2011-06-04 08:51 @410

Publicidad

Re: Bucle infinito

Notapor explorer » 2013-03-11 12:35 @566

¿Los valores que sacas en $gakoa son correctos? Transforma el interior del bucle para que saque los valores de $gakoa.

Una cosilla más... :) Al principio de la subrutina haces algo que es normal en otros lenguajes:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     my @term_arraya1;
  2.     my @term_arraya2;
  3.  
  4.     my %Moten_Hash_Taula = (
  5.         "N.IZE-ARR" => \@term_arraya1,
  6.         "G.ADJ-ARR" => \@term_arraya2
  7.     );
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Declaras dos variables que luego usas para inicializar los valores del hash. El caso es que en Perl no es necesario hacer esto (bueno, casi nunca, depende de si queremos que existan las claves "N.IZE-ARR" y "G.ADJ-ARR" antes de entrar en el bucle).

Esas siete líneas las puedes dejar así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     my %Moten_Hash_Taula = (
  2.         "N.IZE-ARR" => [],
  3.         "G.ADJ-ARR" => [],
  4.     );
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
o incluso así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     my %Moten_Hash_Taula;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
si no es necesario que existan las claves por adelantado. En tu caso, en la línea 31 estás poblando el hash, así que las claves se van creando de forma automática.

El bucle infinito debe ser por otra razón. El bucle está gobernado por lo que devuelve $nodeset->get_nodelist().

¿Esto es también un bucle infinito?

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $i = 0;
  2. for my $node ( $nodeset->get_nodelist ) {
  3.     $i++;
  4. }
  5. print "$i nodos\n";
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: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Bucle infinito

Notapor Eowyn » 2013-03-12 16:59 @749

¡Muchas gracias! Eres como un angelillo de Perl :wink:

Los valores de $gakoa son correctos, incluso lo que devuelve el array es correcto y he podido arreglarlo en el subprograma. Es decir, el subprograma en sí funciona bien.

El problema viene en el main: en lugar de devolverme lo mismo que el subprograma (ya que el main sólo hace de nuevo coger el archivo, copiarlo a otro sitio y ejecutar el subprograma) me devuelve el archivo entero. Y lo más paranormal de todo es que incluso quitando el "print" me devuelve el archivo entero. Seguro que esto tiene sentido para ti, pero para mí... :oops:
Eowyn
Perlero nuevo
Perlero nuevo
 
Mensajes: 45
Registrado: 2011-06-04 08:51 @410

Re: Bucle infinito

Notapor explorer » 2013-03-12 18:03 @794

Lo que hace leer todo el archivo de golpe es la línea
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     local $/;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

que hace que la línea siguiente lea todo el archivo y lo meta dentro de $fitxkopia.

Lo curioso es:
  • en la línea 10 pasas $fitxkopia a la función, pero luego ella no lo lee como argumento, si no que lees en la línea 20 de forma directa
  • en la línea 20 copiamos el contenido de $fitxkopia a $fitxategia2, por lo que esta última contendrá todo el archivo leído antes
  • en la línea 22 mandamos leer un archivo cuyo nombre es el contenido en $fitxategia2. Se supone entonces que el primer archivo contenía solo el nombre de otro archivo, que es el que queremos realmente interpretar
Cuando hablas del main creo que te refieres a las líneas 1 a 10 que has publicado. Yo no veo problemas ahí. Son líneas muy claras.

Debes poner print() en cada fase del programa, para saber qué está haciendo. Y sacar los valores principales. Por ejemplo: no hace falta sacar el contenido de los nodos, sino solo cuántos nodos son. Y los valores que leemos desde archivos, sacarlos con corchetes:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. print "[$fitxkopia]\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

así sabremos si hay algún carácter extra que no debiera.

En último caso, habrá que usar el depurador para ir paso a paso y ver qué está haciendo.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Bucle infinito

Notapor Eowyn » 2013-03-19 18:05 @795

Lo siento pero esta vez no he entendido muy bien qué debo hacer.

Mi intención es esta:

  1. Meto el nombre del archivo por teclado.
  2. Cojo ese archivo y lo copio entero en la variable $fitxkopia
  3. Paso el archivo en $fitxkopia como parámetro a la subrutina Hash_Taula_Kargatu()
  4. Se ejecuta la subrutina
  5. Me saca en pantalla los nodos de la tabla hash que ha cargado con ese archivo y cuya clave sea $gakoa.

Como digo, funciona bien si ejecuto sólo la subrutina, el problema parece venir de o bien no saber pasar el parámetro, o bien no saber hacer la copia. :cry:
Eowyn
Perlero nuevo
Perlero nuevo
 
Mensajes: 45
Registrado: 2011-06-04 08:51 @410

Re: Bucle infinito

Notapor explorer » 2013-03-19 18:54 @829

Con tu explicación, ya queda más claro todo.

Y ahora vienen los problemas :)

¿Para qué necesitas leer todo el archivo en las líneas 2 a 8 si en la línea 28 el propio módulo XML::XPath ya se encarga de ello? (línea 22). Fíjate que estás pasando un argumento a new() en esa línea con la clave 'filename'. Según la página de manual: The filename parameter specifies an XML file to parse. Así que no necesitas leer el archivo XML porque ya se encarga de eso el propio new().

El programa quedaría así (no probado):
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. # Meto el nombre del archivo por teclado.
  4. print "Sartu fitxategiaren izena: ";
  5. my $fitxategia = <STDIN>;
  6. chomp $fitxategia;
  7.  
  8. -f $fitxategia  or  die "ERROREA: Ezin da fitxategi $fitxategia hori aurkitu";
  9.  
  10.  
  11. # Paso el nombre del archivo como parámetro a la subrutina Hash_Taula_Kargatu()
  12. Hash_Taula_Kargatu($fitxategia);
  13.  
  14.  
  15. # Me saca en pantalla los nodos de la tabla hash que ha cargado con ese archivo y cuya clave sea $gakoa.
  16. sub Hash_Taula_Kargatu {
  17.     my $fitxategi = shift;                                      # irakurri parametroa
  18.  
  19.     my %Moten_Hash_Taula = (
  20.         'N.IZE-ARR' => [],
  21.         'G.ADJ-ARR' => [],
  22.     );
  23.  
  24.     my $xpath = XML::XPath->new( filename => $fitxategi );      # irakurri fitxategia
  25.  
  26.     my $nodeset = $xpath->find('/KAF/terms/term');              # bilatu "term" paragrafoa KAF fitxategian
  27.  
  28.     foreach my $node ( $nodeset->get_nodelist ) {
  29.  
  30.         my $term = XML::XPath::XMLParser::as_string($node);     # Nodo horren informazioa string moduan gorde
  31.  
  32.         my($gakoa) =  $term =~ /pos="(.*?)"/;
  33.  
  34.         if (defined $gakoa) {
  35.             push @{  $Moten_Hash_Taula{ $gakoa }  }, $term;
  36.         }
  37.     }
  38.  
  39.     print "@{ $Moten_Hash_Taula{'N.IZE-ARR'} }\n";
  40.  
  41.     #use Data::Dumper;
  42.     #print Dumper \%Moten_Hash_Taula;
  43. }
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: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Bucle infinito

Notapor Eowyn » 2013-03-21 04:42 @237

Ahora ya me aclaro. ¡Muchísimas gracias! :oops:
Eowyn
Perlero nuevo
Perlero nuevo
 
Mensajes: 45
Registrado: 2011-06-04 08:51 @410


Volver a Básico

¿Quién está conectado?

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

cron