Если вы говорите __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;
Теперь поместите следующее в Bar.pm
и скажите 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
похожим на это:
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
. Мы все еще получаем результат, но это не результат, который мы ожидаем. Что произойдет, если мы удалим __PACKAGE__
из Bar.pm
? Ну, мы получаем и ошибку: Undefined subroutine &Bar::main called at Bar.pm line 8.
Это потому, что нет main
функция в модуле, и мы не вызываем его вместе с классом, поэтому он больше не будет искать его в пакете Foo
.