There are a couple of ways to do this. Explicitly pass a scalar ref to $foo
, or take advantage of Perl's built-in pass by reference semantics.
Explicit reference:
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);
}
Pass by reference:
my $foo = "old value";
doRepl( \&repl, $foo );
print $foo; # prints "new value";
sub repl {
$_[0] = "new value";
}
sub doRepl {
my $replFunc = shift;
$replFunc->(@_);
}
Even fancier pass by reference:
my $foo = "old value";
doRepl( \&repl, $foo );
print $foo; # prints "new value";
sub repl {
$_[0] = "new value";
}
sub doRepl {
my $replFunc = shift;
&$replFunc;
}
The first one use normal perl hard references to do the job.
The first pass by ref method uses the fact that Perl passes arguments to all functions as references. The elements of @_
are actually aliases to the values in the argument list when the subroutine is called. By altering $_[0]
in foo()
, you actually alter the first argument to foo()
.
The second pass by ref method use the fact that a sub called with an &
sigil and no parens gets the @_
array of its caller. Otherwise it is identical.
Update: I just noticed you desire to avoid $_[0]
. You can do this in repl if you want:
sub repl {
for my $line( $_[0] ) {
$line = 'new value';
}
}