且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-11-30 21:06:46

如果您说__PACKAGE__->run(@ARGV),则可以在您继承的类中定义run,或者允许一个类从该类继承.如果仅说run(@ARGV),则说明缺少班级信息.这仅在您正在执行OO样式编程时才重要.

If you say __PACKAGE__->run(@ARGV) then run can be defined in a class you inherit from or allows a class to inherit from this one. If you just say run(@ARGV) you are missing the class information. This only matters if you are doing OO style programming.

将以下内容放入名为Foo.pm的文件中,然后说perl Foo.pm 1 2 3

Put the following in a file named Foo.pm, and then say 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;

现在将以下内容放入Bar.pm,并说perl Bar.pm a b c.

Now put the following in Bar.pm, and say perl 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;

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

Now lets see what happens if you don't use __PACKAGE__ in this environment. Make the first section of code in Foo.pm look like this:

main(@ARGV) unless caller;

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

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

Now run perl Foo.pm 1 2 3. Everything should still look right. Now try running perl Bar.pm a b c. We still get output, but it is not the output we expect. What happens if we remove __PACKAGE__ from Bar.pm? Well, we get and error: Undefined subroutine &Bar::main called at Bar.pm line 8. This is because there is no main function in the module and we are not calling it with the class, so it won't look for it in the Foo package anymore.