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 strict
were not in force, I would understand it. The barewordnorequire
would become the string"norequire"
, the unary minus would turn that string into"-bareword"
, and the resulting string would go into theuse
import 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 => bar
becomes"-foo", bar
because=>
turnsfoo
into"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
strict
checks 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 parent
to communicate options. Compare also similar idioms on command line interfaces, where options usually begin with a dash.