当设置Perl代码作为脚本或模块运行时,__PACKAGE__的原因是什么?

FMc*_*FMc 4 perl module

在这个早期的Stackoverflow问题中,特别是brian d foy的"脚本如何成为一个模块"我已经阅读了如何设置代码,以便它可以作为脚本或模块运行,使用这种技术:

package SomeModule;

__PACKAGE__->run(@ARGV) unless caller();

sub run {
    # Do stuff here if you are running the file as
    # a script rather than a module.
}
Run Code Online (Sandbox Code Playgroud)

__PACKAGE__这个设置的目的是什么?为什么不这样做呢?

run(@ARGV) unless caller();
Run Code Online (Sandbox Code Playgroud)

Cha*_*ens 14

如果你说,__PACKAGE__->run(@ARGV)那么run可以在你继承的类中定义,或者允许类从这个类继承.如果你只是说run(@ARGV)你错过了班级信息.这只在您进行OO样式编程时才有意义.

将以下内容放在一个名为的文件中Foo.pm,然后说出来perl Foo.pm 1 2 3

package Foo;

use strict;
use warnings;

__PACKAGE__->main(@ARGV) unless caller;

sub main {
    my $class = shift;
    my $obj   = $class->new(@ARGV);
    print $obj->to_string, "\n";
}

sub new {
    my $class = shift;
    return bless [@_], $class;
}

sub to_string {
    my $self = shift;
    return "args: " . join ", ", map { "[$_]" } @$self;
}

1;
Run Code Online (Sandbox Code Playgroud)

现在把以下内容放进去Bar.pmperl Bar.pm a b c.

package Bar;

use strict;
use warnings;

use base 'Foo';

__PACKAGE__->main(@ARGV) unless caller;

sub to_string {
    my $self = shift;
    return "args: " . join ", ", map { "<$_>" } @$self;
}

1;
Run Code Online (Sandbox Code Playgroud)

现在让我们看看如果你不在__PACKAGE__这种环境中使用会发生什么.使代码的第一部分Foo.pm看起来像这样:

main(@ARGV) unless caller;

sub main {
    my $obj = Foo->new(@ARGV);
    print $obj->to_string, "\n";
}
Run Code Online (Sandbox Code Playgroud)

现在跑perl Foo.pm 1 2 3.一切都应该看起来正确.现在尝试跑步perl Bar.pm a b c.我们仍然得到输出,但它不是我们期望的输出.如果我们__PACKAGE__从中移除会发生什么Bar.pm?好吧,我们得到并且错误:Undefined subroutine &Bar::main called at Bar.pm line 8. 这是因为main 模块中没有函数,我们没有用类调用它,因此它Foo不再在包中查找它.