6

我不明白 Perl read($buf) 函数如何能够修改 $buf 变量的内容。$buf 不是参考,因此参数由副本给出(根据我的 c/c++ 知识)。那么 $buf 变量是如何在调用者中被修改的呢?

是平局变量还是什么?关于 setbuf 的 C 文档对我来说也非常难以捉摸和不清楚

# Example 1
$buf=''; # It is a scalar, not a ref
$bytes = $fh->read($buf);
print $buf; # $buf was modified, what is the magic ?

# Example 2
sub read_it {
    my $buf = shift;
    return $fh->read($buf);
}
my $buf;
$bytes = read_it($buf);
print $buf; # As expected, this scope $buf was not modified
4

2 回答 2

11

不需要魔法——如果你愿意,所有的 perl 子例程都是按别名调用的。Quoth perlsub

数组@_ 是一个本地数组,但它的元素是实际标量参数的别名。特别是,如果元素 $_[0] 被更新,则相应的参数也会被更新(或者如果它不可更新,则会发生错误)。

例如:

sub increment {
  $_[0] += 1;
}

my $i = 0;
increment($i);  # now $i == 1

在您的“示例 2”中,您的read_it子将 的第一个元素复制@_到 lexical$buf中,然后通过调用“就地”修改该副本read()。传入$_[0]而不是复制,看看会发生什么:

sub read_this {
  $fh->read($_[0]);  # will modify caller's variable
}
sub read_that {
  $fh->read(shift);  # so will this...
}
于 2010-06-10T04:51:56.430 回答
0

read()是一个内置函数,所以可以做魔术。不过,您可以通过声明函数原型来使用自己的函数完成类似的操作:

sub myread(\$) { ... }

参数声明\$意味着参数作为引用被隐式传递。

内置的唯一魔力read是它即使在间接调用或作为文件句柄方法时也能工作,这对常规函数不起作用。

于 2010-06-10T04:47:56.420 回答