Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: How to suppress "only used once" regarding script file handles (that are in fact used in my module), but do it from a the module?

by Corion (Patriarch)
on Nov 07, 2019 at 16:52 UTC ( [id://11108448]=note: print w/replies, xml ) Need Help??


in reply to How to suppress "only used once" regarding script file handles (that are in fact used in my module), but do it from a the module?

The traditional approach is to just use the filehandle twice:

sub openOut { select *main::OUT = *main::OUT; # squelch "used once" warning ...

Alternatively, you can disable the warning, see warnings:

sub openOut { { no warnings 'once'; select *main::OUT; } ...

The best approach IMO would be to do away with the global filehandle names alltogether and pass in the filehandle from the main program. but I guess that's beyond the scope of your question :)

  • Comment on Re: How to suppress "only used once" regarding script file handles (that are in fact used in my module), but do it from a the module?
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: How to suppress "only used once" regarding script file handles (that are in fact used in my module), but do it from a the module?
by hepcat72 (Sexton) on Nov 07, 2019 at 21:50 UTC
    Hmmm...

    Perhaps I described the problem inadequately. The user of my module creates the file handle. My module exports openOut and it takes a file handle as its first argument in a variable:

    sub openOut { my $file_handle = $_[0]; my $output_file = $_[1]; ... }
    I use that file handle (in variable form - stored in a hash actually) multiple times throughout the module. My module doesn't know the bareword handle name, so I can't directly reference *main::OUT in my module code to "use it twice". Even if I get the name of the bareword file handle with some trick like $bareword_filehandle = select(), I wouldn't guess that I could satisfy the "use it more than once" requirement regarding main without typing the thing out in the code, and if I did that inside the module, I don't know if that would work for the warning about the file handle in main. How does sort do it WRT $a and $b? And how wouyld I replicate that when I don't know the name of the handle?

    So... if I put no warnings 'once' inside my openOut sub in my module, are you saying that that would suppress warnings about *OUT (or whatever hard-coded handle the user creates) in main?

    Here's a full example of a user's script who would be using my module (we'll call it Foo for now):

    #!perl use Foo qw(openOut); openOut(*BAR,"~/output.txt"); print("Hello world!\n");

    I do have a feature planned to possibly make the openOut method return an anonymous file handle. That would solve the problem, but it would create other problems, which I haven't worked out yet.

      Forgoing a lexical (you’re calling it “anonymous”) filehandle gives you some serious problems you may not have considered. Best practice is never GLOBAL handles (excepting built-ins…).

      I agree with all three replies you've received to this so far. I would also add (my anonymous brother's comment notwithstanding) that you can avoid this problem entirely simply by returning the opened filehandle rather than accepting it as an argument. eg. In your module:

      sub openOut { my $filename = shift; open my $fh, '>', $filename or die $!; select $fh; return $fh; };

      In this way, the user of your module can either call this sub in void context if they don't care about closing the handle later (this avoiding the "once" warning) or in scalar context if they do. eg:

      # void context, no handle to close openOut ("file1"); print "foo\n"; # scalar context, handle stored so can be closed, printed to explicitl +y, etc. my $handle = openOut ("file2"); print "bar\n"; closeOut ($handle);

      I think you're over-thinking this. If the warning is coming from their script and not from your module, it's their job to eliminate the warning. In their script they can do no warnings 'once';, or they can use the name twice.

      Now, you could do something like this in your module:

      sub import { warnings->unimport('once'); }

      … which will effectively do no warnings 'once' on their behalf, but unimporting warnings for your caller is only something you should be doing if you document it in big red letters in your documentation.

      "How does sort do it WRT $a and $b?"

      Perl special cases the $a and $b package variables, not requiring them to be declared with our, and not warning about them being used only once. They're magic. Not as magic as other built-in variables, but still a little magic.

      Here's a full example of a user's script who would be using my module (we'll call it Foo for now):

      Hi

      Thats a tad , optimistic? ;)

      use Path::Tiny qw/ path /; select my $bar = path("~/output.txt")->opena_utf8; print "Hello world!\n";

      At least thats this user's opinion

      Modern Perl , the future is now :)

      $ perl - use Path::Tiny qw/ path /; select path("~/output.txt")->opena_utf8; print "Hello world!\n"; __END__ $ cat %home%\output.txt Hello world! $ del %home%\output.txt $

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11108448]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (4)
As of 2024-04-25 20:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found