in reply to Whither the truth of a tied hash?

I put together this quick test and it seems to work as expected (I'm using perl : 5.005_02)
#!/usr/bin/perl -w use Fcntl; use SDBM_File; my %db; tie (%db, 'SDBM_File', './t.db', O_RDWR | O_CREAT, 0666); my $s=scalar keys (%db); print "s=$s\n"; $db{39485}=1; $db{354345}=1; $s=scalar keys (%db); print "s=$s\n"; foreach (keys %db){ print " \"$_\"\n"; } untie %db;
producing the following output
s=0
s=2
  "39485"
  "354345"
What are you tying to? Maybe there's a problem there.


Les Howard
www.lesandchris.com
Author of Net::Syslog and Number::Spell

Replies are listed 'Best First'.
RE: Re: Whither the truth of a tied hash?
by mojotoad (Monsignor) on Apr 28, 2000 at 23:48 UTC
    Your results are the scalar context of keys(). I'm talking about something like the following statement:
       if (%h) {
          ...do something with a non-empty hash
       }
    

    As far as I can tell, there is no method in the tied hash class that is invoked for this. Try the following module to test:

    package TieTest;
    
    use strict;
    use Carp;
    
    use vars qw(@ISA);
    
    use Tie::Hash;
    @ISA = qw( Tie::StdHash );
    
    sub STORE    { notify('STORE');    shift->SUPER::STORE(@_);    }
    sub FETCH    { notify('FETCH');    shift->SUPER::FETCH(@_);    }
    sub FIRSTKEY { notify('FIRSTKEY'); shift->SUPER::FIRSTKEY(@_); }
    sub NEXTKEY  { notify('NEXTKEY');  shift->SUPER::NEXTKEY(@_);  }
    sub EXISTS   { notify('EXISTS');   shift->SUPER::EXISTS(@_);   }
    sub DELETE   { notify('DELETE');   shift->SUPER::DELETE(@_);   }
    sub CLEAR    { notify('CLEAR');    shift->SUPER::CLEAR(@_);    }
    
    sub notify { print shift, " here.\n"; }
    
    1;
    
    You can use it with something like this:
       #!/usr/bin/perl
       use TieTest;
       tie %h, 'TieTest';
       grep($h{$_} = $_, 0 .. 9);
       print "Scalar test:\n";
       $c = %h;
       print "count is $c\n";
    
    Any ideas?
      The only thing I found that helped at all was copying the hash with a simple:
      my %i = %h; my $c = %i; print "count is $c\n";
      I even made an AUTOLOAD subroutine, to see if I could trap any other method calls. No luck.
        Ah, well. I figured as much. I guess I'll mine the net to see if it's a known problem with perl; if it has not been discussed yet I'll toss it at the porters.