Gay, Jerry on Thu, 17 Apr 2003 09:24:10 -0400


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

RE: tying stashes


mct--

i definitely found this interesting. unfortunately, when you tie a hash, it
clears the hash before it's blessed as a new object. everything i try (based
on your example) causes all available memory to be consumed, resulting in a
segfault.

i can, however, tie a regular hash (of course.) my wrapper notifies via
'warn' for every hash method. i've included my example code below. you can
replace '%hash' with '%main::' to experience the results i've mentioned
above. i tried putting all this in a BEGIN block, but no luck.

i'd love to see if you can do anything with it.

--particle

__CODE__

package My::TieHashTest;
require Tie::Hash;
@ISA= ( Tie::StdHash );

for my $method (
    qw/ TIEHASH STORE FETCH FIRSTKEY NEXTKEY
        EXISTS CLEAR DELETE UNTIE DESTROY / )
{   
    my $super = 'SUPER::' . $method;
    *{ $method } = sub {
        my $self = shift;
        notify( $method );
      
        $self->$super( @_ );
    };
}

sub notify { warn shift, $/ }


package main;

## run script with any argument to see it work,
## run script with no arguments to see it fail
if( @ARGV )
{
        tie %hash => 'My::TieHashTest'
                or die;
        %hash= ( a=>1, b=>2, c=>3 );
}
else
{
        %hash= ( a=>1, b=>2, c=>3 );
        tie %hash => My::TieHashTest
                or die;
}
print "$_ => $hash{$_}",$/ for keys %hash;

__ENDCODE__


-----Original Message-----
From: Michael C. Toren [mailto:mct@toren.net]
Sent: Tuesday, April 15, 2003 11:06 PM
To: phl@lists.pm.org
Subject: tying stashes


Some random thoughts inspired by Mark's talk yesterday:

As I was lying in bed trying to sleep last night, I found myself thinking
about globs and stashes, then suddenly wondered: if a stash is a hash, can
it be tied?  When I finally had time today to play with some code, I went
about experimenting by writing a tied class using Tie::StdHash and replaced
the STORE and FETCH functions so that some basic debugging information is
displayed:

        package MCT::TieHash;
        require Tie::Hash;
        our @ISA = qw(Tie::StdHash);

        sub STORE { print "-> store!\n"; $_[0]->{$_[1]} = $_[2] }
        sub FETCH { print "-> fetch!\n"; $_[0]->{$_[1]} }

I then tied %main:: to MCT::TieHash, hoping that when variables in the
main package were referenced my MCT::TieHash::FETCH and STORE functions
would be called:

        package main;
        tie %main::, 'MCT::TieHash' or die;
        print "%main:: is tied to ", tied %main::, "\n";

        $var = "store something";
        print "\$var contains ``$var''\n";

I was disappointed when it didn't work.  I was successfully able to tie
%main::, but it has no affect on variables in the main package:

        [mct@quint ~/perl]$ perl stashtie.pl
        %main:: is tied to MCT::TieHash=HASH(0x2df8c)
        $var contains ``store something''

It does, however, affect lookups in the %main:: hash.  For example:

        package main;
        tie %main::, 'MCT::TieHash' or die;
        print "%main:: is tied to ", tied %main::, "\n";
        print "\$main::{var} contains ``$main::{var}''\n";

yields the following when run:

        [mct@quint ~/perl]$ perl stashtie.pl
        %main:: is tied to MCT::TieHash=HASH(0x2e0a4)
        -> fetch!
        $main::{var} contains ``''

It might make more sense in this case to modify the FETCH function so that
it returns a value more appropriate in this scenario:

        sub FETCH { my $caller = caller; "*$caller\::$_[1]"; }

The net result of all this is that by tying the stash, it's possible to
write a class which affects the behavior of modules which walk the symbol
table.  That could have interesting results, but I can't think of any
practical applications at the moment.  Can anyone think of a module which
walks the symbol table, and would be fun to fool?

Thanks,
-mct (who hopes someone found this interesting)
-
**Majordomo list services provided by PANIX <URL:http://www.panix.com>**
**To Unsubscribe, send "unsubscribe phl" to majordomo@lists.pm.org**



************************************************************************** 
This e-mail and any files transmitted with it may contain privileged or 
confidential information. It is solely for use by the individual for whom 
it is intended, even if addressed incorrectly. If you received this e-mail 
in error, please notify the sender; do not disclose, copy, distribute, or 
take any action in reliance on the contents of this information; and delete 
it from your system. Any other use of this e-mail is prohibited. Thank you 
for your compliance.



-
**Majordomo list services provided by PANIX <URL:http://www.panix.com>**
**To Unsubscribe, send "unsubscribe phl" to majordomo@lists.pm.org**