2011-04-27 16 views
8

Similar a la forma en que AUTOLOAD se puede usar para definir subrutinas bajo demanda, me pregunto si hay una manera de vincular el alijo de un paquete para que pueda interceptar el acceso a las variables en ese paquete.En Perl, ¿hay alguna forma de atar un alijo?

He intentado varias permutaciones de la siguiente idea, pero ninguno parece funcionar:

{package Tie::Stash; 
    use Tie::Hash; 
    BEGIN {our @ISA = 'Tie::StdHash'} 
    sub FETCH { 
     print "calling fetch\n"; 
    } 
} 

{package Target} 

BEGIN {tie %Target::, 'Tie::Stash'} 

say $Target::x; 

Esta muere con Bad symbol for scalar ... en la última línea, sin tener que imprimir "calling fetch". Si se elimina la línea say $Target::x;, el programa se ejecuta y sale correctamente.

Supongo que la falla tiene que ver con que los depósitos son similares, pero no lo mismo que los hash, por lo que el mecanismo de enlace estándar no funciona bien (o puede ser que la búsqueda oculta nunca invoque magia de enlace).

¿Alguien sabe si esto es posible? Pure Perl sería lo mejor, pero las soluciones XS están bien.

+0

¿Funciona si tomas la llamada 'tie ...' del bloque 'BEGIN'? – mob

+0

Si haces el empate más tarde, perl ya ha estado y se fue a buscar el comodín que tiene $ Target :: x, así que no pasa nada. Intenta ejecutar perl -M0 = Termine foo.pl para ver por qué. – Alex

Respuesta

4

Se está produciendo un error interno de tiempo de compilación ("Símbolo incorrecto para escalar"), esto sucede mientras Perl intenta averiguar qué debe ser '$ Target :: x', que puede verificar ejecutando una depuración Perl con:

perl -DT foo.pl 
... 
### 14:LEX_NORMAL/XOPERATOR ";\n" 
### Pending identifier '$Target::x' 
Bad symbol for scalar at foo.pl line 14. 

creo que la GV para ':: Target' se sustituye por otra cosa cuando se ata(), de modo que cualquiera que sea el tiempo trata de llegar a su hash interna no puede. Teniendo en cuenta que el lazo() es un poco de un desastre, sospecho que lo que estamos tratando de hacer no va a funcionar, que también es sugerido por esta (antiguo) conjunto de intercambios de P5P:

https://groups.google.com/group/perl.perl5.porters/browse_thread/thread/f93da6bde02a91c0/ba43854e3c59a744?hl=en&ie=UTF-8&q=perl+tie+stash#ba43854e3c59a744

1

Un poco tarde a la pregunta, pero aunque no es posible usar el vínculo para hacer esto, Variable :: Magic le permite unir magia a un alijo y así lograr algo similar.

Cuestiones relacionadas