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

2

8

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.

Heritage answered 27/4, 2011 at 20:2 Comment(2)
Does it work if you take the tie ... call out of the BEGIN block?Rentfree
If you do the tie later, perl's already been and gone looking for the glob that holds $Target::x, so nothing happens. Try running perl -M0=Terse foo.pl to see why.Eta
E
4

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

Eta answered 28/4, 2011 at 2:23 Comment(0)
V
1

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.

Vedanta answered 15/8, 2013 at 13:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.