Иллюстрированный самоучитель по Perl

Передача параметров

Информация в подпрограмму и обратно передается через параметры (аргументы). Для передачи параметров в подпрограмму используется специальный массив @_. Все параметры запоминаются в элементах массива $_ [ 0 ], $_ [ 1 ] и т. д. Такой механизм позволяет передавать в подпрограмму произвольное количество параметров.

Массив @_ является локальным для данной подпрограммы, но его элементы – это псевдонимы действительных скалярных параметров. Изменение элемента массива @_ вызывает изменение соответствующего действительного параметра.

В языках программирования различают передачу параметров по ссылке и по значению. При передаче параметров по значению подпрограмма получает копию переменной. Изменение копии внутри подпрограммы не влияет на ее оригинал. При передаче параметров по ссылке подпрограмма получает доступ к самой переменной и может ее изменять.

Передача параметров через специальный массив @_ фактически является передачей параметров по ссылке. В языке Perl можно реализовать передачу параметров по значению, если внутри подпрограммы при помощи функции ту о объявить локальные переменные и присвоить им значения фактических параметров из массива @_, как это сделано в следующем примере.

#!/usr/bin/perl
# Передача в подпрограмму параметров по значению sub f {
my($x, $y) = @_; return (++$х * – $у); }
$val = f ^lib-print "Значение (9+1) * (11-1) равно $val.\n"; $х = 9; $У = 11;
$val = f($x,$y);
print "Значение ($х+1) * ($у-1) равно $val.\n";
print "Значение \$х остается равным $х, а \$у равным $у.\п";

Результат выполнения:

Значение (9+1) * (11-1) равно 100.
Значение (9+1) * (11-1) равно 100.
Значение $х остается равным 9, а $у равным 11.

Передача по ссылке параметров-массивов

Итак, подпрограмма получает и возвращает параметры через специальный массив @_. Если параметр является массивом или хеш-массивом, его элементы также сохраняются в массиве параметров @_. При передаче в подпрограмму нескольких параметров-массивов или хеш-массивов они утрачивают свою целостность. Иными словами, после записи параметров-массивов (хеш-массивов) в массив @_ из него невозможно выделить отдельный параметр-массив (хеш-массив): все параметры в массиве @_ хранятся единой "кучей". Для сохранения при передаче в подпрограмму целостности массива или хеш-массива существуют два основных подхода.

Использование типа typeglob

Первый подход, более старый, заключается в использовании внутреннего типа данных, называемого typeglob. Принадлежность к типу typeglob обозначается префиксом "*". Префикс "*" можно рассматривать как метасимвол, вместо которого может стоять любой из префиксов "$", "@", "%", "&", обозначающих тип данных "скаляр", "массив", "хеш-массив", "функция" соответственно. Интерпретатор преобразует переменную типа typeglob, например, *abc, в скалярную величину. Эта величина является ссылкой на гнездо в таблице символов, содержащее элементы, разных типов с одинаковым именем abc, и представляет любой из этих элементов.

Например, запись *abc обозначает всю совокупность, а также любую из следующих переменных: скаляр $abc, массив @abc, хеш %abc, функция sabc.

(Таблицы символов обсуждаются в части 12)

Передача в подпрограмму вместо параметра-массива или хеш-массива соответствующей переменной типа typeglob является имитацией передачи параметра-массива (хеш-массива) по ссылке с сохранением его целостности. Рассмотрим следующий пример.

sub doublargs {
local(*mylist, *myhash) = @_;
foreach $item (@mylist) { $item *= 2;
}
foreach $key (keys %myhash) { $myhash{$key} *= 2;
} }
@somelist= (1.2.3); <strong>/^~~ – """"~\</strong> %somehash=("one" › 5, "two" › 15, "three" › 20);
print "начальные значения:\n\@somelist=@somelist\n"; foreach $key (keys %somehash) {
print "\$somehash{$key}=$somehash{$key} ";
}
print "\n";
doublargs(*somelist,*somehash);
print "итоговые значения:\n\@somelist=@somelist\n";
foreach $key (keys %somehash) {
print "\$somehash{$key}=$somehash{$key} "; } print "\n";
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.