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

This question should have read: I've been tearing my hair out all afternoon (In preparation to becoming a monk?) and can't find the problem. Is there a difference how PERL handles a variable going into a file vs. one going to <STDOUT>? I thought they were both just filehandles except that <STDOUT> is the default.

What's been happening is that the value of $lineout prints to <STDOUT> as "elephant = gray" but prints to the file as "elephant = grey". (It's test data :-) As you can see, there is no code between setting the variable and displaying/writing it.
open (FILE2, ">$file"); foreach $setting (@settings) { foreach $item (@lines) { chomp($setting); ($setMode, $setSect, $setPair) = split(/ *\| */, $setting); ($setName, $setVal) = split(/ *= */, $setPair); print "$setMode||$setSect||$setPair\n"; chomp($item); if ($item =~ m/ *= */) { ($temp1, $temp2) = split(/ *= */, $item); if ($setName eq $temp1) { $temp2 = $setVal; } #problem area $lineout = "$temp1 = $temp2\n"; print FILE2 "$lineout"; print "$lineout"; #end problem area } else { print "$item\n"; print FILE2 "$item\n"; } } close (FILE2);
I know the file is being written too, because it is being changed

Replies are listed 'Best First'.
Re: Hopefully a simple mistake
by chromatic (Archbishop) on Apr 14, 2000 at 00:30 UTC
    That's truly bizarre. Three recommendations. First, check the open and close statements, just to be sure: open (FILE2, ">$file") || die "can't open $file: $!"; Second, use select on your FILE2 filehandle to make that the default output. You can rewrite the problem area as:
    select(FILE2); $lineout = "$temp1 = $temp2\n"; print $lineout; print STDERR $lineout;
    I removed the double-quotes because they're probably not necessary in this case. You might also use ">>$file" in the open statement for debugging purposes. It appends to the file.

    The last recommendation is to print to STDERR the $temp1 and $temp2 variables after you split them. That's low on my list of things to check, though. Best of luck... that's all I can think of.

      I wasn't using -w (I feel silly)

      Being an initiate I made a rooky mistake. :-)
      The error was closing the file one level too early in the curly braces.
      I was writing to a closed file. I still don't know how the file was being changed, but there are other logic errors. I'll find them now.

      Thank you all for your suggestions and help.

      Your humble servant,
      -Chuck
RE: Hopefully a simple mistake
by Doc Technical (Initiate) on Apr 14, 2000 at 00:53 UTC
    Some questions:

    1) What is your playform/OS, and Perl version?
    2) Setting any switches in the first line of the script?
    3) Setting any Perl global vars before the first foreach?
    4) Can we see some of what's in @settings and @lines?

    Also (I am shooting in the dark here, don't laugh) what
    happens when you re-assign $lineout to "$temp1 = $temp2\n"
    between your print statements?
Re: Hopefully a simple mistake
by stephen (Priest) on Apr 14, 2000 at 01:18 UTC
    The debugger might be helpful here. Just do a
    perl -d chuckular_prog.pl # Or whatever the filename is
    and then stop it in the problem area to see what's going on. perlman:perldebug

    Other than that, I'd recommend localizing your variables with "my" and putting "use strict" into the beginning, plus running with -w (which you're of course already doing, right?)

    Also, remove your data file and re-run the program. Although the data has changed, it's best to double-check. Definitely add the "or die".

    stephen

Re: Hopefully a simple mistake
by btrott (Parson) on Apr 14, 2000 at 00:37 UTC
    Do you have the British Spelling Filter attached to your filehandle? :)

    Why don't you send along your test data (the contents of @settings and @lines, I guess), so we can try to see what's going on.

    Also, are you sure that the two print statements that are giving you the incorrect output are occurring right after one another and not at different times through the loop?

    (By the way: the name of the filehandle is STDOUT, not <STDOUT>.)

Re: Hopefully a simple mistake
by turnstep (Parson) on Apr 14, 2000 at 01:21 UTC
    Add some simple debugging:
    $lineout = "$temp1 = $temp2\n"; print FILE2 "A. $lineout"; print "B. $lineout"; ... print "C. $item\n"; print FILE2 "D. $item\n";
RE: Hopefully a simple mistake
by Anonymous Monk on Apr 15, 2000 at 02:23 UTC
    And this is a really minor thing, but I'd move the chomp ($setting); out of the second loop... Or at least *I* don't see a reason to chomp the bejeezus out the same variable over and over :) markguy
      I noticed that myself, and changed it. It doesn't hurt $setting, but I'm sure it uses more processor cycles!
      Your humble servant,
      -Chuck