Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

filehandle question

by warpod (Novice)
on Oct 11, 2004 at 13:36 UTC ( [id://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; ==== mmm.pm ====== #!/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 test.pl line 7.
but if I move fopen and fclose into test.pl, 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 (Patriarch) 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 (Prior) 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().

    Hugo

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

    HTH
A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (4)
As of 2024-04-19 20:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found