develooper Front page | perl.perl5.porters | Postings from August 2001

Tying symbol tables

Thread Next
From:
Simon Cozens
Date:
August 8, 2001 17:36
Subject:
Tying symbol tables
Message ID:
20010804014720.A16657@netthink.co.uk
Someone (It might have been Stephane Payrand) asked me at TPC if you
could tie a symbol table. I've found out that it's a horribly, horribly
bad idea but in fact, it's actually possible to tie a symbol table.
There's a kind of Lovecraftian interest in doing this.

The problem is that symbol table lookups - a variable access, say -
are resolved at compile-time. $main::a is turned into an area of
storage at compile-time, so this won't work:
    tie %main::, 'main';
    sub TIEHASH {}
    return FETCH {*main::b}
    $main::a

You'll never get main::a because the tie is done at runtime, not compile
time.

But we can trick Perl, of course, by creating *another* compile time
after the run time - this is also known as "using eval".

So this works, of sorts:

    tie %main::, 'main';
    sub TIEHASH {}
    sub FETCH { *main::b }
    eval q/$main::a/;

Except for one thing. Where are we getting all these tie methods from?

The rot sets in earlier than you may think:
 Undefined subroutine &main::DELETE called at -e line 1.

Whoa, what's calling DELETE? It took me a while to work out what it
was - the debugger uses variable forms like "$::<(eval 1)" to store
information about the current subroutine. When the eval finishes, this
variable is removed from the stash. 

So we give it a DELETE method, but it still complains. Why? The DELETE
method, main::DELETE, lives in the symbol table. The symble table is tied. 
Can you see the problem? It can't even get at main::FETCH, poor thing.
Since it can't do a DELETE, it looks for an AUTOLOAD. Same problem.

It's at this point that bleadperl does the honourable thing and goes
insane. The stash is now magical, so we ought to check that the
overloading methods are up to date. We do this by fetching a bunch of
methods - uhoh. Since this goes awry, the magic cache is invalid. So we
need to check that the overloading methods are up to date. We do this by
fetching a bunch of methods...

And no, it doesn't get any better if you tie a symbol table you're not
sitting in. In that case, it just fails to work altogether. Yes, I know
why. Yes, it's probably fixable. But I think we really ought to just let
this one lie. Here be dragons.

Simon


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About