Если же определенная ранее скалярная величина не является ссылкой, но используется в качестве ссылки,
то ее называют символической ссылкой. Значение символической ссылки интерпретируется как имя некоторой
переменной. Над этой переменной будут выполняться все операции, применяемые к символической ссылке.
Вспомним, что значением жесткой ссылки является адрес. В следующем примере переменная $name_а
используется как символическая ссылка на переменную $а.
1. $name_a = "а";
2. $$name_а = 17;
3. @$name_а = (1,2,3);
4. $name_a->[3] = 4;
5. %$name_a = ("оnе" => 1, "two" => 2, "three" => 3);
6. &$name_a( );
B строке 2 переменной $a присваивается значение 17. В строке 3 определяется и инициализируется
массив @а с элементами (1,2,3). В строке 4 к массиву @а добавляется четвертый элемент со значением 4.
В строке 5 инициализируется хэш-массив %а. В строке 6 осуществляется вызов функции а( ) (предположим,
что такая функция существует).
Символическая ссылка может указывать только на переменную, имя которой содержится в таблице символов
пакета.
Лексические переменные, определяемые при помощи функции
my( ),
в таблицу символов не входят,
поэтому их имена невидимы для механизма, реализующего символические ссылки.
Для иллюстрации рассмотрим следующий пример:
$name_а = "а";
{
my $a = "Hello!";
print $$name_а;
};
Здесь переменная $name_a используется в качестве символической ссылки на переменную $а, и можно
предположить, что результатом выполнения этой последовательности будет вывод строки "Hello!".
В действительности переменная $а является невидимой для символической ссылки, поскольку она определена
как лексическая переменная внутри блока {...}. Поэтому в результате выполнения данного фрагмента
будет напечатана пустая строка.
Применение символических ссылок является потенциально опасным из-за возможности возникновения
смысловых ошибок. Например, может показаться, что в результате выполнения следующей последовательности
операторов:
1. $a[0] = "b";
2. #..............
3. $b[0] = 2;
4. $b[1] = 2;
5. #..............
6. $а[0][0] = 0;
7. #..............
8. $prod = $b[0]*b[1];
переменная $prod получит значение 4. Но это не так. В строке 6 мы осуществляем присваивание, рассчитывая
на то, что будет применен известный механизм неявного создания жесткой ссылки $а[0]. Мы «забыли» о том,
что значение $а[0] уже использовалось в строке1 и, следовательно, в строке 6 элемент массива $а[0]
является символической ссылкой, указывающей на переменную с именем "b". Это имя будет подставлено вместо
символической ссылки, в результате чего элемент массива b[0] получит новое значение 0. В итоге значение
переменной $prod будет равно 0.
Во избежание подобных ошибок можно запретить использование символических ссылок в пределах текущего
блока при помощи директивы
use strict ‘refs’;
Это ограничение, если требуется, можно отменить для внутреннего блока при помощи другой директивы
no strict 'refs';
Еще одно замечание, касающееся символических ссылок. В версии 5.001 появилась новая возможность:
если переменную, являющуюся символической ссылкой, заключить в фигурные скобки, то такая конструкция
интерпретируется не как символическая ссылка, а как значение переменной, подобно тому как аналогичная
конструкция интерпретируется командной оболочкой shell операционной системы UNIX. В следующем фрагменте:
1. use strict 'refs';
2. ${name};
3. ${"name"};
вторая строка представляет собой просто значение переменной $name, а третья строка интерпретируется
как символическая ссылка, указывающая на переменную $name, и из-за применения директивы use strict 'refs'
вызывает сообщение об ошибке вида
Can't use string ("name") as a SCALAR ref while "strict refs" in use