$$a
indique
que $a
es una variable del tipo referencia a un escalar.
Si no fuera el caso, esto es, si $a
no fuera
una referencia, Perl comprueba si $a
contiene
una cadena (esto es, la variable
está en un contexto escalar cadena) y si es el caso usa esa cadena
como nombre de la variable. Esto se conoce como
referenciado simbolico. Su uso es mas eficiente que la alternativa
de usar eval
. Veamos un ejemplo:
DB<1> $user = "juan" DB<2> $a = "user" DB<3> $$a = "pedro" DB<4> p $user pedro
El pragma strict
impide el uso de referencias simbólicas:
$ cat symbol_ref.pl #!/usr/bin/perl -w use strict; my $x = 4; my $a = "x"; $$a = 10; print $x; $ ./symbol_ref.pl Can't use string ("x") as a SCALAR ref while "strict refs" in use at ./symbol_ref.pl line 7.
Se puede ser mas específico y restringir solo el uso de
referencias simbólicas con use strict 'refs'
:
$ cat symbol_ref2.pl #!/usr/bin/perl -w use strict 'refs'; $x = 4; # no my $a = "x"; # $a no declarada $$a = 10; print $x; $ ./symbol_ref2.pl Can't use string ("x") as a SCALAR ref while "strict refs" in use at ./symbol_ref2.pl line 7.
Si, por el contrario, lo que se quiere es permitir el uso
de referenciado simbólico en un segmento del programa sin renunciar al
control que nos da use strict
, debemos usar la cláusula no
:
$ cat -n ./symbol_ref3.pl 1 #!/usr/bin/perl -w 2 3 use strict; 4 5 my $x = 4; 6 my $a = "x"; 7 { 8 no strict 'refs'; 9 $$a = 10; 10 } 11 12 print "$x\n"; $ ./symbol_ref3.pl 4
Por tanto:
Otro ejemplo:
#!/usr/bin/perl -w package main; sub data { print "inside data\n"; } $data = 4; @data = (1,2,3,4); $name = "data"; print "${$name}\n"; push @{$name}, @data; print "@data\n"; &{$name}();La ejecución da como resultado:
~/perl/src> symbolic.pl 4 1 2 3 4 1 2 3 4 inside dataSi la cadena sigue las reglas de un nombre completo, Perl utilizará la tabla de símbolos adecuada:
$name = "General::Specific::data"; print ${$name}; # Lo mismo que: print $General::Specific::data;Las referencias simbólicas tambien pueden usarse a la izquierda del operador
->
$symref = "set"; $symref->{type} = "discrete"; # Lo mismo que: $set->{type} = "discrete";
Es importante señalar que, puesto que las referencias simbólicas acceden a la tabla de símbolos, no pueden ser usadas para acceder a las variables léxicas. Por ejemplo:
#!/usr/bin/perl { my $grain = "headache"; ${"grain"} = "rye"; print "$grain\n"; } print "$grain\n";Imprime la primera vez
headache
y no rye
. Es asi porque la variable
léxica $grain
oculta a la variable de paquete $main::headache
en el ámbito. La salida del programa es:
$ symbolex.pl headache rye
En un programa Perl pueden existir varias tablas de símbolos.
Una declaración package
cambia el ``espacio de nombres''
hasta que encontremos una nueva declaración package
,
o hasta el final del bloque actual. De hecho, las variables en
Perl se clasifican como package variables
y lexical variables
.
Estas últimas son las declaradas con my
. Las
variables package
pertenecen, naturalmente, a un package
(normalmente el actual).
El package
inicial es el package main
.
Cuando sea necesario hacer explícito a que package
pertenece
la variable, puede hacerse prefijando su nombre con el del
package
, separado por ::
.