Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

filehandle question

by warpod (Novice)
on Oct 11, 2004 at 13:36 UTC ( #398146=perlquestion: print w/replies, xml ) Need Help??
warpod has asked for the wisdom of the Perl Monks concerning the following question:

What is wrong with this code?
==== test. pl ====== #!/usr/bin/perl use strict; use mmm; local* F; mmm::fopen(F, ">tst"); print F "hi"; mmm::fclose F; ==== ====== #!/usr/bin/perl use strict; package mmm; BEGIN {} sub fopen(*;$) { local *FH = $_[0]; return CORE::open(FH, $_[1]); } sub fclose(*) { local *FH = $_[0]; return CORE::close(FH); } END { } 1;
when executed it says:
print() on unopened filehandle F at line 7.
but if I move fopen and fclose into, then this code
local* F; fopen(F, ">tst"); print F "hi"; fclose F;
works just fine. What is wrong in package?

Replies are listed 'Best First'.
Re: filehandle question
by BrowserUk (Pope) on Oct 11, 2004 at 13:47 UTC

    You can't pass a glob by bareword. Try this:

    #!/usr/bin/perl use strict; use mmm; local* F; mmm::fopen( *F, ">tst"); print F "hi"; mmm::fclose *F;

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: filehandle question
by revdiablo (Prior) on Oct 11, 2004 at 17:00 UTC

    It may be beside the point, but -- assuming you have a new enough perl -- I would recommend avoiding bareword filehandles, and switching to autovivifying lexicals:

    use strict; use warnings; { package mmm; sub fopen { CORE::open $_[0], $_[1]; } sub fclose { CORE::close $_[0]; } } mmm::fopen(my $fh, ">test"); print $fh "Foo, bar.\n"; mmm::fclose($fh);
Re: filehandle question
by hv (Parson) on Oct 11, 2004 at 14:30 UTC

    If you define fopen in the same package as you use it it works fine. When passing the bareword to the mmm package, however, it gets interpreted as *mmm::F instead of *main::F, so the file has been opened but in the wrong glob.

    Given the prototype, this is arguably a bug - the bareword 'F' should be coerced to a glob in the caller's context. However there is no guarantee it is easily fixable - I suspect that it is currently passed as a simple string, and not turned into a glob reference until the actual assignment in mmm::fopen().


Re: filehandle question
by bobf (Monsignor) on Oct 11, 2004 at 16:53 UTC

    As soon as I read your error message I thought, "how do you know you opened F in the first place?" Then I read the rest of your question and the other responses and realized that the globbing issue was the primary problem. Nonetheless, you should always check the return value of open to make sure it succeeded. If open fails, you will get the same error (print() on unopened filehandle F) when you try to print to the filehandle later.

    open, perlopentut

Re: filehandle question
by coreolyn (Parson) on Oct 11, 2004 at 13:52 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://398146]
Approved by Happy-the-monk
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (3)
As of 2017-06-27 04:28 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (598 votes). Check out past polls.