Assume we have code like this
package Foo;
sub bar {
say 'hi';
}
and this
package Foo;
sub Foo::bar {
say 'hi';
}
I thought they are equivalent, so we can do this
Foo->bar();
whether we define the method with fully qualified name or not. However, in some circumstances they are indeed different. For instance, in the example given by perldoc -f require
, the method INC
must be fully qualified with the package name:
# In Foo.pm
package Foo;
sub new { ... }
sub Foo::INC {
my ($self, $filename) = @_;
...
}
# In the main program
push @INC, Foo->new(...);
If we don't fully qualify the method name, then a compile-time error occurs. So, what is the difference between full qualified name and no package name prepended?
The mechanism that causes @main::INC
to be globally accessible as @INC
also causes sub INC { }
to mean sub main::INC { }
.
Quote perlvar,
Perl identifiers that begin with digits, control characters, or punctuation characters are exempt from the effects of the
package
declaration and are always forced to be in packagemain
; they are also exempt fromstrict 'vars'
errors. A few other names are also exempt in these ways:ENV STDIN INC STDOUT ARGV STDERR ARGVOUT SIG
If we don't fully qualify the method name, then a compile-time error occurs.
hum... It won't do what you want, but it won't cause a compile-time error either.
$ perl -ce'
package Foo;
sub new { ... }
sub INC {
my ($self, $filename) = @_;
...
}
push @INC, Foo->new("...");
'
-e syntax OK
perldoc -f require
states why this is so:
If the hook is an object, it must provide an INC method that will be called as above, the first parameter being the object itself. (Note that you must fully qualify the sub’s name, as unqualified "INC" is always forced into package "main".)
It would thus be as if you wrote sub main::INC {}
if you leave the package qualifier out. I can't tell you why this is happening, but my guess is this is one of the special cases in the interpreter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With