我做通按引用这样的:

use strict;
use warnings;

sub repl {
    local *line = \$_[0]; our $line;
    $line = "new value";
}

sub doRepl {
    my ($replFunc) = @_;
    my $foo = "old value";
    $replFunc->($foo);
    print $foo; # prints "new value";
}

doRepl(\&repl);

是否有这样做的更清洁的方式?

由于我使用的是函数引用(相信我,有一个很好的理由,使用函数引用)的原型不工作。

我也不想在$_[0]到处使用repl,因为它是丑陋的。

有帮助吗?

解决方案

让你看着数据::别名?它可以让你有一个清晰的语法词法创建范围的别名。

可以使用它来创建通引用语义如下:

use strict;
use warnings;

use Data::Alias;

sub foo {
    alias my ($arg) = @_;
    $arg++;
}

my $count = 0;

foo($count);

print "$count\n";

的输出是1,指示呼叫到foo改性它的参数。

其他提示

sub repl {
    my $line = \$_[0];     # or: my $line = \shift
    $$line = "new value";
}

有几个方法可以做到这一点。明确地通过一个标量裁判$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硬引用来完成这项工作。

在第一遍通过参考方法使用是Perl参数传递给所有用作参考的事实。 @_的元素实际上是别名在参数列表中的值时,则子程序调用。通过在$_[0]改变foo(),实际上改变到foo()第一个参数。

在第二遍通过参考方法利用一个事实,即所谓带有印记&和没有括号子得到其呼叫者的@_阵列。否则,它是相同的。

更新:我只注意到你的愿望,以避免$_[0]。您可以在REPL做到这一点,如果你想:

sub repl {
    for my $line( $_[0] ) {
        $line = 'new value';
    }
}

我不认为这有什么错误使用local建立在这种情况下别名。

动态范围当然是一个强大的功能,但只要你是知道的副作用(新值在其范围内调用函数可见,如果同名的词汇是在范围上,它不能是局部的,...),那么它是一种有用的除了已经溢出的Perl工具箱。

在约local Perl的文档警告的主要原因是保持无意中使用它,而不是my人,以缓解从Perl4样式的转变。但也有一定的时间时local是有用的,并且这是一个。

使用for创建您的别名也是一种选择,但我发现,在其意图更清晰local明确语法。它也有点更快,如果性能是一个问题。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top