Есть несколько способов сделать это. Явно передайте скалярную ссылку на $foo
или воспользуйтесь встроенным проходом Perl по ссылочной семантике.
Явная ссылка:
my $foo = "old value";
doRepl( \&repl, \$foo );
print $foo; # prints "new value";
sub repl {
my $line = shift;
$$line = "new value";
}
sub doRepl {
my ($replFunc, $foo) = @_;
$replFunc->($foo);
}
Передать по ссылке:
my $foo = "old value";
doRepl( \&repl, $foo );
print $foo; # prints "new value";
sub repl {
$_[0] = "new value";
}
sub doRepl {
my $replFunc = shift;
$replFunc->(@_);
}
Еще любопытнее передать по ссылке:
my $foo = "old value";
doRepl( \&repl, $foo );
print $foo; # prints "new value";
sub repl {
$_[0] = "new value";
}
sub doRepl {
my $replFunc = shift;
&$replFunc;
}
Первый использует обычные жесткие ссылки на Perl для выполнения работы.
При первом проходе по методу ref используется тот факт, что Perl передает аргументы всем функциям в качестве ссылок. Элементы @_
фактически являются псевдонимами значений в списке аргументов при вызове подпрограммы. Изменив $_[0]
в foo()
, вы фактически измените первый аргумент на foo()
.
Во втором проходе по методу ref используется тот факт, что подпрограмма, вызванная с символом &
без паренов, получает массив @_
своего вызывающего. В остальном он идентичен.
Обновление: Я только что заметил, что вы хотите избежать $_[0]
. Вы можете сделать это в repl, если хотите:
sub repl {
for my $line( $_[0] ) {
$line = 'new value';
}
}