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

Consider the code:

BEGIN { open(MESSAGES,'>msg.txt') or die "$!"; }
Assuming that this is the only occurance of MESSAGES at the time of compilation, we get a warning that MESSAGES is used only once (i.e. the file is opened, but nothing is written to it). My question is: Is it possible to get rid of this warning by a means like "declaring" the filehandle, similar to how it can be done with variables by using our or use vars, i.e. somthing similar in spirit to
use vars qw(MESSAGES); # wrong !!!!!!
? Of course there are various workarounds, for example Given these alternatives, my question is of more theoretical nature, but still one I'm interested in...

-- 
Ronald Fischer <ynnor@mm.st>

Replies are listed 'Best First'.
Re: Is it possible to "use vars" or "our" a file handle?
by almut (Canon) on Nov 02, 2009 at 16:08 UTC

    As the other Monks, I'd recommend using a lexical my variable, but to answer your question, the respective use vars statement would be:

    use vars qw(*MESSAGES);

      That's it, thanks a lot! BTW I already tried

      our *MESSAGES;
      which was rejected as syntax error, so I did not think about trying this approach with use vars. I shouldn't have given up so quickly...

      -- 
      Ronald Fischer <ynnor@mm.st>
Re: Is it possible to "use vars" or "our" a file handle?
by SuicideJunkie (Vicar) on Nov 02, 2009 at 15:56 UTC

    Try:

    my $fileHandle; #Closes for you when it goes out of scope! open $fileHandle, '>', $fileName or die "Can't open $fileName: $!\n"; writeFancyLogging($fileHandle, "Loggin' some stuff to a file"); sub writeFancyLogging { my $file = shift; my $msg = shift; print $file $msg . "\n"; }

    3-arg open is nicer and safer, using the variable twice solves the warning, and by my'ing it, you can pass it around and have it go out of scope.
      my $fileHandle; #Closes for you when it goes out of scope! open $fileHandle, '>', $fileName or die "Can't open $fileName: $!\n";
      Good suggestion (though to parallel my original one, I would have to use our $fileHandle instead of my). Actually, although it does not directly answer my original question (where I was looking for a solution using a global file handle, i.e. one written without a sigil), I think it complements nicely my "list of alternative solutions" which I had compiled in my posting.

      -- 
      Ronald Fischer <ynnor@mm.st>
      3-arg open is nicer and safer
      In general yes. In this case it doesn't make a difference, since the filename is passed literally.

      -- 
      Ronald Fischer <ynnor@mm.st>
Re: Is it possible to "use vars" or "our" a file handle?
by kennethk (Abbot) on Nov 02, 2009 at 15:57 UTC
    It seems like you've overlooked the most obvious solution:

    open(my $messages,'>', 'msg.txt') or die "$!";

    or, if you really mean to use the global property associated with bareword filehandles,

    open(our $messages,'>', 'msg.txt') or die "$!";

    Is there a reason you are not using lexicalindirect file handles? ( and using 2-argument instead of 3-argument open? )

      Is there a reason you are not using lexical file handles?

      Yes - the file will be opened on startup of the program, but the actual writing - if something is written at all - is performed at various other places (for instance by code pulled in from a file and evaluated with do. Actually, this is part of a debugging aid for our app, so there is no fancy solution needed; in contrary, it should be as simple as possible :-D.

      -- 
      Ronald Fischer <ynnor@mm.st>
        the actual writing - if something is written at all - is performed at various other places

        I'd encapsulate the logging in subroutine, rather than a variable.

        Yes - the file will be opened on startup of the program, but the actual writing - if something is written at all - is performed at various other places

        That doesn't answer the question since those "various other places" can call a function that has access to the lexical variable without having access to the lexical variable themselves.

        Less coupling == good.

        Sorry, I meant indirect, not lexical, and have updated the original post appropriately. If the only issue you wish to resolve is removing the warning, it's probably best to use

        BEGIN { no warnings qw(once); open(MESSAGES,'>msg.txt') or die "$!"; }

        since the warning removal will be scoped to the begin block and will only affect the known warning (see perllexwarn for the list of warning categories). Use of our will also suppress the warning and maintain global scope. Global scope can also be accomplished with package variables (open($main::messages,'>', 'msg.txt') or die "$!";), but this will still display the once warning, as well as will have precedence issues w/o the parentheses.

Re: Is it possible to "use vars" or "our" a file handle?
by JavaFan (Canon) on Nov 02, 2009 at 16:35 UTC
    If you still want to use bareword filehandles, there are several options. First of all, whenever Perl gives a warning when the code is correct, you have the option to disable the warning. IMO, that's preferred over any code changes you make just to make 'use warnings' happy. Disabling the warning is clear sign to whomever later has to deal with the code that you've judged the warning, and (s)he isn't left with WTF code. Second, you can just mention the variable twice ;-). For instance, by duplicating the line. Or printing the empty string to the handle.
      ... For instance, by duplicating the line. Or printing the empty string to the handle.

      Or just

      *MESSAGES;

      (which doesn't seem to emit a "Useless use of ... in void context" warning, or similar...)

Re: Is it possible to "use vars" or "our" a file handle?
by ambrus (Abbot) on Nov 03, 2009 at 13:48 UTC

    For a name you use once, you can use a symbol starting with an underscore, which suppresses the used once warning. This works in your case as well. Eg. open _MESSAGES, ">", "msg.txt" or die;