• Publicidad

Duda sobre Term::Menu y hash

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

Duda sobre Term::Menu y hash

Notapor Leo_Gutierrez » 2011-01-28 19:46 @865

Hola a todos.

Estoy tratando de hacer un menú de archivos sobre la consola, esto es para elegir un archivo y que luego lo muestre en pantalla. Estoy intentando usar el módulo Term::Menu (Si saben alguno mejor, por favor, díganmelo).

Quiero que salgan los archivos de esta manera:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
0 -> abecedario_en_matriz.pl
1 -> abrir_archivo_para_actualizar.pl
2 -> agregar_al_vector_si_se_cumple_la_condicion.pl
3 -> agregar_lista_de_elementos_a_arreglo.pl
4 -> agregar_prefijo_a_cadena.pl
5 -> agregar_tokens_a_cadena.pl
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Yo agregaría a un hash %files los archivos hallados en el directorio X.

Pero Term::Menu tiene la siguiente estructura y no hallo cómo indicarle que tome mi hash para su uso:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use Term::Menu;
  2.   my $menu = new Term::Menu;
  3.   my $answer = $menu->menu(
  4.         Foo    => ["Bar", 'a'],
  5.   );
  6.   if(defined($answer)) {
  7.         print "Answer was $answer\n";
  8.   } else {
  9.         print "Answer was undefined\n";
  10.   }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


¿Podrían brindarme un poco de ayuda?
Leo_Gutierrez
Perlero nuevo
Perlero nuevo
 
Mensajes: 91
Registrado: 2008-08-20 23:38 @026

Publicidad

Re: Duda sobre Term::Menu y hash

Notapor explorer » 2011-01-28 20:11 @883

El hash le construyes como indica el módulo que debes hacerlo (una clave -el valor que recibes- y el valor es una referencia a un array que contiene la entrada que aparece en el menú, seguido de uno o más letras que es lo que el usuario puede pulsar.

Construyes el hash, y se lo pasas.

my $answer = $menu->menu( %hash );
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: Duda sobre Term::Menu y hash

Notapor Leo_Gutierrez » 2011-01-28 21:38 @943

Hola, explorer, gracias por la respuesta.

Suponiendo que tengo mi hash así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my %hash = (
  2.         1 => 'hola.txt',
  3.         2 => 'adios.pl',
  4.         3 => 'algo.c',
  5.         4 => 'otroasd.xml'
  6.         );
  7.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Y se lo paso al método menu():
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my %hash = (
  2.         1 => 'hola.txt',
  3.         2 => 'adios.pl',
  4.         3 => 'algo.c',
  5.         4 => 'otroasd.xml'
  6.         );
  7.  
  8.       use Term::Menu;
  9.         my $menu = new Term::Menu;
  10.        
  11.         my $answer = $menu->menu( %hash );
  12.        
  13.         if(defined($answer)) {
  14.               print "Answer was $answer\n";
  15.         } else {
  16.               print "Answer was undefined\n";
  17.         }
  18.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Obtengo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Can't use string ("otroasd.xml") as an ARRAY ref while "strict refs" in use at /usr/share/perl5/site_perl/Term/Menu.pm line 57.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


EDITO:

Usando este formato sí que se puede:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my %hash = (
  2.         1 => ["file.txt", 1],
  3.         2 => ["lalala.xml", 2],
  4.         3 => ["otro asd.text", 3],
  5.         4 => ["abc.cpp", 4]
  6.         );
  7.  
  8.       use Term::Menu;
  9.         my $menu = new Term::Menu(
  10.        
  11.         nooptiontext => "",
  12.         toomanytries => ""
  13.        
  14.         );
  15.        
  16.         my $answer = $menu->menu(%hash );
  17.        
  18.         if(defined($answer)) {
  19.               print "Answer was $answer\n";
  20.         } else {
  21.               print "Answer was undefined\n";
  22.         }
  23.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


El problema va a ser a la hora de agregar a la estructura elementos. explorer, ¿cómo podría agregarle al hash un valor siguiendo el patrón n => ["ALGO", n]?

Otra cosa, obtengo la salida como quiero, pero por defecto el módulo me está ordenando los archivos:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
  1. [leo@archero Desktop]$ perl pl.pl
  2. Please choose one of the following options.
  3.       4) abc.cpp
  4.       1) file.txt
  5.       3) otro asd.text
  6.       2) lalala.xml
  7. Please enter a letter or number corresponding to the option you want to choose:
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Gracias por la ayuda.

EDITO:

Podría hacer algo como:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $hash{$contador} = [$fichero, $contador]
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

¿?
Leo_Gutierrez
Perlero nuevo
Perlero nuevo
 
Mensajes: 91
Registrado: 2008-08-20 23:38 @026

Re: Duda sobre Term::Menu y hash

Notapor explorer » 2011-01-28 22:05 @962

Efectivamente, con

$hash{$contador} = [$fichero, $contador];

podrías ir agregando entradas del menú, porque es justo la estructura que se pide: un array anónimo que contiene al menos dos elementos: la entrada que aparece en pantalla y la opción a elegir del menú. Y eso se asocia a la clave del menú, que, en este caso, la has puesto a lo mismo que el usuario debe pulsar.

En cuanto al orden, no veo nada en el manual del módulo que indique el orden de salida de las entradas. Y como las entradas dentro de un hash no siguen el orden en que fueron escritas, por esa salen, aparentemente, desordenadas.

En eso caso, lo que podríamos hacer es que el hash que vamos a usar, configurarle para que sí devuelva las claves y valores en el mismo orden en que se crearon.

Para ello, se puede usar un módulo como Tie::IxHash. Al principio del programa escribes
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use Tie::IxHash;
  2. my %hash;
  3. tie %hash, Tie::IxHash;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
y a partir de ese momento, el hash devolverá las claves y valores de forma ordenada. También funcionarán las funciones keys() y values().
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: Duda sobre Term::Menu y hash

Notapor Leo_Gutierrez » 2011-01-28 22:13 @967

Gracias, explorer.

Voy a tener que instalar el módulo.

Una pregunta, ¿es normal que haya tenido que instalar el módulo Find?, ¿que no viene incluido ya en Perl?

Estoy hablando de la versión 5.12.2.

Ya funciona todo bien:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. #use strict;
  3. use warnings;
  4. use 5.010;
  5.  
  6. my %archivos;
  7. my $contador = 0;
  8.  
  9. use Tie::IxHash;
  10. tie (%archivos, Tie::IxHash);
  11.  
  12.  
  13. opendir(my $dir, ".") or die("Error abriendo directorio. $!");
  14. for(readdir($dir))
  15. {
  16.         #-f && say;
  17.         $archivos{$contador} = [$_, $contador++] if -f;
  18. }
  19.  
  20. use Term::Menu;
  21. my $menu = new Term::Menu(
  22.         nooptiontext => "",
  23.         toomanytries => ""
  24.                 );
  25.  
  26. my $answer = $menu->menu(%archivos);
  27.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Salida:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. [leo@archero Desktop]$ perl pl.pl
  2. Please choose one of the following options.
  3.       0) un.pl
  4.       1) code.c
  5.       2) pl.pl
  6.       3) code.cpp
  7.       4) code
  8.       5) _comandos.txt
  9.       6) shell.sh
  10. Please enter a letter or number corresponding to the option you want to choose: ^C
  11. [leo@archero Desktop]$
  12.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Gracias, si tengo otro problema les comento.
Leo_Gutierrez
Perlero nuevo
Perlero nuevo
 
Mensajes: 91
Registrado: 2008-08-20 23:38 @026

Re: Duda sobre Term::Menu y hash

Notapor Leo_Gutierrez » 2011-01-28 22:47 @991

Hola, explorer.

Tengo un último problema.

Después de agregar correctamente al hash, necesito saber como desreferenciar para obtener el valor, es decir:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. say "Elegiste el archivo : $archivos{$answer}";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Soy algo neófito en esto.

Saludos.

EDITO:

Ya lo he resuelto.

Al usar esto
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. say "Elegiste el archivo : $archivos{$answer}";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Me tiraba:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Elegiste el archivo : ARRAY(0x89bd6b0)
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Por lo que al recordar que es un array anónimo solo hice
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. say "Elegiste el archivo : $archivos{$answer}[0]";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Y listo.

Gracias.

EDITO:

Mi script por si a alguien le interesa es este:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use warnings;
  3. use 5.010;
  4.  
  5. my %archivos;
  6. my $contador = 0;
  7. my $dir;
  8.  
  9. use Tie::IxHash;
  10. use Term::Pager;
  11. tie (%archivos, Tie::IxHash);
  12. my $answer; #= $menu->menu(%archivos);
  13.  
  14. do
  15. {
  16.         %archivos = ();
  17.         $contador = 0;
  18.         opendir($dir, ".") or die("Error abriendo directorio. $!");
  19.         for(readdir($dir))
  20.         {
  21.                 $archivos{$contador} = [$_, $contador++] if -f; # && m/.*pl$/;
  22.         }
  23.  
  24.         use Term::Menu;
  25.         my $menu = new Term::Menu(
  26.         beforetext => "Elija su archivo : ",
  27.         aftertext => " : ",
  28.         nooptiontext => "",
  29.         toomanytries => ""
  30.                 );
  31.  
  32.         $answer = $menu->menu(%archivos);
  33. } while(!defined($answer));
  34.  
  35. close($dir);
  36.  
  37. my $text = do { local $/; open FILE, $archivos{$answer}[0]; <FILE> };
  38. my $t = Term::Pager->new(rows => 100, cols => 100, speed => 10);
  39. $t->add_text( $text );
  40. $t->more();
  41.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Saludos.
Leo_Gutierrez
Perlero nuevo
Perlero nuevo
 
Mensajes: 91
Registrado: 2008-08-20 23:38 @026


Volver a Básico

¿Quién está conectado?

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

cron