Página 1 de 1

Sistema de variables para inputs

NotaPublicado: 2017-07-11 02:00 @125
por Blue_Shell
Hola chicos, bueno, al grano...

Tengo un problemilla. Estoy intentando hacer un sistema de variables que se use en los inputs, tal como las variables de bash, y se me había ocurrido algo tal que así:

### He resumido un poco el script porque tiene 500 líneas ###

Paso 1: Exportar la variable

El usuario introduce #Export nombre_de_la_variable variable y se escribe en un .txt en el directorio /home/usuario_que_lo_haga o en /etc/ si es root.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $CMD = <STDIN>;
  2. my $USER = POSIX::cuserid();
  3. chomp $CMD ;
  4. my @CMD = split(/\s+/, $CMD);
  5. elsif (@CMD[0] eq "#Export") {
  6.         my $variable_nom = "@CMD[1]";
  7.         my $variable_eq = "@CMD[2]";
  8.         if ($USER eq "root"){
  9.                 open (VARLIST, ">> /etc/rlsh_varlist.txt");
  10.                 print VARLIST "@CMD[1] @CMD[2]\n";
  11.                 close VARLIST;
  12.         }
  13.         else{
  14.                 open (VARLIST, ">> /home/$USER/rlsh_varlist.txt");
  15.                 print VARLIST "@CMD[1] @CMD[2]\n";
  16.                 close VARLIST;
  17.         }
  18. }
  19.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Paso 2: Todo esto pasa en un ciclo while que captura la variable $CMD todo el rato, así que en el siguiente ciclo se ponen en uso las variables. Si no encuentra un archivo de variables, lo crea.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. if ($USER eq "root") {
  2.         if (-e "/etc/rlsh_varlist.txt") {
  3.              open (my $READVARS, "< /etc/rlsh_varlist.txt") or warn "Variables not active\n";
  4.              while (my $row = <$READVARS>) {
  5.                   chomp $row;
  6.                   my @VARS = split(/\s+/, $row);
  7.                   my %variables_hash = (
  8.                   "@VARS[0]" => "@VARS[1]",
  9.                   "@VARS[2]" => "@VARS[3]",
  10.                   "@VARS[4]" => "@VARS[5]",
  11.                   );
  12.              }
  13.              close $READVARS;
  14.      }
  15.      else{
  16.         open (CREATEVARS, "> /etc/.rlsh_history");
  17.         close CREATEVARS;
  18.      }
  19. }
  20. else {
  21.         $COLOR = 'bold blue' ;
  22.         $SH_PATH = "/home/$USER";
  23.         if (-e "$SH_PATH/rlsh_varlist.txt") {
  24.                 open (my $READVARS, "< $SH_PATH/rlsh_varlist.txt") or warn "Variables not active\n";
  25.                 while (my $row = <$READVARS>) {
  26.                         chomp $row;
  27.                         my @VARS = split(/\s+/, $row);
  28.                         my %variables_hash = (
  29.                         "@VARS[0]" => "@VARS[1]",
  30.                         "@VARS[2]" => "@VARS[3]",
  31.                         "@VARS[4]" => "@VARS[5]",
  32.                         );
  33.                 }
  34.                 close $READVARS;
  35.          }
  36.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

¿Está bien como lo hago? Si estos hashes están bien creados, ¿cómo podría identificarlos en el input y sustituirlos por su valor? ¿Hay algún módulo que haga esto?
¡Gracias por adelantado!

Re: Sistema de variables para inputs

NotaPublicado: 2017-07-11 05:45 @281
por explorer
No estoy muy seguro de lo que quieres hacer, pero parece que es como un sistema de plantillas, o que quieres tener una serie de valores en ciertas variables.

Lo que sí está claro es que hay algunos errores en el código. Y el más grave es usar la forma @CMD[0]. El programa sí que te funciona, pero puede darte una sorpresa en algunas situaciones.

Verás, en Perl, los array tienen el sigilo '@' delante del nombre de la variable, que usamos en el momento de su declaración:

my @array;

Pero a partir de ese momento, el sigilo que ponemos delante denota la pluralidad (o aridad) de los elementos que queremos almacenar/extraer de ese array.

Si vamos a almacenar un valor, uno solo, entonces tenemos que ponerlo un '$':

$array[1023] = "Vecino del quinto";

say $array[998];


En cambio, si queremos acceder a varios elementos, el sigilo cambia a '@':

@array[23, 24, 100] = (12, "hola", sqrt 100);

@array[0 .. 19] = map { int 1 + rand 10 } 0 .. 19; # 20 números aleatorios entre 1 y 10, incluidos

print "@array[8,11]\n";


Entonces, cuando en tu código pones @VARS[0], estás indicando a Perl que quieres recuperar "una lista de elementos desde VARS, compuesta de solo el elemento que está en la posición 0".

Esto, en principio, parece que no es importante, pero lo que estás haciendo es ejecutar esa sentencia en contexto de lista, sobre lo que tienes en el lado izquierdo de la expresión. Y en Perl, hay funciones y métodos que funcionan de forma distinta si están en contexto escalar o en contexto de lista.

Dicho esto, he realizado algunos cambios en tu código, para que quede algo más sencillo.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $USER = POSIX::cuserid();
  2. my $FILE = $USER eq 'root'      ? '/etc/rlsh_varlist.txt'
  3.          :                        "/home/$USER/rlsh_varlist.txt"
  4.          ;
  5.  
  6. my $CMD  = <STDIN>;
  7. chomp $CMD;
  8.  
  9. my @CMD = split " ", $CMD;
  10.  
  11. if ($CMD[0] eq '#Export') {
  12.  
  13.         open (VARLIST, ">>$FILE");
  14.         print VARLIST "$CMD[1] $CMD[2]\n";
  15.         close VARLIST;
  16. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $FILE = $USER eq "root"      ? '/etc/rlsh_varlist.txt'
  2.          :                        "/home/$USER/rlsh_varlist.txt"
  3.          ;
  4.  
  5. my %variables_hash;
  6.  
  7. open (my $READVARS, "<$FILE") or die "Variables not active\n";
  8. while (my $row = <$READVARS>) {
  9.     chomp $row;
  10.     my @VARS = split " ", $row;
  11.  
  12.     $variables_hash{ $VARS[0] } = $VARS[1];
  13. }
  14. close $READVARS;
  15.  
  16. # A partir de aquí ya tenemos el hash poblado de entradas
  17. #
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Y ya puedes usar el hash, por ejemplo:

print $variables_hash{'mi_variable'}, "\n";


P.D.: En Perl 6, las variables mantienen su sigilo a lo largo de todo el programa.

Re: Sistema de variables para inputs

NotaPublicado: 2017-07-11 06:42 @321
por Blue_Shell
Hola de nuevo, gracias, ya he solucionado el problema y funciona genial, muchas gracias de nuevo y ¡hasta pronto!

Re: Sistema de variables para inputs

NotaPublicado: 2017-07-11 07:09 @339
por Blue_Shell
Ahora tengo otra dudilla :?

Para incluir estas variables a los input, he creado estas líneas de código:
Sintáxis: [ Descargar ] [ Ocultar ]
  1. while (($key, $value) = each %variables_hash) { 
  2.      if (-1 != index($CMD, $key)) { 
  3.       #Aqui estaria el proceso para cambiar la llave por el valor del hash; 
  4.      } 

Solo necesito el método para cambiar en la cadena de texto la llave por el valor del hash, es decir, si en el hash hubiera una llave llamada "amigo" y un valor asociado, como por ejemplo "roberto", si la string fuera "mi amigo es verde" cambiarla quedando "mi roberto es verde". ¿Sabrías cómo?

Re: Sistema de variables para inputs

NotaPublicado: 2017-07-11 16:26 @726
por explorer
Sí, es algo que se hace muy a menudo.

Consiste en hacer una sustitución. De hecho, así es como funcionan los sistemas de plantillas que hay para Perl y para el resto de lenguajes.

$CMD =~ s/\{$key\}/$variables_hash{$key}/ge;

Ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
> perl -E '%hash = ("hola" => "adiós"); $x = "Esto solo es un {hola}."; say $x; $x =~ s/\{hola\}/$hash{hola}/ge; say $x'
Esto solo es un {hola}.
Esto solo es un adiós.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4