Я не добираюсь, чтобы понять, как Perl читал ($buf), функция может изменить содержание переменной $buf. $buf не является ссылкой, таким образом, параметр дан копией (от моего c/c ++ знание). Таким образом, каким образом переменная $buf изменяется в вызывающей стороне?
Действительно ли это - переменная связи или что-то? Документация C о setbuf также довольно неуловима и неясна мне
# 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:
Массив @_ является локальным массивом, но его элементы являются псевдонимами для фактических скалярных параметров. В частности, если элемент $_[0] обновляется, то обновляется и соответствующий аргумент (или возникает ошибка если он не может быть обновлен).
Например:
sub increment {
$_[0] += 1;
}
my $i = 0;
increment($i); # now $i == 1
В "Примере 2" ваш read_it
sub копирует первый элемент @_
в лексический $buf
, который затем модифицируется "на месте" вызовом read()
. Передайте $_[0]
вместо копирования и посмотрите, что произойдет:
sub read_this {
$fh->read($_[0]); # will modify caller's variable
}
sub read_that {
$fh->read(shift); # so will this...
}
read ()
- это встроенная функция, которая может творить чудеса. Однако вы можете добиться чего-то подобного с помощью ваших собственных функций, объявив прототип функции :
sub myread(\$) { ... }
Объявление аргумента \ $
означает, что аргумент неявно передается как ссылка.
Единственное волшебство во встроенном чтении
заключается в том, что оно работает даже при косвенном вызове или как метод дескриптора файла, который не работает для обычных функций.