Beefy Boxes and Bandwidth Generously Provided by pair Networks vroom
There's more than one way to do things
 
PerlMonks  

Open file issues

by hotshot (Prior)
on Aug 18, 2004 at 09:39 UTC ( #383906=perlquestion: print w/ replies, xml ) Need Help??
hotshot has asked for the wisdom of the Perl Monks concerning the following question:

Hi all!

I have the following function for openning a file:
sub openFile { my ($file, $accessMode) = @_; my $err; if (! defined($accessMode)) { # by default, open the file for re +ading $accessMode = $MODE_READ; } if (exists($ACCESS_MODES{$accessMode})) { if (! open(FILE, "$ACCESS_MODES{$accessMode}$file")) { $err = $!; if (defined($returnOnError)) { return $FALSE; } &throwGenError("Can't open $file: $err"); # throw except +ion } } else { &throwGenError("In openFile: Wrong access mode $accessMode"); } return FILE; }
The problem is when I call it in a function, and before closing the file handler I call another function the also opens a file (another file), for example:
sub func1 { my (@fileContent,@temp, @comment); my $contentFh = &openFile($file1); while (my $line = <$contentFh >) { ... push(@fileContent,&func2($line)); ... } } close($contentFh); return \@fileContent; } sub func2 { my ($user) = @_; my @groupsFile; my $groupsFh = &openFile($file2); @groupsFile = <$groupsFh>; close($groupsFh); ... return @groupsFile; }
When calling func1 I get the following errors to screen:
readline() on closed filehandle FILE at /var/www/cgi-bin/lib/myfile.pl + line 25.
It's the leine of the while(). It doesn't happen when I don't call func2 from within func1, I guess the close() call in func2 somehow effects func1.
Anywhy can explain the problem and suggest a solution?

Thanks a lot

Comment on Open file issues
Select or Download Code
Re: Open file issues
by eserte (Deacon) on Aug 18, 2004 at 09:55 UTC
    All the files in your script share one filehandle, FILE. You have two options to solve this problem: use Symbol::gensym() to create unique filehandles, or use lexicals instead of bareword filehandles. The latter option requires you to have a new perl (5.6 or 5.8, I can't remember). The code would look like this:
    my $fh; open($fh, "...") or die ...; return $fh;

      You could also use IO::File which should work in even older perls.

Re: Open file issues
by davorg (Chancellor) on Aug 18, 2004 at 09:55 UTC

    If you were running with "use warnings" then Perl would have told you what the problem is. Filehandles aren't first-class variables in Perl so you can't just return a filehandle from a function and assign it to a variable like that. You're actually using the same filehandle (FILE) for both files - which is why you can't use it after you've closed the first filehandle.

    You can get round this by using lexical filehandles.

    sub openFile { my ($file, $accessMode) = @_; my $err; $accessMode = $MODE_READ unless defined $accessMode; if (exists($ACCESS_MODES{$accessMode})) { if (open(my $fh, "$ACCESS_MODES{$accessMode}$file")) { return $fh; } else { $err = $!; if (defined($returnOnError)) { return; } &throwGenError("Can't open $file: $err"); # throw exception } } else { &throwGenError("In openFile: Wrong access mode &accessMode"); } return; }

    Some of your logic is a bit scary, so I haven't changed too much. You might need to check it carefully.

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      Some of your logic is a bit scary, so I haven't changed too much. You might need to check it carefully. Can you explain what you ment?

      And thanks for your pre answer

        Oh, I just mean that there are a few globals which make me a bit uncomfortable and your error handling is (to my eyes) a bit bizarre. The more "Perlish" approach would be to return a false value for smaller errors and to just die on fatal stuff.

        --
        <http://www.dave.org.uk>

        "The first rule of Perl club is you do not talk about Perl club."
        -- Chip Salzenberg

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://383906]
Approved by eserte
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (9)
As of 2014-04-18 22:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (472 votes), past polls