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

I have no idea why this doesn't work...
$tmp_dir and $dir are both strings
if ($tmp_dir ne $dir) { print OUTPUTFILE "\n" . $tmp_dir . "\n"; $dir = $tmp_dir; }
This gives a "isn't numeric in numeric ne (!=)" error, even though in "man perlop" is says: "Binary 'ne' returns true if the left argument is stringwise not equal to the right argument." What am I doing wrong? I've tried quoting them, making ne into !=, and then quoting that also. Nothing is working, and they _all_ give the same error. This isn't my box, but I do know that it's running Perl v5.6.0. Thanks for any help you can give me! :)

Justin

Replies are listed 'Best First'.
Re: Really dumb question...
by jorg (Friar) on May 20, 2001 at 01:38 UTC
    Try to put use strict; at the top of your script and always run it with the -w commandline switch. This often gives you a better idea of what *could be going wrong.
    I ran you script like this and it didn't produce the error
    use strict; use vars qw($tmp_dir $dir); open OUTPUTFILE, ">test.txt"; $tmp_dir = "test"; $dir = "tester"; if ($tmp_dir ne $dir) { print "dumping to file\n"; print OUTPUTFILE "\n$tmp_dir\n"; $dir = $tmp_dir; }
    Maybe there is something wrong in your assignment of $tmp_dir and $dir...

    Jorg

    "Do or do not, there is no try" -- Yoda
Re: Really dumb question... ('ne' not working)
by damian1301 (Curate) on May 20, 2001 at 08:23 UTC
    It might be wise to have given the error message to us, but anyway...

    I have had this problem before as well. I would try to test if the expressions turned out false with the ne equality operator. The great thing about Perl is that Larry has given you options and versatility so, instead of using the if($tmp_dir ne $dir){...} stuff, you could simply just negate that with the unless loop. In the process of switching loops, you will have to switch equality operators as well. To fix this, we will just change ne to eq. What we have now is
    unless($tmp_dir eq $dir){ print OUTPUTFILE "\n", $tmp_dir ,"\n"; $dir = $tmp_dir; }


    This code has the exact same behavior as the loop you were using and has never caused me problems under ActivePerl (on windows 98).

    Hope I helped :-)

    Tiptoeing up to a Perl hacker.
    Dave AKA damian

Re: Really dumb question... ('ne' not working)
by tachyon (Chancellor) on May 20, 2001 at 07:13 UTC
    This works for me under WIN32 and linux, perl 5.6.0. C:\>type test.pl #!/usr/bin/perl use strict; use warnings; use diagnostics; open (OUTPUTFILE, ">./file.txt") || die "Oops $!"; my $tmp_dir = "foo"; my $dir = "bar"; if ($tmp_dir ne $dir) { print OUTPUTFILE "\n" . $tmp_dir . "\n"; $dir = $tmp_dir; } close OUTPUTFILE; C:\>perl test.pl C:\>type file.txt foo C:\> The only way I could reproduce the error you describe is to do this (ie put in a != in place of ne): C:\>type test.pl #!/usr/bin/perl use strict; use warnings; use diagnostics; open (OUTPUTFILE, ">./file.txt") || die "Oops $!"; my $tmp_dir = "foo"; my $dir = "bar"; if ($tmp_dir != $dir) { print OUTPUTFILE "\n" . $tmp_dir . "\n"; $dir = $tmp_dir; } close OUTPUTFILE; C:\>perl test.pl Argument "foo" isn't numeric in numeric ne (!=) at test.pl line 11 (#1 +) (W numeric) The indicated string was fed as an argument to an oper +ator that expected a numeric value instead. If you're fortunate the message will identify which operator was so unfortunate. C:\> If you genuinely have ne I suspect your perl may be broken!! If you have ne in the above code perl is quite happy even if both the vars *are actually numeric* vis: C:\>type test.pl #!/usr/bin/perl use strict; use warnings; use diagnostics; open (OUTPUTFILE, ">./file.txt") || die "Oops $!"; my $tmp_dir = 2; my $dir = 1; if ($tmp_dir ne $dir) { print OUTPUTFILE "\n" . $tmp_dir . "\n"; $dir = $tmp_dir; } close OUTPUTFILE; C:\>perl test.pl C:\> Note that this runs quite happily. Perl stringifies the numeric values in $tmp_dir and $dir for ne to use. Because the behavior you describe is not repeatable, and should not logically occur as perl should be automatically stringifying the values in $tmp_dir and $dir if required I suggest you may have a corrupt perl binary. It does happen. I agree that use strict; use warnings; and use diagnostics; may help. Unfortunately if you have a big script that was not written under use strict you will have a lot of tweaking to do yo get it to run (mostly declaring your variables with my), but other stuff too. Good luck Suggest testing on another box to test dud perl hypothesis tachyon
Re: Really dumb question... ('ne' not working)
by Anonymous Monk on May 22, 2001 at 02:43 UTC
    Well, I tried this code on my work server, which I know has a perfectly working Perl install. It still is giving me the same error:
    Argument "Daft Punk\\Homework\\01 Daftendirekt\r\n" isn't numeric in numeric ne (!=) at mp3listgen.pl line 142, <INPUTFILE> line 1.

    Here's my code...I'd greatly appreciate any help I could get.
    #!/usr/bin/perl -w $fileOUT = "mp3list.txt"; open(OUTPUTFILE,">$fileOUT"); $filename = "A02.txt"; &parseDown; $filename = "A03.txt"; &parseDown; $filename = "A04.txt"; &parseDown; $filename = "A05.txt"; &parseDown; $filename = "A06.txt"; &parseDown; $filename = "A07.txt"; &parseDown; $filename = "A08.txt"; &parseDown; $filename = "A09.txt"; &parseDown; $filename = "A10.txt"; &parseDown; close(OUTPUTFILE); sub parseDown { open(INPUTFILE,"$filename"); $dir = ""; while(($line = <INPUTFILE>) != null) { $line =~ m%(.*)\\(.*)%; $tmp_dir = $1; $line = $2; if ($tmp_dir ne $dir) { print OUTPUTFILE "\n" . $tmp_dir . "\n"; $dir = $tmp_dir; } chomp($line); print OUTPUTFILE "\t" . $line . "\n"; } close(INPUTFILE); }
    The files have entries that look like this:
    Paul van Dyk\Seven Ways\01 Home Paul van Dyk\Seven Ways\02 Seven Ways Paul van Dyk\Seven Ways\03 Heaven Paul van Dyk\Seven Ways\04 I Like It Paul van Dyk\Seven Ways\05 Come (and Get It) Paul van Dyk\Seven Ways\06 Forbidden Fruit Paul van Dyk\Seven Ways\07 Beautiful Place Paul van Dyk\Seven Ways\08 People Paul van Dyk\Seven Ways\09 The Greatness of Britain Paul van Dyk\Seven Ways\10 I Can't Feel It Paul van Dyk\Seven Ways\11 Words

    Thanks again,
    Justin

      Two things: (1) the error message says you're trying to treat a string as a number. ne tests for unequal *strings*, while != tests for unequal *numbers*.

      Perl (which, as you're finding out, is Not Java =) provides the defined() function to test for null values. So write that as

      while (defined ( my $line = <INPUT>) ) {

      Actually, go ahead and try

      while ($line = <INPUT>) {

      as even blank lines contain newlines, and so evaluate to true.

      (2) it makes more sense to write parseDown1 as a subroutine that accepts $filename as an argument than as something that expects a global to be set. Here it's not causing problems but it's not a good design to use in any script you'll keep (or cadge code from!).

      sub parseDown { my $filename = shift @_; # or $_[0] or just plain shift # rest of sub }

      (3) use strict and warnings (-w in pre-5.6.0 Perl). Doing this will require that you declare your variables with my2 and pay attention to scope. This is a Good thing.

      (4) don't blindly use $1 and $2 without checking to see whether your regex matched. If it doesn't weird things can happen. Instead, do this:

      if (my ($tmp_dir, $file) = $line =~ m%(.*)\\(.*)% ) { # do the rest of the stuff } else { warn "$line has incorrect format!\n"; }

      (5) I can't count.

      HTH

      1 That spelling, and the != null test, suggest you're coming from a Java background. Apologies if that's incorrect.
      2(update) or our (5.6.0) or use vars. Included for completeness. Ignore this for now, I just don't want to say anything false.

        wow. i actually come from a c++ background, but ive been doing _waaaaayyy_ too much java lately. good call. :) i cant believe i forgot that i use "defined" and not testing to see if it's != null....but i did, and we all make mistakes. ;-) anyways, thanks for the mini-lesson on standards and proper coding techniques -- i seriously lack these in perl, and i really need to start learning them.

        anyways, thanks a lot for your help, it was exactly what i needed!

        justin