Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Perl, is there any way to tie a stash?

Similar to the way AUTOLOAD can be used to define subroutines on demand, I am wondering if there is a way to tie a package's stash so that I can intercept access to variables in that package.

I've tried various permutations of the following idea, but none seem to work:

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

This dies with Bad symbol for scalar ... on the last line, without ever printing "calling fetch". If the say $Target::x; line is removed, the program runs and exits properly.

My guess is that the failure has to do with stashes being like, but not the same as hashes, so the standard tie mechanism is not working right (or it might just be that stash lookup never invokes tie magic).

Does anyone know if this is possible? Pure Perl would be best, but XS solutions are ok.

like image 385
Eric Strom Avatar asked Apr 27 '11 20:04

Eric Strom


2 Answers

You're hitting a compile time internal error ("Bad symbol for scalar"), this happens while Perl is trying to work out what '$Target::x' should be, which you can verify by running a debugging Perl with:

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

I think the GV for '::Target' is replaced by something else when you tie() it, so that whatever eventually tries to get to its internal hash cannot. Given that tie() is a little bit of a mess, I suspect what you're trying to do won't work, which is also suggested by this (old) set of exchanges on p5p:

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

like image 152
Alex Avatar answered Nov 12 '22 01:11

Alex


A little late to the question, but although it's not possible to use tie to do this, Variable::Magic allows you to attach magic to a stash and thereby achieve something similar.

like image 27
tobyink Avatar answered Nov 12 '22 01:11

tobyink