Consider the following snippets and what warnings (if any) they generate.

First, assume the following template for each of the subsequent three open calls.

use strict; use warnings; use autodie; my $filename = 'ourfile.txt'; # open call goes here.

Now consider each of the following 'open' statements to exist on its own within the preceding template:

open my $fh, '<', $filename; # No warning; open my $fh, $filename or die $! # No warning; open my $fh, $filename; # Issues a warning.

The warning issued is:

Parentheses missing around "my" list at mytest.pl line 11 (#1)

use diagnostics; adds the following output:

(W parenthesis) You said something like my $foo, $bar = @_; when you meant my ($foo, $bar) = @_; Remember that "my", "our", "local" and "state" bind tighter than c +omma.

I appreciate that the warning is trying to protect me from a situation where declaring multiple 'my' variables without parens around them would result in behavior that might not be expected. I guess what I'm pondering is the inconsistent behavior in what conditions trigger the warning. One could simply turn it off. Or one could just say open my($fh), $filename, or use the three arg open (as we should). But then what would we have to obsess over? ;)

It's fairly obvious that with the "open my $fh, '>', $filename call, that '>' string literal is not a variable, so the coder's intent is clearly to only declare a single lexical. So that situation could be ignored when talking about consistent behavior. Let's just focus on the two situations where the open is called in its two-arg form: open my $fh, $filename or die $! and open my $fh, $filename. I guess what I would be looking for (in keeping with the principle of least astonishment) would be for the syntax that generates the warning to be ignored in the context of an open statement. This already happens when an "or die $!" is appended.

I can't explain why the warning behaves as I would want it to when 'or die' is appended, and not when it's left out. Maybe someone could shed some light on that. Regardless, it seems that Perl should either complain in both situations, or in neither.

There are other examples of this behavior, such as readdir; another case where an embeded 'my' within the argument list for the built-in ought to fail to trigger a warning on missing parens. Or if it should trigger the warning, should do so always (ie, even when 'or die' is appended).


Dave

Replies are listed 'Best First'.
Re: Inconsistency in warning for parens with my.
by BrowserUk (Patriarch) on Jul 03, 2011 at 07:40 UTC
    I can't explain why the warning behaves as I would want it to when 'or die' is appended, and not when it's left out.

    First, this is nothing to do with open.

    It simply comes down to the fact that when the parser sees the or, it knows that the second variable is a part of a compound statement. So it cannot be part of a list argument to the my, so it must be a separate term.

    c:\test>perl -wE"my $a, $b or die;" Name "main::b" used only once: possible typo at -e line 1. Died at -e line 1.

    Without the or to disambiguate, the second variable could be intended to be a part of a list argument to my, hence the warning is issued to persuade you to clarify

    c:\test>perl -wE"my $a, $b;" Parentheses missing around "my" list at -e line 1. Useless use of a variable in void context at -e line 1. Name "main::b" used only once: possible typo at -e line 1.

    Another way to disambiguate the syntax is to interpolate the second variable in quotes:

    c:\test>perl -wE"my $a, qq[$b];" Useless use of string in void context at -e line 1. Name "main::b" used only once: possible typo at -e line 1. Use of uninitialized value $b in string at -e line 1.

    Which just looks weird in isolation, but makes more sense when used in conjunction with open:

    c:\test>perl -wE"open my $a, qq[> $b];" Name "main::b" used only once: possible typo at -e line 1. Use of uninitialized value $b in concatenation (.) or string at -e lin +e 1.

    Other disambiguations are possible:

    c:\test>perl -wE"open my $a, +$b;" Name "main::b" used only once: possible typo at -e line 1. Use of uninitialized value $b in open at -e line 1. c:\test>perl -wE"open my $a, ''.$b;" Name "main::b" used only once: possible typo at -e line 1. Use of uninitialized value $b in concatenation (.) or string at -e lin +e 1.

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Inconsistency in warning for parens with my.
by Anonymous Monk on Jul 03, 2011 at 07:22 UTC
      I can not access the URL you posted. I tried on couple different browsers/OSs. I logged in to https://rt.cpan.org and searched for ticket 7250, but it was not found there.

      Does anyone now how I can view this ticket? Is there an alternate URL?

Re: Inconsistency in warning for parens with my.
by shmem (Chancellor) on Jul 06, 2011 at 14:08 UTC

    A bit off topic:

    shmem [qwurx] ~ > perl -wle 'my $f = "X"; open my $fh, $f' shmem [qwurx] ~ >

    Nothing. Hmm...

    shmem [qwurx] ~ > perl -wle 'my $f = "X"; open my $fh, $f;' Parentheses missing around "my" list at -e line 1. shmem [qwurx] ~ >

    Heh...

    :-)