in reply to How best to tell when my hash is "full" (all values defined)?

To answer your question (which is what you asked, not necessarily what you want :) ): use grep.
my @undefined = grep !defined $stats{$_}, keys %stats; if(@undefined { local $" = ", "; my $undefined = @undefined; warn "$undefined values were not defined, for keys (@undefined)\n" +; }

If you just want a simple count, not an elaborate report, you can use the simpler

my $undefined = grep !defined, values %stats; warn "$undefined values were not defined\n" if $undefined;

Replies are listed 'Best First'.
Re^2: How best to tell when my hash is "full" (all values defined)?
by OfficeLinebacker (Chaplain) on Dec 18, 2006 at 15:08 UTC
    bart, thanks for the reply. grep is another one of those functions that I don't know well. Continuing on our theoretical tangent, if you will, could one golf your approach down to
    grep !defined, values %stats || last;

    as a quick and simple escape clause?

    For some reason I like the idea of predeclaring what data I want (by mnemonic), and "filling" an empty data structure, as opposed to creating the key-value pairs on the fly. It's just mental I guess, though I suppose it may increase readability somewhat. Also, is there a memory or performance penalty if you don't predeclare the numer of elements in a hash? Returning the scalar of the hash gives me 4/8 with the predeclared version; I suppose I will try it the other way and report back.

    Thanks again to everyone,
    T.


    I like computer programming because it's like Legos for the mind.
      Hi,
      grep !defined, values %stats || last; my $swvn=grep !defined, values %stats; print $swvn; $swvn || last;
      produces
      3
      2
      2
      0
      
      so that means it doesn't work. The "fix" is to scalar() what grep() returns:
      scalar(grep !defined, values %stats) || last; my $swvn=grep !defined, values %stats; print $swvn; $swvn || last;
      produces
      3
      2
      2
      
      I'll check the memory consuption thing shortly.

      I like computer programming because it's like Legos for the mind.
      Hi again :) The following code (I plan to implement the piped open shortly, but just used what I have to test the memory usage of the hashes in the two approaches)
      my @raw=`top -b -n 1`; my (%stats,%stats2); my $expected_keys = 5; @stats{'users','load','tmem','fmem','runproc'} = (); my $its=0; foreach my $line (@raw){ if ($line =~ /up\s.+\s(\d+)\suser.+\s+load\saverage:\s+(\d+\.\d{2}), +/){ $stats{users}=$1; $stats{load}=$2; $stats2{users}=$1; $stats2{load}=$2; } elsif ($line =~ /(?:Tasks|processes):.+\s+(\d+) running/i){ $stats{runproc}=$1; $stats2{runproc}=$1; } elsif ($line =~ /^Mem:\s+(\d+)k\s+(?:total|av),.+used,\s+(\d+)k\s+fr +ee/){ $stats{tmem}=$1; $stats{fmem}=$2; $stats2{tmem}=$1; $stats2{fmem}=$2; } $its++; print scalar(%stats2); print scalar(%stats); (scalar(keys(%stats2)) == $expected_keys) && last; } ## end foreach my $line (@raw)
      outputs
      
      2/8
      4/8
      2/8
      4/8
      2/8
      4/8
      4/8
      4/8
      
      So the memory usage is no different (correct me if I am wrong--my understanding is that the number we are worried about (if we're worried about memory consumption) is the divisor).

      I'll go ahead and make the call to `top` a piped open and have done with it. Thanks for your help (everyone who posted).

      T.

      I like computer programming because it's like Legos for the mind.