Шаг 117.
Способы передачи по ссылке параметров-массивов. Использование ссылок

    На этом шаге мы рассмотрим использование ссылок.

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

#! perl -w
sub doublparms 
{
  my ($listref, $hashref) = @_;
  foreach $item (@$listref)
  { 
    $item *= 2;
  }
  foreach $key (keys  %$hashref)
  { 
    $$hashref {$key} *= 2;
  }
}

@somelist=(1,2,3);
%somehash=("one"=>5, "two"=>15, "three"=>20); 
print "начальные значения: \@somelist=@somelist\n";
foreach $key (keys %somehash) 
{
  print "\$somehash{$key}=$somehash{$key} ";
}
print "\n";

doublparms (\@somelist, \%somehash);
print "итоговые значения: \n\@somelist=@somelist\n";
foreach $key (keys %somehash) 
{
  print "\$somehash{$key}=$somehash{$key} ";
}
print "\n";
Текст этого примера можно взять здесь.

    Здесь для описания локальных переменных использована функция my(). Как мы выяснили ранее, применение функции my() в подобном случае реализует передачу параметров по значению. Другими словами, их изменение внутри подпрограммы не влияет на фактические параметры. Каким же образом в данном случае осуществляется передача массива и хеш-массива по ссылке? Дело в том, что по значению передаются только ссылки, указывающие на фактические параметры: массив @somelist и хеш-массив %somehash. Используя операции разыменования внутри подпрограммы, мы получаем доступ непосредственно к массиву @somelist и хеш-массиву %somehash, и изменяем их элементы. В результате выполнения данного сценария будет выведено (рисунок 1):


Рис.1. Результат работы примера

    Со следующего шага мы будем отвечать на вопрос: в каких случаях функцию local() нельзя заменить функцией my()?




Предыдущий шаг Содержание Следующий шаг