The following chart shows how Perl resolves identifiers in order of descending priority.
It also applies to identifiers chained by ::
(which I’ll call “qualified identifiers”) unless otherwise stated.
-
Syntactically-defined meaning, when syntactically expected.
sub foo { } # «foo» («sub» is covered later) sub main::foo { } # «main::foo» («sub» is covered later) method Class # «Class» («method» is covered later) method Some::Class # «Some::Class» («method» is covered later) $foo $main::foo //i =head <<FOO Class:: Some::Class:: LABEL:
-
String literal, when followed by a
=>
or when the entirety of a hash index expression.This doesn’t apply to qualified identifiers.
my %h = ( a => 1 ); $h{a}
-
Variable name, when the entirety of the dereference expression.
${foo} ${main::foo}
Note that using the name of a keyword, named operator or declared sub will result in an
ambiguous use
warning. -
Keyword.
while (1) { } sub { } use __END__
-
Sub call, when the name of a previously imported sub.
use Time::HiRes qw( time ); time main::time
-
Invocation of a named list operator, named unary operator or named nullary operator.
print $x, $y, $z; $c = chr $i; $t = time; $t = CORE::time;
-
Label, when used as the operand for
next
,last
,redo
orgoto
.A qualified identifier treated as a label results in a compilation error since labels can’t be qualified identifiers.
next LABEL;
-
Sub call or inlined constant, when the name of a previously declared sub or constant.
sub foo { } foo # Calls sub «foo» main::foo # Calls sub «foo» sub bar; bar # Calls sub «bar» use constant FOO => 123; FOO # Replaced with the value of the constant.
-
Indirect method call, when followed by a possibly-qualified identifier, a possibly-qualified identifier suffixed with
::
, a scalar (incl array element or hash element) or a block.method Class # Calls method «method» («Class» is covered earlier) method Some::Class # Calls method «method» («Some::Class» is covered earlier) method Class:: # Calls method «method» («Class» is covered earlier) method Some::Class:: # Calls method «method» («Some::Class» is covered earlier) method $o # Calls method «method» method { $o } # Calls method «method» Base::method Class # Calls method «Base::method» («Class» is covered earlier)
You can use the
no indirect
pragma to warn when code is parsed this way. -
Glob, when used as the operand for an operator expecting a file handle.
open(FH, '>', $qfn) or die $!; # Equivalent to open(*FH, ...) or ...; print FH "Hello, World!\n"; # Equivalent to print *FH ...; print main::FH "Hello, World!\n"; # Equivalent to print *main::FH ...;
-
String literal, in the following situations:
-
When used as the invocant of a direct method call.
Class->method(@args) # Uses the string «Class» as the invocant. Some::Class->method(@args) # Uses the string «Some::Class» as the invocant.
-
When used as the operand for unary minus.
-foo -foo::bar
-
When used as an argument for the a sub parameter with a prototype of
*
.sub myprint(*@); myprint(FH, "Hello, World\n"); myprint(main::FH, "Hello, World\n");
-
-
String literal. This is disallowed by
use strict qw( subs );
.
Hopefully, I didn’t miss any.
Thanks to @mosvy, @Grinnz and @stevesliva! Each has uncovered a few cases I had missed.
CURRENTLY MISSING:
-
funcname
insort funcname
. -
BEGIN
and similar. They sometimes act as keyword, and sometimes as a declared sub. -
Importing a sub named
print
doesn’t follow the above steps.$ perl -M5.010 -e' use subs qw( time ); eval { time; }; say $@ =~ /Undefined sub/ ? "ok" : "bad"; ' ok $ perl -M5.010 -e' use subs qw( system ); eval { system; }; say $@ =~ /Undefined sub/ ? "ok" : "bad"; ' ok $ perl -M5.010 -e' use subs qw( print ); eval { print; }; say $@ =~ /Undefined sub/ ? "ok" : "bad"; ' bad
I don’t know what makes that one special, and I don’t know if there are others or not. I was guessing it’s because
print
doesn’t have a prototype, butsystem
has no prototype either.