particle has asked for the wisdom of the Perl Monks concerning the following question:

while trying to override methods in Tie::StdHash, i've inadvertently screwed up STORE and FETCH. my print statement (last line) isn't printing the keys of %hash. i think it's in the My::TieHashTest methods, but i don't have my OO book handy. any ideas?

package My::TieHashTest; require Tie::Hash; @ISA= ( Tie::StdHash ); for( qw/ TIEHASH STORE FETCH FIRSTKEY NEXTKEY EXISTS CLEAR DELETE UNTIE DESTROY / ) { eval qq{ sub $_ { notify($_); shift->SUPER::$_ } } } sub notify { warn shift, $/ } package main; use strict; use warnings; tie my %hash => 'My::TieHashTest' or die; %hash= ( a=>1, b=>2, c=>3 ); $hash{d}= 4; print $_,$/ for keys %hash;

prints

> t-tiehash.pl TIEHASH CLEAR STORE STORE STORE STORE FIRSTKEY NEXTKEY DESTROY

~Particle *accelerates*

Replies are listed 'Best First'.
Re: tying hashes and SUPER
by dws (Chancellor) on Apr 16, 2003 at 20:01 UTC
    while trying to override methods in Tie::StdHash, i've inadvertently screwed up STORE and FETCH.

    On first glance, I'd guess that

    eval qq{ sub $_ { notify($_); shift->SUPER::$_ } }
    might be better written as something like
    eval qq{ sub $_ { my $self = shift; notify("$_"); $self->SUPER::$_ (@_); } }
    so that it's explict about passing arguments.

    Update: Nope, go with chromatic's approach.

      Ugh. You need to escape the sigil in $self. I'd rather use a closure to prevent me from having to be so clever:

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

      That's also untested. Mixing SUPER and autogenerated methods makes it a little knotty.

        ahh, much better. i was able to fix the minor bugs in dws's solution, but i like your method better. much more straightforward to muck with the symbol table than to exploit eval

        ~Particle *accelerates*

      You also need to pass @_ into the SUPER method and escape the $ in $self.

                      - tye

      no luck. if i do as you type, it seems notify is not called. the keys are printed, but no warn is generated. i' guess i'll have to dig a little deeper....

      ~Particle *accelerates*