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

Help,
I've writen a small piece of code that compares a string to a hash with if exists. If I set the value in the script manual ie $test="10.20.47.13" the test at if exists works, but if I read in the value from a file with open, the test fails? I print the value before the if statment and it looks ok? Why is the string different when read from a file? I did try chomp but it did not help. I also tried this with "eq" in an if statment and again the test failed?

#!/usr/bin/perl -w my $dir="/home/lcollins"; open MISS, "$dir/miss" or die "can't open $!";# file has 1 line "10.20 +.46.13". %clocks=("10", 0,"10.20.20.10", 0,"10.20.46.13", 0,"10.20.46.37",0); my $miss=<MISS>; #chomp $miss; #my $miss="10"; print "$miss" if (exists $clocks{$miss}){ print "Yup it's there\n"; }

20050401 Janitored by Corion: Added formatting

Replies are listed 'Best First'.
Re: read value from file won't pass if exists??
by TedYoung (Deacon) on Jan 04, 2005 at 14:28 UTC

    Hi,

    First, a suggestion for future posts: you may want to surround your code in code tags. It makes reading it a bit easier.

    You definately will want the chomp in there. $miss will need to be one of the keys exactly. So, if you have any other whitespace on that line in the file, it could be throwing you off too.

    Also, the example you gave said you used 10.20.47.13 as the test string, which is not in your hash (you have 10.20.46.13). With that correction and the chomp, the script works fine for me. Check the file you are reading from.

    Ted Young

    ($$<<$$=>$$<=>$$<=$$>>$$) always returns 1. :-)
      Thanks, Sorry that ip was a typo. It works for you?? I flicked the chomp back on and still no go. Son of a gun!! I rm the file and vi'd another and it worked. (Embarassed) Thanks for the sanity check.
Re: read value from file won't pass if exists??
by Eimi Metamorphoumai (Deacon) on Jan 04, 2005 at 14:34 UTC
    The code you pasted doesn't compile (it's missing a semicolon after the print line). That's not that big a deal, but it's always important to test the exact code you're going to be posting. In this case, it definitely should work with the chomp in place. Have you tried checking exactly what the line contains? That is, replace
    print "$miss";
    with
    print "'$miss'\n";
    and make sure there are no spaces, trailing characters, or anything else getting in the way. The following works for me.
    #!/usr/bin/perl -w %clocks=("10", 0,"10.20.20.10", 0,"10.20.46.13", 0,"10.20.46.37",0); my $miss=<DATA>; chomp $miss; #my $miss="10"; print "'\Q$miss\E'\n"; if (exists $clocks{$miss}){ print "Yup it's there\n"; } __DATA__ 10.20.46.13
      Sorry first posting. Thanks for the help.
Re: read value from file won't pass if exists??
by Fletch (Bishop) on Jan 04, 2005 at 14:28 UTC

    Something doesn't sound correct. Run under the debugger (perl -d foo) and check that $miss really contains what you think it does (maybe there's a line ending problem and you've got an extraneous \cM a DOS-y file that chomp isn't removing, for example).

      That was it. I recreated the file with vi and it worked. the problem is the file is created by another perl scipt that pings addresses. if it fails it writes to my miss file. I'll need to look at the output to this file. Thanks again.
Re: read value from file won't pass if exists??
by Mutant (Priest) on Jan 04, 2005 at 14:33 UTC
    There's probably some weird (unprintable) character in the file. Assuming you're using a *NIX system, try viewing it in 'less' or something similar. You could also try recreating the file using vi or something you can be fairly sure isn't going to put weird stuff in there.
      It was the file. But i was not aware of "less" i'll add it to the tool kit. thanks,
Re: read value from file won't pass if exists??
by jbrugger (Parson) on Jan 04, 2005 at 14:38 UTC
    I tried it like this (i think you have a typo somewere), i noticed your file isn't colsed, and your hash is not readable:
    However, this should work.
    !/usr/bin/perl -w open MISS, "miss" or die "can't open $!"; my $miss=<MISS>; close MISS; my %clocks=( "10" => 0, "10.20.20.10" => 0, "10.20.47.13" => 0, "10.20.46.37" => 0, ); chomp $miss; # $miss="10.20.47.13"; print "$miss\n"; if (exists($clocks{$miss})){ print "Yup it's there\n"; }
      I did not know I needed to close like that. Much to learn. thanks!
        In general, you don't need to call close yourself in a small script. Perl will close all open file handles when the script finishes. Additionally, if you open the same filehandle with a different file, Perl will close the first one for you first. If you're writing a large program, you can sometimes run into a limit on the total number of files you can have open at once, so it's a good habbit to close anything you have open when you're done with it, but it generally won't do any harm if you don't.