Подтвердить что ты не робот

Мой $self = сдвиг в Perl; объяснение

Мне очень трудно понять пересечение OO Perl и my $self = shift; Документация по этим отдельным элементам велика, но ни один из них, который я нашел, не касался того, как они работают вместе.

Я использую Moose для создания модулей с атрибутами, и, конечно, полезно ссылаться на атрибут модуля в указанном модуле. Мне снова и снова говорили использовать my $self = shift; в рамках подпрограммы, чтобы назначать атрибуты модуля этой переменной. Это имеет смысл и работает, но когда я также передаю аргументы подпрограмме, этот процесс явно берет первый элемент массива @ARGV и назначает его также $self.

Может кто-нибудь предложить объяснение того, как я могу использовать shift, чтобы получить внутренний доступ к атрибутам модуля, а также передать аргументы в массиве @ARGV?

4b9b3361

Ответ 1

Прежде всего, подпрограмма не передается массивом @ARGV. Скорее все параметры, переданные подпрограмме, сглаживаются в один список, представленный @_ внутри подпрограммы. Массив @ARGV доступен на верхнем уровне вашего script, содержащего аргументы командной строки, переданные вам script.

Теперь, в Perl, когда вы вызываете метод объекта, объект неявно передается в качестве параметра для метода.

Если вы игнорируете наследование,

 $obj->doCoolStuff($a, $b);

эквивалентно

 doCoolStuff($obj, $a, $b);

Это означает, что содержимое @_ в методе doCoolStuff будет:   @_ = ($obj, $a, $b);

Теперь встроенная функция shift без каких-либо параметров сдвигает элемент из переменной массива по умолчанию @_. В этом случае это будет $obj.

Итак, когда вы делаете $self = shift, вы эффективно говорите $self = $obj.

Я также надеюсь, что это объясняет, как передать другие параметры методу с помощью обозначения ->. Продолжая приведенный выше пример, это будет выглядеть так:

sub doCoolStuff {
  # Remember @_ = ($obj, $a, $b)
  my $self = shift;
  my ($a, $b) = @_;

Кроме того, в то время как Moose является отличным объектным уровнем для Perl, он не отменяет требования, необходимые для инициализации $self самостоятельно в каждом методе. Всегда помните об этом. Хотя язык, подобный С++ и Java, инициализирует ссылку на объект this неявно, в Perl вам нужно сделать это явно для каждого метода, который вы пишете.

Ответ 2

В коде верхнего уровня shift() сокращен для shift(@ARGV). @ARGV содержит аргументы командной строки.

В подстроке shift() сокращен для shift(@_). @_ содержит вспомогательные аргументы.

Итак, my $self = shift; захватывает первый аргумент. При вызове метода в качестве первого параметра передается invocant (то, что осталось от ->). Другими словами,

$o->method(@a)

похож на

my $sub = $o->can('method');
$sub->($o, @a);

В этом примере my $self = shift; назначит $o $self.

Ответ 3

Если вы вызываете:

$myinstance->myMethod("my_parameter");  

- это то же самое, что и делать:

myMethod($myinstance, "my_parameter");  

но если вы выполните:

myMethod("my_parameter");  

будет передан только "my_parameter".

ТОГДА, если внутри myMethod вы всегда делаете:

 $self = shift @_;  

$self будет ссылкой на объект при вызове myMethod id из контекста объекта
но будет "my_parameter" при вызове из другого метода внутри процедурным способом.
Помните об этом;