Первый подход не будет работать так, как написано.
sub bar {
my($self) = @_;
foo();
}
Здесь вы явно вызываете foo
как функцию без аргументов через этот оператор foo();
.Это создаст пустой локальный массив @_
.Первый оператор в foo
извлекает $self
в качестве первого элемента из этого локального @_
, поэтому $self
не определен с этим механизмом.
Вам необходимо передать $self
в качестве аргумента foo
.Есть (как минимум) пять способов сделать это:
- Обозначение стрелки: Вызвать
foo
через $self->foo();
- Косвенное обозначение: Вызвать
foo
через foo $self;
- Обычный вызов подпрограммы: Invoke
foo
via foo($self);
- Предполагаемые аргументы: Invoke
foo
via foo $self;
Этот параметр можно использовать, только если foo
был предварительно объявлен с прототипом функции. - Не создавайте этот локальный массив
@_
.Позвольте foo
добавить в массив bar
@_
.Вызвать foo
через &foo;
Обратите внимание, что в этом вызове нет скобок.
Относительно опции № 5: она существует.Не используйте это.Это доставит вам неприятности.
Разница между # 2 и # 4 становится очевидной, когда foo принимает дополнительные аргументы.Косвенная нотация становится (например) foo $self 42;
, в то время как подразумеваемая форма становится foo $self, 42;
Косвенная нотация (вариант 2) теперь настоятельно не рекомендуется.Варианты 3 и 4 также не рекомендуется использовать с методами.
Это оставляет вариант № 1.Несмотря на то, что обозначение стрелки является просто синтаксическим сахаром, оно очень много значит для читателя.Используйте это.