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

Dear Monks,

I've shown some of this code before, please forgive me.

I have passed the output file name to this bit of code. You pick up on this code where the input and output file name are picked up. I have not shown you the headers, modules activators and ODBC connection ... all these are fine. The problem I have is the print to the output file. The relevant bit of code is highlighted. I am using MS SQL Server.
my $inputfile = $ARGV[0]; my $outputfile = $ARGV[1]; open (OUTPUT_FILE, ">$outputfile"); my $Request_id; my $Variable_number; my $Variable; my $Choice; my @VARIABLE; my @CHOICE; my $Command; my $Return_results; my $Component_number_old = 1; my $Component_number = 1; my $SPROC; my $unique; my $elements_in_array; my $flat_file = $inputfile; open (FLAT_FILE, "<$flat_file"); while (<FLAT_FILE>){ chomp; $Component_number_old = $Component_number; if ($_ =~ /^$/) { exit; } elsif ($_ =~ /SPROC\sName\:\s([a-z|A-Z|0-9|_]{1,100})/){ $SPROC = $1; } elsif ($_ =~ /^\*(.{36})\;(\d{1,5})\;(\d{1,5})\;([a-z|A-Z|0-9|_]{1,5 +0})\;(.{1,100})/){ push (@VARIABLE, $Variable); push (@CHOICE, $Choice); print "Hi_B\n"; $unique = $1; $Component_number = $2; $elements_in_array = $3; $Variable = $4; $Choice = $5; } if ($_ =~ /^\sEND/){ print "Hi_E\n"; push (@VARIABLE, $Variable); push (@CHOICE, $Choice); $Command = join(' ', 'EXEC', $SPROC, join(', ', @CHOICE[1 .. $elements_in_array])) . ';'; my $Request_id = $CHOICE[26]; Got_Command($Command, $Request_id, $outputfile); undef @CHOICE; my @CHOICE; } } close FLAT_FILE; sub Got_Command { my($Command,$Request_id, $outputfile) = @_; my $sthB_A = $dbh->do($Command) or die "Couldn't do query: ".$dbh-> +errstr; my $Return_results = "Select * from Result_storage_keep where Unique +_identifier LIKE '".$Request_id."' AND Aggregated_area = Instance_nam +e AND Disease_cat = Cause_catagory\;"; my $sth_C = $dbh->prepare($Return_results) or die "Couldn't prepare +query: ".$dbh->errstr; $sth_C->execute() or die "Couldn't execute query: ".$sth_C->errstr; while (my @row = $sth_C->fetchrow_array) { print OUTPUT_FILE join("\t", @row); print OUTPUT_FILE "\n"; ## This is the bit that causes me problems ## I get the error messages # print() on closed filehandle OUTPUT_FILE at 20_October_2004_K.pl lin +e 227, <FLAT _FILE> line 29. #print() on closed filehandle OUTPUT_FILE at 20_October_2004_K.pl line + 228, <FLAT _FILE> line 29. } }
Any suggestions as to the problem is most welcome.

Replies are listed 'Best First'.
Re: print() on closed filehandle
by davis (Vicar) on Dec 14, 2004 at 15:44 UTC

    You don't check the status of open()ing OUTPUT_FILE. Change your open to read something like:

    open (OUTPUT_FILE, ">", $outputfile) or die "Unable to open $outputfile: $!\n";
    I've also used the 3-argument form of open().


    davis
    It wasn't easy to juggle a pregnant wife and a troubled child, but somehow I managed to fit in eight hours of TV a day.
      Does the output file have to exist before it the system call on this code is made? Can it not create the file on the fly?

        It can fail for numerous reasons. The most common are probably:

        • Insufficient permissions
        • Path doesn't exist
        • Disk error (someone ejected it)
        • Invalid characters in file name

        The correct answer is: "Try it, or read perldoc -f open". The short answer is that using ">" in your open will (attempt to) open the file, clobbering (ie removing) its contents, or creating the file anew if necessary.

        Update: added documentation pointer.

        davis
        It wasn't easy to juggle a pregnant wife and a troubled child, but somehow I managed to fit in eight hours of TV a day.
Re: print() on closed filehandle
by Eimi Metamorphoumai (Deacon) on Dec 14, 2004 at 15:50 UTC
    Always check the return value of calls to open. The idomatic way to do that would be
    open (OUTPUT_FILE, ">$outputfile") or die "Could not open $outputfile: + $!";
    (same for FLAT_FILE, and anything else you open.) That form is great for debugging ($! will contain the actual error message if there's a problem), but you might want to replace the die with something more robust if you need to recover from the error. Once you find out why your file isn't opening, you can proceed to fix it.
Re: print() on closed filehandle
by theorbtwo (Prior) on Dec 14, 2004 at 16:37 UTC

    If I were you, I'd use IO::File, and pass the filehandles around like any other object. No, that isn't an answer to your speicifc problem. Try whittling down your code to as small an example as you can that still exibits the problem you're having. After this, either you'll figure out the problem yourself, or you'll be able to give us a smaller snippet in which to find the problem.


    Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).

Re: print() on closed filehandle
by ikegami (Patriarch) on Dec 14, 2004 at 16:49 UTC
    As an aside, you probably want to use last rather than exit. The former exits the loop, while the latter exits the program. You never reach close FLAT_FILE; as it is now. The close isn't necessary, but this misdirection might cause you problems in the future.