Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Whither the truth of a tied hash?

by mojotoad (Monsignor)
on Apr 28, 2000 at 10:10 UTC ( #9548=perlquestion: print w/ replies, xml ) Need Help??
mojotoad has asked for the wisdom of the Perl Monks concerning the following question:

How can you test the truth of a tied hash? It seems that, when tied, the hash always returns 0 in scalar context. I'm using 5.005_03.

Comment on Whither the truth of a tied hash?
Re: Whither the truth of a tied hash?
by lhoward (Vicar) on Apr 28, 2000 at 18:43 UTC
    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

      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.
RE: Whither the truth of a tied hash?
by takshaka (Friar) on Apr 29, 2000 at 04:23 UTC
    If all you really want is whether the hash is empty, you can call FIRSTKEY directly.
    #!/usr/bin/perl -w use strict; use TieTest; my %h; tie %h, 'TieTest'; $h{$_} = $_ for 0..9; print defined scalar tied(%h)->FIRSTKEY ? "Not empty\n" : "Empty\n";
Reasoning behind the musings
by mojotoad (Monsignor) on May 01, 2000 at 22:05 UTC
    Well, the reason this concerns me is that I often tie variables in order to snoop on them. I was under the impression that the hash tie is the most venerable of ties; however, now I see a circumstance where a normal hash is used that would break when the hash is tied -- the program flow alters based on tied status. This is not a big deal with some of the younger ties, but a bit disconcerting for the hash tie.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://9548]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (8)
As of 2014-12-26 09:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (171 votes), past polls