• Publicidad

Sistema de variables para inputs

Así que programas sin strict y las expresiones regulares son otro modo de hablar. Aquí encontrarás respuestas de nivel avanzado, no recomendable para los débiles de corazón.

Sistema de variables para inputs

Notapor Blue_Shell » 2017-07-11 02:00 @125

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!
Blue_Shell
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2017-04-20 10:41 @487

Publicidad

Re: Sistema de variables para inputs

Notapor explorer » 2017-07-11 05:45 @281

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.
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: Sistema de variables para inputs

Notapor Blue_Shell » 2017-07-11 06:42 @321

Hola de nuevo, gracias, ya he solucionado el problema y funciona genial, muchas gracias de nuevo y ¡hasta pronto!
Última edición por Blue_Shell el 2017-07-11 07:25 @351, editado 1 vez en total
Blue_Shell
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2017-04-20 10:41 @487

Re: Sistema de variables para inputs

Notapor Blue_Shell » 2017-07-11 07:09 @339

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?
Blue_Shell
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2017-04-20 10:41 @487

Re: Sistema de variables para inputs

Notapor explorer » 2017-07-11 16:26 @726

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
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


Volver a Avanzado

¿Quién está conectado?

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