Why is the following use line legal Perl syntax? (Adapted from the POD for parent; tested on Perl 5.26.2 x64 on Cygwin.)
package MyHash;
use strict;
use Tie::Hash;
use parent -norequire, "Tie::StdHash";
# ^^^^^^^^^^ A bareword with nothing to protect it!
Under -MO=Deparse, the use line becomes
use parent ('-norequire', 'Tie::StdHash');
but I can't tell from the use docs where the quoting on -norequire comes from.
If
use strictwere not in force, I would understand it. The barewordnorequirewould become the string"norequire", the unary minus would turn that string into"-bareword", and the resulting string would go into theuseimport list. For example:package MyHash; use Tie::Hash; use parent -norequire, "Tie::StdHash";Similarly, if there were a fat comma, I would understand it.
-foo => barbecomes"-foo", barbecause=>turnsfoointo"foo", and then the unary minus works its magic again. For example:package MyHash; use strict; use Tie::Hash; use parent -norequire => "Tie::StdHash";
Both of those examples produce the same deparse for the use line. However, both have quoting that the original example does not. What am I missing that makes the original example (with strict, without =>) legal? Thanks!
You already cited
perldoc perlop, but it is relevant here.This behavior of the unary minus operator is applied to the bareword before the
strictchecks are applied. Therefore, unary minus is a kind of quoting operator that also works in strict mode.Similarly, barewords as the invocant in method invocation do not need to be quoted as long as they are not a function call:
However, the unary minus behaviour seems to be due to constant folding, not due to a special case in the parser. For example, this code
will only complain about the bareword "bar" being disallowed, suggesting that the bareword check happens very late during parsing and compilation. In the unary minus case, the bareword will already have been constant-folded into a proper string value at that point, and no bareword remains visible.
While this is arguably buggy, it is also impossible to change without breaking backwards compatibility – and this behaviour is used by many modules such as
use parentto communicate options. Compare also similar idioms on command line interfaces, where options usually begin with a dash.