perl read() 函数和不是引用的缓冲区背后的魔力是什么?

发布于 2024-09-04 15:42:07 字数 496 浏览 9 评论 0原文

我不明白 Perl read($buf) 函数如何修改 $buf 变量的内容。 $buf 不是引用,因此参数是通过 copy 给出的(来自我的 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

I do not get to understand how the Perl read($buf) function is able to modify the content of the $buf variable. $buf is not a reference, so the parameter is given by copy (from my c/c++ knowledge). So how come the $buf variable is modified in the caller ?

Is it a tie variable or something ? The C documentation about setbuf is also quite elusive and unclear to me

# 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦巷 2024-09-11 15:42:07

不需要任何魔法——如果你愿意的话,所有 Perl 子例程都是通过别名调用的。 perlsub

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

例如:

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

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

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

sub read_this {
  $fh->read($_[0]);  # will modify caller's variable
}
sub read_that {
  $fh->read(shift);  # so will this...
}

No magic is needed -- all perl subroutines are call-by-alias, if you will. Quoth perlsub:

The array @_ is a local array, but its elements are aliases
for the actual scalar parameters. In particular, if an element $_[0]
is updated, the corresponding argument is updated (or an error occurs
if it is not updatable).

For example:

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

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

In your "Example 2", your read_it sub copies the first element of @_ to the lexical $buf, which copy is then modified "in place" by the call to read(). Pass in $_[0] instead of copying, and see what happens:

sub read_this {
  $fh->read($_[0]);  # will modify caller's variable
}
sub read_that {
  $fh->read(shift);  # so will this...
}
好菇凉咱不稀罕他 2024-09-11 15:42:07

read() 是一个内置函数,因此可以发挥神奇作用。不过,您可以通过声明 函数原型,使用自己的函数完成类似的操作:

sub myread(\$) { ... }

参数声明 \$ 表示参数作为引用隐式传递。

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

read() is a built-in function, and so can do magic. You can accomplish something similar with your own functions, though, by declaring a function prototype:

sub myread(\$) { ... }

The argument declaration \$ means that the argument is implicitly passed as a reference.

The only magic in the built-in read is that it works even when called indirectly or as a filehandle method, which doesn't work for regular functions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文