virtuoso tutorial query online example español perl

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