Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

perl

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?

like image 823
Cody Avatar asked Jul 22 '14 09:07

Cody


2 Answers

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
like image 125
ikegami Avatar answered Nov 15 '22 17:11

ikegami


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.

like image 29
Leeft Avatar answered Nov 15 '22 17:11

Leeft