Передача параметров
Информация в подпрограмму и обратно передается через параметры (аргументы). Для передачи параметров в подпрограмму используется специальный массив @_. Все параметры запоминаются в элементах массива $_ [ 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";