Disable Perl warnings for missing qw outer parentheses - perl

Since upgrading Debian recently I've had Perl whining about not having extra parentheses around the qw operator.
As a Systems Administrator this is unacceptable. It is breaking mod_perl applications left, right, and centre.
How can I run Perl with this warning disabled? Is there a flag I can run with the Perl interpreter? Note that editing source is not an option.

This changed in Perl 5.14 - see perldelta.
Use of qw(...) as parentheses
Historically the parser fooled itself into thinking that qw(...)
literals were always enclosed in parentheses, and as a result you
could sometimes omit parentheses around them:
for $x qw(a b c) { ... }
The parser no longer lies to itself in this way. Wrap the list literal
in parentheses like this:
for $x (qw(a b c)) { ... }
This is being deprecated because the parentheses in for $i (1,2,3) {
... } are not part of expression syntax. They are part of the
statement syntax, with the for statement wanting literal parentheses.
The synthetic parentheses that a qw expression acquired were only
intended to be treated as part of expression syntax.
Looks like you can turn the warnings off with no warnings 'qw' but you'd be far better off fixing the code.

As a system administrator I find bad code unacceptable.
The best answer, of course, is to fix the offending perl scripts.
If your business won't let you fix the offending perl scripts, then don't upgrade Debian.
You have risks either way.

Related

The ?PATTERN? operator is not working for Matching Only Once in Perl

I am new to Perl and am practising some programs. I have encountered a syntax error. Please help me.
My Perl program
#!/usr/bin/perl
#list = qw/ food foosball subeo footnote terfoot canic footbridge /;
foreach ( #list ) {
$first = $1 if ?(foo.*)?;
$last = $1 if /(foo.*)/;
}
print "First: $first, Last: $last\n";
Output
syntax error at MatchingOnlyOnce.pl line 9, near "if ?"
Execution of MatchingOnlyOnce.pl aborted due to compilation errors.
Output of perl -v
This is perl 5, version 24, subversion 1 (v5.24.1) built for MSWin32-x64-multi-t
hread
Copyright 1987-2017, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
Use
$first=$1 if m?(foo.*)?;
?PATTERN? could be used as a shortcut for m?PATTERN?, but you can no longer omit the match operator's leading m when you use ? as the delimiter.
5.14 deprecated the ability to omit the leading m from m?PATTERN?flags.
5.22 removed the ability to omit the leading m from m?PATTERN?flags.
5.22 and 5.24's perlop lists both m?PATTERN?flags and ?PATTERN?flags, but only the former if legal in these versions.
5.26's documentation will be free of all mentions of ?PATTERN? (as opposed to m?PATTERN?).
If you are not using the default / pattern delimiters, you must specify the match operation as in $x =~ m{...}, $x =~ m!...! etc.
?...? is different than those other alternative delimiters as ?...? does something different than /.../. perldoc perlreref currently states:
?pattern? is like m/pattern/ but matches only once. No alternate delimiters can be used. Must be reset with reset().
That is misleading as Perl used to recognize the plain ?...?, but support for that was completely removed a few years ago:
[perl #120912] [PATCH] Remove support for ?PATTERN? without explicit 'm' operator
…
This has issued a deprecation warning since Perl v5.14 (commit
725a61d70), and precludes using ? as an operator after a unary operator
that defaults to $_, such as:
ref ? $_ : [$_]
Here is the motivation for the deprecation and eventual removal:
Deprecate ?PATTERN?, recommending the equivalent m?PATTERN? syntax, in
order to eventually allow the question mark to be used in new operators
that would currently be ambiguous.
If you are just beginning to learn Perl, you ought to enable strict and warnings. Declare your variables in the smallest applicable scope.
#!/usr/bin/env perl
use strict;
use warnings;
my #list = qw/food foosball subeo footnote terfoot canic footbridge/;
my ($first, $last);
foreach my $item (#list) {
$item =~ m?(foo.*)?
and $first = $1;
$item =~ /(foo.*)/
and $last = $1;
}
print "First: $first, Last: $last\n";
Output:
$ perl tt.pl
First: food, Last: footbridge
A lot of things about Perl are unusual for a programming language, and you have happened upon a corner of the language that is rarely used
Perl was designed by a the linguist Larry Wall, and there are many similarities between Perl and spoken languages. Perl allows abbreviations of some constructs, for instance, a pattern match like
/abc/
is equivalent to
$_ =~ m/abc/
That is to say, if it looks like a regex pattern it will be treated as one, regardless of whether the leading m is there or not. Also, many Perl operators work on $_ by default, which allows you to write a few lines of code without explicitly mentioning a variable
But m?...? is an old-fashioned construct that has really been edged out by lexical variables. If you declare a variable using my then there is no need for the one-shot match, or the corresponding reset operator. It is your declaration that defines the lifetime of the variable
If you are just starting with Perl, I recommend that you
Always start every program with use strict and use warnings 'all'. This isn't optional as it's the first line of defence against simple mistakes and errors
Always declare every variable using my as close as possible to its first use. Occasionally you may want to declare variables before a loop so that its value is kept across iterations, but generally variables should be temporary and useful only for a few lines of code
Forget about m?...?. I have never seen a program that uses it in twenty years of writing Perl professionally
I hope this helps

Should I use parenthesis in postfix `if` syntax?

Are there any benefits to use parenthesis in postfix if statement? like:
return 1 if ($self->found());
One of my workmate stick to use parenthesis and It's not common for me. I would appreciate if someone point out differences.
Following is output from perl -MO=Deparse
#!/usr/bin/perl
use strict;
my $found = 1;
print "FOUND\n" if $found;
print "FOUND\n" if ($found);
__END__
test.pl syntax OK
use strict;
my $found = 1;
print "FOUND\n" if $found;
print "FOUND\n" if $found;
Parens are never needed around the condition in the if statement modifier, so consistency and playing-it-safe aren't factors. (Same goes for the other statement modifiers.)
I don't see any advantage to using them. In fact, I find them a bit jarring.
I believe most experienced Perl programmers don't use them, to the point that it's a fair indicator of "newbieness".
It's mainly a matter of style. There's no requirement to use parens around the entire conditional expression and it has no effect on the way the code behaves, so decide for yourself what standard you want to use. Personally, I don't, and my impression is that most Perl programmers don't either, but that could just be selection bias.
I will note, though, that any time I start wanting to use parens within the conditional expression, that's a pretty good sign that it shouldn't be in a postfix clause, so then I put parens around the whole thing and change it to the if (...) {...} form.
If you want to use Perl Best Practices, you should only postfix if for control of flow (break, next, last). When you use postfix if you should probably have easy enough if-statements to not need parenthesis.
For If blocks I think the best practice is to use parenthesis.
I usually use the parentheses because more often than not I guess wrong on how many statements I need to be conditional. Then I have to rewrite the line to become a proper if (condition) { BLOCK }. Having the parentheses already there make this slightly easier.
There's also the mental/readability benefit of having all if statements look the same.

Ambiguous use of -CONSTANT resolved as -&CONSTANT()

I'm trying to declare magic numbers as constants in my Perl scripts, as described in perlsub. However, I get warnings:
$ cat foo.perl
use warnings ; use strict ;
sub CONSTANT() { 5 }
print 7-CONSTANT,"\n" ;
$ perl foo.perl
Ambiguous use of -CONSTANT resolved as -&CONSTANT() at foo.perl line 3.
2
$
The warning goes away if I insert a space between the minus and the CONSTANT. It makes the expressions more airy than I'd like, but it works.
I'm curious, though: What is the ambiguity it's warning me about? I don't know any other way it could be parsed.
(Perl 5.10.1 from Debian "squeeze").
First, some background. Let's look at the following for a second:
$_ = -foo;
-foo is a string literal[1].
$ perl -Mstrict -wE'say -foo;'
-foo
Except if a sub named foo has been declared.
$ perl -Mstrict -wE'sub foo { 123 } say -foo;'
Ambiguous use of -foo resolved as -&foo() at -e line 1.
-123
Now back to your question. The warning is wrong. A TERM (7) cannot be followed by another TERM, so - can't be the start of a string literal or a unary minus operator. It must be the subtraction operator, so there is no ambiguity.
This warning is still issued in 5.20.0[2]. I have filed a bug report.
Look ma! No quotes!
system(grep => ( -R, $pat, $qfn ));
Well, 5.20.0 isn't out yet, but we're in a code freeze running up to its release. This won't be fixed in 5.20.0.
mpapec's answer helpfully referenced perldiag (which I wasn't aware of) but quoted the wrong diagnostic. The one I'm actually getting is
Ambiguous use of -%s resolved as -&%s()
(S ambiguous) You wrote something like -foo, which might be the string "-foo", or a call to the function foo, negated. If you meant the string, just write "-foo". If you meant the function call, write -foo().
So apparently the point is that -CONSTANT is a valid bareword. I didn't know they could start with dashes.
I still don't really understand why that would give a warning here, given that (a) I'm using strict subs so obviously I'm not going to throw around barewords deliberately, and (b) even if I were, a bareword or string in this position would be a syntax error anyway.
Edit: As pointed out (more or less) by tobyink, it is not actually that -CONSTANT in itself is a bareword, but that strict subs still allows barewords after the unary minus operator. Apparently the lexer isn't context-aware enough to know that parsing -CONSTANT as an unary minus is not allowed in this context.
Still feels strange to me -- one would expect the effect of prototyping a sub with no arguments ought to be that I deliberately forfeit using that name as a bareword, no matter whether it happens to be as the operand to unary minus or in a different context.

Perl does not complain about missing semicolon

I just found on my Ubuntu that Perl is not complaining about the semicolon at the end. Check the following code:
#!/usr/bin/perl
use warnings;
use strict;
my #array = (1, 2, 3, 4);
foreach (#array)
{
print $_."\n"
}
print "no, this cant be true"
Please notice that semicolon ";" is missing from the print statement. Still the code runs fine.
OUTPUT:
1
2
3
4
no, this cant be true
If I put semicolon after print, it still works. So this is confusing to me.
Could you help me understand what am I missing here, OR is there some obvious Perl ideology that I overlooked?
From perldoc perlsyn:
Every simple statement must be terminated with a semicolon, unless it is the final statement in a block, in which case the semicolon is optional.
Your print statement is the last statement in a block.
Omitting the semi-colon isn't recommended though. It's too easy to forget to add it if you extend the block later.
I often think of semicolons in Perl as separators rather than terminators - that makes this behaviour a lot easier to get used to.
That said, it's not at all a bad idea to always use a semicolon as you don't have to remember to add it later if you put more statements at the end of the block, a bit like using an extra comma in a list so that you don't forget to add that later (Perl ignores the last comma if there's no list item after it).
From the Perl documentation:
Every simple statement must be terminated with a semicolon, unless it
is the final statement in a block, in which case the semicolon is
optional.

Why is parenthesis optional only after sub declaration?

(Assume use strict; use warnings; throughout this question.)
I am exploring the usage of sub.
sub bb { print #_; }
bb 'a';
This works as expected. The parenthesis is optional, like with many other functions, like print, open etc.
However, this causes a compilation error:
bb 'a';
sub bb { print #_; }
String found where operator expected at t13.pl line 4, near "bb 'a'"
(Do you need to predeclare bb?)
syntax error at t13.pl line 4, near "bb 'a'"
Execution of t13.pl aborted due to compilation errors.
But this does not:
bb('a');
sub bb { print #_; }
Similarly, a sub without args, such as:
special_print;
my special_print { print $some_stuff }
Will cause this error:
Bareword "special_print" not allowed while "strict subs" in use at t13.pl line 6.
Execution of t13.pl aborted due to compilation errors.
Ways to alleviate this particular error is:
Put & before the sub name, e.g. &special_print
Put empty parenthesis after sub name, e.g. special_print()
Predeclare special_print with sub special_print at the top of the script.
Call special_print after the sub declaration.
My question is, why this special treatment? If I can use a sub globally within the script, why can't I use it any way I want it? Is there a logic to sub being implemented this way?
ETA: I know how I can fix it. I want to know the logic behind this.
I think what you are missing is that Perl uses a strictly one-pass parser. It does not scan the file for subroutines, and then go back and compile the rest. Knowing this, the following describes how the one pass parse system works:
In Perl, the sub NAME syntax for declaring a subroutine is equivalent to the following:
sub name {...} === BEGIN {*name = sub {...}}
This means that the sub NAME syntax has a compile time effect. When Perl is parsing source code, it is working with a current set of declarations. By default, the set is the builtin functions. Since Perl already knows about these, it lets you omit the parenthesis.
As soon as the compiler hits a BEGIN block, it compiles the inside of the block using the current rule set, and then immediately executes the block. If anything in that block changes the rule set (such as adding a subroutine to the current namespace), those new rules will be in effect for the remainder of the parse.
Without a predeclared rule, an identifier will be interpreted as follows:
bareword === 'bareword' # a string
bareword LIST === syntax error, missing ','
bareword() === &bareword() # runtime execution of &bareword
&bareword === &bareword # same
&bareword() === &bareword() # same
When using strict and warnings as you have stated, barewords will not be converted into strings, so the first example is a syntax error.
When predeclared with any of the following:
sub bareword;
use subs 'bareword';
sub bareword {...}
BEGIN {*bareword = sub {...}}
Then the identifier will be interpreted as follows:
bareword === &bareword() # compile time binding to &bareword
bareword LIST === &bareword(LIST) # same
bareword() === &bareword() # same
&bareword === &bareword # same
&bareword() === &bareword() # same
So in order for the first example to not be a syntax error, one of the preceding subroutine declarations must be seen first.
As to the why behind all of this, Perl has a lot of legacy. One of the goals in developing Perl was complete backwards compatibility. A script that works in Perl 1 still works in Perl 5. Because of this, it is not possible to change the rules surrounding bareword parsing.
That said, you will be hard pressed to find a language that is more flexible in the ways it lets you call subroutines. This allows you to find the method that works best for you. In my own code, if I need to call a subroutine before it has been declared, I usually use name(...), but if that subroutine has a prototype, I will call it as &name(...) (and you will get a warning "subroutine called too early to check prototype" if you don't call it this way).
The best answer I can come up with is that's the way Perl is written. It's not a satisfying answer, but in the end, it's the truth. Perl 6 (if it ever comes out) won't have this limitation.
Perl has a lot of crud and cruft from five different versions of the language. Perl 4 and Perl 5 did some major changes which can cause problems with earlier programs written in a free flowing manner.
Because of the long history, and the various ways Perl has and can work, it can be difficult for Perl to understand what's going on. When you have this:
b $a, $c;
Perl has no way of knowing if b is a string and is simply a bareword (which was allowed in Perl 4) or if b is a function. If b is a function, it should be stored in the symbol table as the rest of the program is parsed. If b isn't a subroutine, you shouldn't put it in the symbol table.
When the Perl compiler sees this:
b($a, $c);
It doesn't know what the function b does, but it at least knows it's a function and can store it in the symbol table waiting for the definition to come later.
When you pre-declare your function, Perl can see this:
sub b; #Or use subs qw(b); will also work.
b $a, $c;
and know that b is a function. It might not know what the function does, but there's now a symbol table entry for b as a function.
One of the reasons for Perl 6 is to remove much of the baggage left from the older versions of Perl and to remove strange things like this.
By the way, never ever use Perl Prototypes to get around this limitation. Use use subs or predeclare a blank subroutine. Don't use prototypes.
Parentheses are optional only if the subroutine has been predeclared. This is documented in perlsub.
Perl needs to know at compile time whether the bareword is a subroutine name or a string literal. If you use parentheses, Perl will guess that it's a subroutine name. Otherwise you need to provide this information beforehand (e.g. using subs).
The reason is that Larry Wall is a linguist, not a computer scientist.
Computer scientist: The grammar of the language should be as simple & clear as possible.
Avoids complexity in the compiler
Eliminates sources of ambiguity
Larry Wall: People work differently from compilers. The language should serve the programmer, not the compiler. See also Larry Wall's outline of the three virtues of a programmer.