有几种方法可以做到这一点。显式传递一个标量ref到$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将参数作为引用传递给所有函数的事实。当调用子例程时,@_
的元素实际上是参数列表中值的别名。通过改变foo()
中的$_[0]
,您实际上将第一个参数更改为foo()
。
第二次通过ref方法使用的事实是,调用&
sigil并且没有parens调用的子实例获取调用者的@_
数组。否则它是相同的。
更新:我只是注意到你想避免$_[0]
。如果你愿意,你可以在repl中这样做:
sub repl {
for my $line($_[0]) {
$line = 'new value';
}
}
不幸的是,我看着文档的“实施”部分... ack!我猜这个模块有点像香肠......如果你不知道它们是如何制作的,那么它会更令人愉快...... :) – JoelFan 2010-03-18 16:22:31
@JoelFan:yup。这是一个“不要在家里尝试这个”模块:) – 2010-03-18 16:37:12
开始“这个模块不使用源过滤器”,并从那里下坡... :) – JoelFan 2010-03-18 20:01:30