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; Тогда следующие выражения эквивалентны:
Теперь мы можем привести пример использования ссылок. Рассмотрим следующий оператор: @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, но запрещает его изменение. [Ссылки] |