2011-04-27 4 views
8

Analogamente al modo in cui è possibile utilizzare AUTOLOAD per definire subroutine su richiesta, mi chiedo se esiste un modo per legare lo stash di un pacchetto in modo da poter intercettare l'accesso alle variabili in quel pacchetto.In Perl, c'è un modo per legare una scorta?

Ho provato varie permutazioni della seguente idea, ma nessuno sembra funzionare:

{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; 

Questo muore con Bad symbol for scalar ... sull'ultima riga, senza mai la stampa "calling fetch". Se viene rimossa la riga , il programma viene eseguito ed esce correttamente.

La mia ipotesi è che l'errore abbia a che fare con lo stash, ma non lo stesso di hash, quindi il meccanismo di collegamento standard non funziona correttamente (o potrebbe semplicemente essere che la ricerca di stash non invoca mai il tie magia).

Qualcuno sa se questo è possibile? Pure Perl sarebbe la cosa migliore, ma le soluzioni XS sono ok.

+0

Funziona se si prende la chiamata 'tie ...' dal blocco 'BEGIN'? – mob

+0

Se si fa il legame più tardi, perl è già stato e andato a cercare il glob che contiene $ Target :: x, quindi non succede niente. Prova a eseguire perl -M0 = Terse foo.pl per vedere perché. – Alex

risposta

4

Si sta verificando un errore interno di compilazione ("Simbolo errato per scalare"), questo accade mentre Perl sta cercando di capire cosa dovrebbe essere '$ Target :: x', che è possibile verificare eseguendo un debug Perl con:

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

penso che la GV per ':: target' è sostituito da qualcosa di diverso quando si legano(), in modo che tutto ciò che alla fine cerca di raggiungere il suo hash interna non può. Dato che tie() è un po 'di confusione, ho il sospetto che quello che stai cercando di fare non funziona, che è anche suggerito da questo (vecchio) serie di scambi su 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 po 'tardi per la domanda, ma sebbene non sia possibile usare la cravatta per farlo, Variable :: Magic ti consente di attaccare la magia a una scorta e quindi ottenere qualcosa di simile.