perl - query - sparql tutorial español
¿Qué significa__PACKAGE__->{foo}? (3)
Estoy refactorizando un módulo perl en código heredado, y esta es una función del módulo:
sub get_user {
my $user = __PACKAGE__->{user};
if (!defined $user) {
# more code
__PACKAGE__->{user} = $user;
}
return $user;
}
Este módulo se compila bajo use strict
. Y no hay variables de paquete definidas. ¿Qué significa __PACKAGE__->{user}
?
__PACKAGE__
es el nombre del paquete actual; su código lo está utilizando como una referencia de hash simbólica. Entonces, si su paquete es foo, está configurando $foo::foo{''user''}
. Esto es algo extraño que hacer; Sospecho que puede ser un error.
Debido a que es una referencia simbólica, no debe permitirse bajo estricto. Sin embargo, parece ser que al menos cuando el paquete actual tiene varias partes (por ejemplo, Foo :: Bar, no solo Foo). Sin embargo, no dependería de que este error permanezca en efecto.
__PACKAGE__
es un hash. Esta sintaxis accede a un valor con clave.
use strict;
use warnings;
use 5.012;
{
package X::Y;
our $user = 10;
say $user;
say __PACKAGE__;
}
--output:--
10
X::Y
El nombre del paquete puede ser ''X :: Y'' pero la tabla de símbolos para el paquete se llama ''X :: Y ::'' (tenga en cuenta los dos puntos posteriores). Una tabla de símbolos es un hash de perl, y las claves en% X :: Y :: hash son los nombres globales utilizados en el paquete X :: Y. Los valores correspondientes son los typeglobs para cada nombre:
use strict;
use warnings;
use 5.012;
{
package X::Y;
our $user = 10;
say $user;
say __PACKAGE__;
say $X::Y::{user}; #Hash name is %X::Y::
}
--output:--
10
X::Y
*X::Y::user
Pero la expresión en la op:
__PACKAGE__->{user}
es equivalente a:
''X::Y''->{user}
No veo cómo esa línea logrará recuperar algo de un hash cuyo nombre es ''X :: Y ::'' (termina en dos puntos). Y de hecho, me sale este error:
use strict;
use warnings;
use 5.012;
{
package X::Y;
our $user = 10;
say $user;
say __PACKAGE__;
say $X::Y::{user};
say __PACKAGE__->{user};
}
--output:--
10
X::Y
*X::Y::user
Use of uninitialized value in say at 2.pl line 13.
Si el código crea realmente un hash llamado% X :: Y en algún lugar, entonces el código se ejecutará sin errores:
use strict;
use warnings;
use 5.012;
%X::Y = (); #This hash has nothing to do with the hash named
#%X::Y::, which is the symbol table for the
#X::Y package.
$X::Y{user} = ''hello'';
{
package X::Y;
sub get_user {
say __PACKAGE__->{user};
}
get_user;
}
--output:--
hello
Como se mencionó en el comentario, el hash% X :: Y no tiene nada que ver con el paquete X :: Y. De hecho, la línea:
%X::Y = ();
Declara explícitamente una variable llamada Y en el paquete X. El paquete X y el paquete X :: Y son dos paquetes diferentes.
Y no hay variables de paquete definidas
El subnombre es una variable de paquete:
use strict;
use warnings;
use 5.012;
{
package X::Y;
sub get_user {say ''hello'';}
say $X::Y::{get_user};
}
--output:--
*X::Y::get_user
El hecho de que exista un typeglob para el nombre ''get_user'' significa que el código usa al menos una variable global llamada ''get_user''.