perl read()函数和缓冲区背后的魔力是什么? [英] What is the magic behind perl read() function and buffer which is not a ref?

查看:279
本文介绍了perl read()函数和缓冲区背后的魔力是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法理解Perl read($ buf)函数如何能够修改$ buf变量的内容。 $ buf不是引用,因此参数由copy(来自我的c / c ++知识)给出。那么为什么在调用者中修改$ buf变量呢?

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 ?

这是一个平局变量还是什么?关于setbuf的C文档对我来说也是非常难以捉摸的

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


推荐答案

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

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


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

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).

例如:

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

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

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

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...
}

这篇关于perl read()函数和缓冲区背后的魔力是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆