Шаг 61.
Символические ссылки

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

    В предыдуших шагах мы говорили, что если ссылка не определена, но ее присутствие требуется контекстом, то она создается автоматически.

    Если же определенная ранее скалярная величина не является ссылкой, но используется в качестве ссылки, то ее называют символической ссылкой. Значение символической ссылки интерпретируется как имя некоторой переменной. Над этой переменной будут выполняться все операции, применяемые к символической ссылке. Вспомним, что значением жесткой ссылки является адрес. В следующем примере переменная $name_a используется как символическая ссылка на переменную .

  $name_a = "a";
  $$name_a = 17;
  @$name_a = (1,2,3);
  $name_a->[3] = 4;
  %$name_a = ("one"=>l, "two"=>2, "three"=>3);
  &$name_a();

    В строке 2 переменной присваивается значение 17. В строке 3 определяется и инициализируется массив с элементами (1,2,3). В строке 4 к массиву добавляется четвертый элемент со значением 4. В строке 5 инициализируется хеш-массив . В строке 6 осуществляется вызов функции а() (предположим, что такая функция существует).

    Символическая ссылка может указывать только на переменную, имя которой содержится в таблице символов пакета.

    Лексические переменные, определяемые при помощи функции my(), в таблицу символов не входят, поэтому их имена невидимы для механизма, реализующего символические ссылки.

    Для иллюстрации рассмотрим следующий пример:

$name_a="a"; 
{ 
  my $a="Hello!";
  print  $$name_a;
};

    Здесь переменная $name_a используется в качестве символической ссылки на переменную , и можно предположить, что результатом выполнения этой последовательности будет вывод строки "Hello!". В действительности переменная является невидимой для символической ссылки, поскольку она определена как лексическая переменная внутри блока {...}. Поэтому в результате выполнения данного фрагмента будет напечатана пустая строка.

    Применение символических ссылок является потенциально опасным из-за возможности возникновения смысловых ошибок. Например, может показаться, что в результате выполнения следующей последовательности операторов:

  $а[0]="b";
  # ....................	
  $b[0]=2;
  $b[1]=2;
  # ....................
  $а[0][0]=0;
  # ....................	
  $prod =  $b[0]*b[l];

переменная $prod получит значение 4. Но это не так. В строке 6 мы осуществляем присваивание, рассчитывая на то, что будет применен известный механизм неявного создания жесткой ссылки $а[0]. Мы "забыли" о том, что значение $а[0] уже использовалось в строке 1 и, следовательно, в строке 6 элемент массива $а[0] является символической ссылкой, указывающей на переменную с именем "b". Это имя будет подставлено вместо символической ссылки, в результате чего элемент массива b[0] получит новое значение 0. В итоге значение переменной $prod будет равно 0.

    Во избежание подобных ошибок можно запретить использование символических ссылок в пределах текущего блока при помощи директивы:

  use  strict   'refs';

    Это ограничение, если требуется, можно отменить для внутреннего блока при помощи другой директивы:

  no strict   'refs';


    Замечание. В версии 5.001 появилась новая возможность: если переменную, являющуюся символической ссылкой, заключить в фигурные скобки, то такая конструкция интерпретируется не как символическая ссылка, а как значение переменной, подобно тому, как аналогичная конструкция интерпретируется командной оболочкой shell операционной системы UNIX. В следующем фрагменте:
  use strict   'refs';
  $ {name} ; 
  ${"name"} ;

вторая строка представляет собой просто значение переменной $name, а третья строка интерпретируется как символическая ссылка, указывающая на переменную $name и вследствие применения директивы use strict 'refs' вызывает сообщение об ошибке вида:

  Can't use string   ("name")   as a SCALAR ref while  "strict refs"  in use

    Со следующего шага мы начнем рассматривать примеры использования ссылок.




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