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

This node falls below the community's threshold of quality. You may see it by logging in.
  • Comment on module which tells more warning about FILHANDLE

Replies are listed 'Best First'.
Re: module which tells more warning about FILHANDLE
by liverpole (Monsignor) on Dec 28, 2006 at 02:13 UTC
    Just let the filehandle get closed when you're done with it.

    The easiest way is to use a module like IO::File, and either undefine the filehandle when you're finished writing to it, or have it close automatically when it goes out of scope.

    Here's one way (going out of scope):

    use strict; use warnings; use IO::File; # Create a new filehandle, and write to 'file.txt' my $fname = "file.txt"; { my $fh = new IO::File($fname, ">"); print $fh "Here's a single line of text\n"; # Close the file once the user types [RETURN] print "Type [RETURN] to close file ...\n"; <STDIN>; } # When this block ends, the enclose "scope" ends, and $fh is delet +ed print "Go check whether '$fname' was created (from a separate process) + ...\n"; while (1) { sleep 3; print "Still here... (type ^C when finished)\n"; }

    And here's another (explicit deletion using undef) ...

    use strict; use warnings; use IO::File; # Create a new filehandle, and write to 'file.txt' my $fname = "file.txt"; my $fh = new IO::File($fname, ">"); print $fh "Here's a single line of text\n"; # Close the file once the user types [RETURN] print "Type [RETURN] to close file ...\n"; <STDIN>; undef $fh; # Undefine the filehandle and it will close automati +cally print "Go check whether '$fname' was created (from a separate process) + ...\n"; while (1) { sleep 3; print "Still here... (type ^C when finished)\n"; }

    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
      It would seem that given the new (to me) my in open you don't even need IO::File anymore...
      use strict; my $in; SCOPE: { open my $in, "/etc/passwd" or die $!; print "", scalar <$in>, "\n"; } print "(nothing?): ", scalar <$in>, "\n";

      -Paul

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: module which tells more warning about FILHANDLE
by wfsp (Abbot) on Dec 28, 2006 at 08:26 UTC
    Just to add to the points already made. I like to restrict the scope of scalars to the smallest possible scope. I try even harder when that scalar is a lexical file handle where unexpected side effects, in my mind, can be even less desirable.

    A happy consequence of this approach means I can be even more lazy. :-)

    I often want to load one or more arrays from data from files and later write out to one or more files. I also use the name of the file in the error message so avoiding typing the name of the file twice means putting it in a variable.

    Thinking up a name for the file and the file handle 2, 3, 4 or more times? Far too much effort. Screwing the scope of both to the floorboards saves the effort.

    Explicitly closing the file handle is for my benefit, Perl would close it anyway as it goes out of scope (although I must admit I don't check for success). I like to a see matching close with every open.

    #!/usr/bin/perl use strict; use warnings; my @rawdata; { my $file = 'rawdata.txt'; open my $fh, '<', $file or die "can't open $file to read: $!"; @rawdata = <$fh>; close $fh; } my @exceptions; { my $file = 'exceptions.txt'; open my $fh, '<', $file or die "can't open $file to read: $!"; @exceptions = <$fh>; close $fh; } # crunch the data my @exceptions_found; my @exceptions_counted; { my $file = 'exceptions_found.txt'; open my $fh, '>', $file or die "can't open $file to write: $!"; print $fh "$_\n" for @exceptions_found; close $fh; } { my $file = 'exceptions_counted.txt'; open my $fh, '>', $file or die "can't open $file to write: $!"; print $fh "$_\n" for @exceptions_counted; close $fh; }
Re: module which tells more warning about FILHANDLE
by Old_Gray_Bear (Bishop) on Dec 28, 2006 at 17:53 UTC
    Not so much a Module as a Methods solution --

    When I write open(my $fh,  .....) or die ...., the very next line of code I write is close($fh) die "Close error on file xxxx -- $!"; then I go back and fill-in the stuff between the open() and close().

    This (usually) makes my close() in the same scope as my open(), so I don't go littering open file-handles; or worse, reusing a file-handle unintentionally. Now, I know that Perl will close files when they go out of scope, I just prefer the tidiness aspect of doing it myself. And, there have been times when the name of my temporary file was significant to the process; knowing which TempFile had the problem made restart much cleaner.

    ----
    I Go Back to Sleep, Now.

    OGB