Perl: ссылки Печать
Добавил(а) microsin   

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

PERL обеспечивает три способа создания ссылок. Первый способ состоит в применении к переменной операции \:

$sref = \$scalar; # ссылка на скаляр
$aref = \@array;  # ссылка на массив
$href = \%hash;   # ссылка на ассоциативный массив

Применение операции \ к списку возвращает массив ссылок, например оператор

@list = \($a, @b, %c);

эквивалентен оператору

@list = (\$a, \@b, \%c);

В частности, \(@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 позволяет запретить использование символических ссылок в текущем блоке программы директивой

use strict 'refs';

Во вложенном блоке мы можем вновь разрешить символические ссылки директивой

no strict 'refs';

Локальные переменные, объявленные функцией 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. После этого любая операция с переменными this одновременно изменяет значение соответствующей переменной that, и наоборот. Пример:

$a = 0;
*b = *a;
$a = 1;
print $b;       # выводит 1
$b = 2;
print $a;       # выводит 2

После появления в языке PERL ссылок эта конструкция стала использоваться довольно редко. Тем не менее она продолжает употребляться в более безопасной форме следующего вида:

local *my_x = \$x;

Этот оператор временно делает переменную $my_x синонимом переменной $x, но не создает синонимов для @x и т. д.

Еще одно полезное применение typeglob — это создание именованных констант, например, оператор

*PI = \3.14159265358979;

позволяет нам пользоваться значением переменной $PI, но запрещает его изменение.

[Ссылки]

1. Книги по DHTML, Java.