Ссылка — это указатель на переменную. Здесь рассматриваются способы задания ссылок, символические ссылки и ссылки на таблицу символов.
PERL обеспечивает три способа создания ссылок. Первый способ состоит в применении к переменной операции \:
$sref = \$scalar; # ссылка на скаляр
$aref = \@array; # ссылка на массив
$href = \%hash; # ссылка на ассоциативный массив
Применение операции \ к списку возвращает массив ссылок, например оператор
эквивалентен оператору
В частности, \(@array) возвращает массив ссылок на элементы @array. Аналогично и \(%hash) вернет массив ссылок на ключи и значения %hash с одним нюансом: возвращаются ссылки не на ключи исходного ассоциативного массива, а на их копии.
Второй способ позволяет нам создавать ссылки на безымянные объекты. Ссылка на безымянный скаляр также создается операцией \:
$nref = \10; # ссылка на число
$sref = \"\n"; # ссылка на строку
а ссылки на безымянные массивы и ассоциативные массивы создаются с помощью списков, заключенных в квадратные и фигурные скобки соответственно:
$aref = [1, 2, 3];
$href = {red => 0xff0000, blue => 0x0000ff, green => 0x008000};
Еще один способ создания ссылок имеет синтаксис *name{THING}, где name — имя переменной, а THING — название ее типа:
$sref = *x{SCALAR}; # ссылка на скаляр $x
$aref = *x{ARRAY}; # ссылка на массив @x
$href = *x{HASH}; # ссылка на ассоциативный массив %x
Если переменной с заданным именем и заданного типа нет, то эта конструкция возвращает undef.
Доступ к объекту, на который указывает ссылка $ref (разадресация ссылки) производится согласно следующему правилу: имя объекта эквивалентно выражению {$ref}. Это правило легко запомнить, но полученные с его помощью конструкции читать нелегко. Поэтому PERL допускает несколько сокращений, позволяющих обращаться к элементам разадресуемых объектов проще. Пусть, например,
$s = "Проверка";
$ps = \$s;
@a = (1, 2, 3);
$pa = \@a;
%h = {red => 0xff0000, blue => 0x0000ff, green => 0x008000};
$ph = \%h;
Тогда следующие выражения эквивалентны:
Исходный объект | Полная форма | Сокращения |
$s |
${$ps} |
$$ps |
@a |
@{$pa} |
@$pa |
$a[1] |
${$pa}[1] |
$pa->[1], $$pa[1] |
%h |
%{$ph} |
%$ph |
$h{'red'} |
${$ph}{'red'} |
$ph->{'red'}, $$ph{'red'} |
Теперь мы можем привести пример использования ссылок. Рассмотрим следующий оператор:
@a = ([1, 2, 3], [4, 5, 6], [7, 8, 9]);
Он присваивает переменной @a массив, состоящий из трех ссылок на безымянные массивы. Фактически мы получили двумерный массив, к элементам которого можно обращаться так: $a[строка]->[столбец]. PERL позволяет нам опускать стрелку между индексами массива, т. е. обращение к элементу может иметь вид $a[строка][столбец], подобно обращению к элементам двумерных массивов в других языках программирования.
Символические ссылки
Ссылки, рассмотренные в предыдущем разделе, выглядят вполне традиционно для программиста, знакомого с языками C/C++, Pascal и т. п. Однако, PERL содержит еще один вариант ссылок (т. н. символические ссылки), который ближе по возможностям к функции eval сценарных языков. Суть состоит в том, что любая скалярная переменная может интерпретироваться как указатель на переменную, имя которой она содержит. Пусть, например, переменная $name имеет строковое значение "abc". Тогда мы можем обращаться к $name как к ссылке на переменную с именем abc, например:
$$name = 1; # $abc = 1
${$name} = 2; # $abc = 2
${$name x 2} = 3; # $abcabc = 3
$name->[0] = 4; # $abc[0] = 4
@$name = (); # @abc = ()
Это удивительно мощная, но опасная возможность; отсутствие скалярных типов приводит к тому, что любая скалярная переменная может служить ссылкой на свое содержимое. В итоге PERL считает корректной разадресацию любого скаляра, что может привести к очень интересным и трудноуловимым ошибкам исполнения. Поэтому PERL позволяет запретить использование символических ссылок в текущем блоке программы директивой
Во вложенном блоке мы можем вновь разрешить символические ссылки директивой
Локальные переменные, объявленные функцией my(), невидимы для символических ссылок. Например, сценарий
$ref = "value";
$value = 10;
{
my $value = 20;
print $$ref;
}
выведет на экран число 10, а не 20.
Ссылки на таблицу символов
PERL использует для хранения ссылок на записи таблицы символов внутренний тип typeglob. Для указания на него используется форма *name. Основное назначение таких ссылок — создание синонимов для записей таблицы символов. Присваивание
делает $this синонимом для $that, @this синонимом для @that, %this синонимом для %that и &this синонимом для &that. После этого любая операция с переменными this одновременно изменяет значение соответствующей переменной that, и наоборот. Пример:
$a = 0;
*b = *a;
$a = 1;
print $b; # выводит 1
$b = 2;
print $a; # выводит 2
После появления в языке PERL ссылок эта конструкция стала использоваться довольно редко. Тем не менее она продолжает употребляться в более безопасной форме следующего вида:
Этот оператор временно делает переменную $my_x синонимом переменной $x, но не создает синонимов для @x и т. д.
Еще одно полезное применение typeglob — это создание именованных констант, например, оператор
позволяет нам пользоваться значением переменной $PI, но запрещает его изменение.
[Ссылки]
1. Книги по DHTML, Java. |