next up previous contents index practicapracticaPP2moodleLHPmoodlepserratacpanmodulospauseperlgoogleetsiiullpcgull
Sig: Práctica: Referenciado Simbólico Sup: Referencias Ant: Gestión de la memoria Err: Si hallas una errata ...


Referencias simbólicas

Lo normal es que una expresión como $$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 data
Si 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 ::.



Subsecciones
next up previous contents index practicapracticaPP2moodleLHPmoodlepserratacpanmodulospauseperlgoogleetsiiullpcgull
Sig: Práctica: Referenciado Simbólico Sup: Referencias Ant: Gestión de la memoria Err: Si hallas una errata ...
Casiano Rodríguez León
2006-02-21