sandeep.waikar has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I am having below hash in my programm.

$moduleRef->{modRef}{$moduleName}{ioRef}{$net}.....

When is check for some string of $net1 if its is part of hash and defined or not, It went into that loop even if its wasn't part of the hash.

My code is here.

foreach my $net(@netLst){ if($net =~ /\'/) {next;} elsif(defined ($moduleRef->{modRef}{$moduleName}{ioRef}{$net})) { print "$net is part of hash"; } }

Even though some element of @netLst which wasn't defined for above hash, else loop got executed and it printed
  "XYZ is part of hash"... where as actually its not.

Please help me in solving this.
I am using Pel v5.10.1 version.

Thanks,
Sandeep

Replies are listed 'Best First'.
Re: Wrong Results in checking if hash value is defined or not
by Eily (Monsignor) on Jun 30, 2017 at 08:26 UTC

    Code has to be posted between <code> and </code>, it is not terminated by <endcode>. Read Markup in the Monastery for more info.

    If you don't give us any sample data, all we can say is that yes, $moduleRef->{modRef}{$moduleName}{ioRef}{$net} does seem to be defined. What you can do is check what you actually have rather than "be sure". You could add the value in your print line : print "$net is part of hash, the value is $moduleRef->{modRef}{$moduleName}{ioRef}{$net}".

    Your best option is probably to dump your output (with Data::Dump or Data::Dumper) because it helps you visualize the data you actually have, and helps you tell the difference between undef, 0 and the empty string. Just add use Data::Dump qw( pp ); at the top of your program, and print pp $moduleRef->{modRef}{$moduleName}{ioRef} before your loop.
    Or if you don't want to install Data::Dump, use Data::Dumper; and print Dumper $moduleRef->{modRef}{$moduleName}{ioRef}

      Hi Eilly , Thanks for your inputs. I have puts small portion of the complete code to replicate scenerio. I have used dumper and checked the results before and after execution of the loop and observed that even elseif condition was not satisfied, that loop got executed. I have modified my code as below to print initial and final value of the hash before and after the loop.
      foreach my $net(@netLst){ //For debug foreach my $key_net (keys %{$moduleRef->{modRef}{$moduleName +}{ioRef}}) { print "IN: moduleName = $moduleName; net = $key_net; indx + = $moduleRef->{modRef}{$moduleName}{ioRef}{$key_net}{indx}\n"; } if($net =~ /\'/) {next;} elsif(defined ($moduleRef->{modRef}{$moduleName}{ioRef}{$net}) +) { print "$net is part of hash "; } //For debug foreach my $key_net (keys %{$moduleRef->{modRef}{$moduleName +}{ioRef}}) { print "OUT: moduleName = $moduleName; net = $key_net; ind +x = $moduleRef->{modRef}{$moduleName}{ioRef}{$key_net}{indx}\n"; } }
      It Printed output as below.
      IN: moduleName = msc_chan_reset; net = ch_rst_l; indx = 2 IN: moduleName = msc_chan_reset; net = data_in; indx = 3 IN: moduleName = msc_chan_reset; net = clk; indx = 0 IN: moduleName = msc_chan_reset; net = rst_l; indx = 1 IN: moduleName = msc_chan_reset; net = data_out; indx = 4 ts_500_gated_clk_buf is hash part of hash OUT: moduleName = msc_chan_reset; net = ch_rst_l; indx = 2 OUT: moduleName = msc_chan_reset; net = data_in; indx = 3 OUT: moduleName = msc_chan_reset; net = clk; indx = 0 OUT: moduleName = msc_chan_reset; net = ts_500_gated_clk_buf; indx = + OUT: moduleName = msc_chan_reset; net = rst_l; indx = 1 OUT: moduleName = msc_chan_reset; net = data_out; indx = 4 ####:
      So here even though ts_500_gated_clk_buf was not part of the hash, it executed that loop and here on it added that hash with net ts_500_gated_clk_buf even though it wasn't intended. Thanks, Sandeep

        Please use a dumper module to display the content of your hashes rather than try to print them, not only will it help tell if a value is actually defined or the empty string, it will also make it much easier for us to try and reproduce your defect.

        And if you're going to use the same deep-level element several times in a row, please use a temp variable for readability: my $ioRef = $moduleRef->{modRef}{$moduleName}{ioRef}; With that you'll be able to call keys %$ioref; and $ioref->{$net}. It also helps make sure you are actually always accessing the same thing.

        Also, your output doesn't match your code. Your code prints "$net is part of hash " but your output has "is hash part of hash", so either you are not giving us the output you got from that code, or you are working with the wrong file.

Re: Wrong Results in checking if hash value is defined or not
by Anonymous Monk on Jun 30, 2017 at 08:21 UTC

    Hi. Thats not likely; This is your program with the missing data filled in

    #!/usr/bin/perl -- use strict; use warnings; my @nets = qw/ a b c d /; # my $ioRef = $moduleRef->{modRef}{$moduleName}{ioRef}; my $ioRef = { qw/ q q c c d /, undef }; ## Data::Dump::dd( $ioRef ) for my $net ( @nets ){ print "checking $net\n"; if( defined $ioRef->{$net} ){ print "defined $net $ioRef->{$net} \n"; } } __END__ checking a checking b checking c defined c c checking d

    You're saying a/b are defined inside $ioRef ... but thats highly unlikely (impossible)

    What does that mean? You need to post runnable code

Re: Wrong Results in checking if hash value is defined or not
by locked_user sundialsvc4 (Abbot) on Jun 30, 2017 at 14:54 UTC

    From perldoc perlfunc, on the entry for “defined()”:

    When used on a hash element, it tells you whether the value is defined, not whether the key exists in the hash.   Use "exists" for the latter purpose.