My Favorite Warnings: syntax
Warnings category syntax
contains a number of sub-categories representing possibly-problematic syntax. These include ambiguous
syntax, problematic bareword
usage, invalid printf
conversions, and more. But there are also syntax
diagnostics that do not fall under any of the sub-categories. These tend to be a miscellaneous group, and a normal-sized blog post can do no more than to give a sample.
What brought this to my attention was a noisy test in Template-Toolkit. under Perl 5.35.2 and up. The noisy code was untainting a variable using code like
$foo = each %{ { $foo => undef } } if ${^TAINT};
This makes use of the fact that hash keys are (so far) never tainted. The new warning was each on anonymous hash will always start from the beginning
.
The adopted fix was to put this in the scope of a no warnings 'syntax';
, which I initially thought was overkill, knowing that syntax
was a group category. But further investigation showed that this diagnostic was, in fact, not a member of any sub-category of syntax
. I got curious about what other warning categories were in syntax
but not in a sub-category.
Some of my findings are in fact old friends: %s found where operator expected
was there, as were (Missing operator before %s?)
and (Missing semicolon on previous line?)
.
Others struck me as pointing out interesting or out-of-the way features of Perl that might need a diagnostic as an alternative to a hard-to-diagnose bug. The completely-random selection below is from the Perl 5.34.0 perldiag
. Comments by me are in italics.
- Array passed to stat will be coerced to a scalar%s
- (W syntax) You called stat() on an array, but the array will be
coerced to a scalar - the number of elements in the array. - elseif should be elsif
- (S syntax) There is no keyword "elseif" in Perl because Larry thinks
it's ugly. Your code will be interpreted as an attempt to call a
method named "elseif" for the class returned by the following block.
This is unlikely to be what you want. - "my %s" used in sort comparison
- (W syntax) The package variables $a and $b are used for sort
comparisons. You used $a or $b in as an operand to the "<=>" or
"cmp" operator inside a sort comparison block, and the variable had
earlier been declared as a lexical variable. Either qualify the sort
variable with the package name, or rename the lexical variable.
And this, boys and girls,
is why variables$a
and$b
should
be avoided, even as lexicals. - Old package separator used in string
- (W syntax) You used the old package separator, "'", in a variable
named inside a double-quoted string; e.g., "In $name's house". This
is equivalent to "In $name::s house". If you meant the former, put a
backslash before the apostrophe ("In $name\'s house").
The apostrophe as a package separator (i.e.
Foo'Bar
rather thanFoo::Bar
) is
left over from Perl 4. In the given example,
"In ${name}'s house"
also works. - !=~ should be !~
- (W syntax) The non-matching operator is !~, not !=~. !=~ will be
interpreted as the != (numeric not equal) and ~ (1's complement)
operators: probably not what you intended.
This seems only to be emitted if the
right-hand side is a match (i.e./foo/
or
m/foo/
). It appears not to be emitted if the
right-hand side isqr/foo/
or'foo'
.
Previous entries in this series:
Leave a comment