boo = "Cuidado!!";
print boo . ", te vas a caer de las escaleras!\n";
(estas "variables" en realidad son subrutinas, pero nadie tiene porqué saberlo :D Vamos a llamarlas variables igual, o a lo sumo "nuestras variables especiales", porque les tenemos mucho cariño).
Hay que declarar cada una de las variables como una subrutina. Un montón de copiar y pegar de código, repetido y dificil de mantener. Y ¡ay! si tenés que hacer algún cambio.
¿Se puede hacer más dinámico? No perfectamente como yo hubiera querido, pero zafa bastante bien.
Necesitamos primero definir cada variable con "var". Var no es más que una subrutina, que va a generar nuestra "variable especial".
var "espia";y luego podemos usarlas:
var "amante_de_espia";
espia = "James Bond";Ningún sigil. ¡Genial! ¿Cómo se hace? Es medio complicado, pero acá va:
amante_de_espia = "Mariam D'Abo";
say "Mi nombre es " . espia ", y me acuesto con " . amante_de_espia;
"espia" y "amante_de_espia" son en realidad funciones (lo vimos en la primera parte), asi que "var" tiene que crearlas al vuelo. Para eso tiene que ponerlas en el mismo namespace, osea, al mismo nivel que el programa principal.
sub var ($) {La parte horrible de esto, como se ve, es la cuarta linea.
my $p = "main";
no strict 'refs';
*{"${p}::${_[0]}"} = sub (;$) :lvalue {
state $internal = "**internal**";
if ( $_[0] ) { $internal = $_[0]; }
return $internal;
};
use strict;
}
*{"${p}::${_[0]}"}$p es "main" (linea 2) y ${_[0]} es $_[0] escrito minuciosamente. Sí escribimos: var "espia", $_[0] es "espia". Osea, que queda:
*main::espiaQue quiere decir que vamos a manejar el nombre "espia", en el namespace "main", exactamente donde nuestro programa lo va a ir a buscar.. Vamos bien.
La línea completa es así:
*main::espia = sub (;$) :lvalue {Que dice que nuestro nombre "espía" va a ser una función, igual que la que que vimos en la entrada anterior. Ese es todo el truco para insertarla en el espacio de nombres correcto.
Lo último que hace falta, que arruina un poco las cosas, es que el compilador, cuando revisa todo el script, encuentra que 'espia = "James Bond"' no es nada: no es una variable porque no tiene sigil, y no es una función, porque todavía no se ejecutó lo de arriba que hace que exista. Lo mejor que puede encontrar es que pongamos la definición en un bloque BEGIN:
BEGIN { var "espia"; }De esa manera, perl lo ejecuta primero, creando nuestras variables especiales para cuando las vaya a ejecutar. Y ¡ojo! También puede ser un buen lugar para declarar varias variables así:
BEGIN {
var "espia";
var "jefe";
var "familia_que_ignora_la_verdad";
}
Creo que voy a hacer una tercera parte. Quedaron ideas :)
Saludos!
-- Diego.
No hay comentarios:
Publicar un comentario