Cody
Cody

Reputation: 639

What is the difference between sub Foo::bar {} and sub bar {} when they both belong to package Foo?

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?

Upvotes: 8

Views: 239

Answers (2)

ikegami
ikegami

Reputation: 385986

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 package main; they are also exempt from strict '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

Upvotes: 6

Leeft
Leeft

Reputation: 3837

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.

Upvotes: 2

Related Questions