Разыменование ссылок

Разыменованием ссылки называется получение объекта, на который указывает эта ссылка. Для разыменования, как и для создания ссылки, применяются различные синтаксические конструкции, подчас достаточно сложные для визуального восприятия. К ним нужно привыкнуть. Вид конструкции зависит от типа ссылки, к которой применяется разыменование. Рассмотрим их по степени возрастания сложности.

Разыменование простой скалярной переменной

Если ссылка на некоторый объект: скалярную переменную, массив, ассоциативный массив и т. д., является простой скалярной переменной без индексов, то для обращения к самому объекту применяется правило: вместо имени объекта подставить в выражение простую скалярную переменную, содержащую ссылку. Например:
1.$а = $$scal_ref;
2.@b = @$arr_ref;
3.%с = %$hash_ref;
4.&f = &$code_ref;
5.$$d[0] = 7;
6.$$h{"one"} = 1;
В этом примере предполагается, что переменная $scal_ref содержит ссылку на скалярную величину, $arr_ref — ссылку на массив, $hash_ref — ссылку на ассоциативный массив, $code_ref — ссылку на подпрограмму.
Рассмотрим подробно пятую строку. Во-первых, следует определить, что является ссылкой: скалярная переменная $d, указывающая на анонимный массив, или элемент $d[0] массива @d. Ответ содержится в сформулированном выше правиле разыменования. Поскольку в строке 5 применяется именно оно, то индексированная переменная $d[0] ссылкой быть не может. Ссылкой является простая скалярная переменная $d, которая используется в качестве имени. Из контекста видно, что на ее месте должно стоять имя массива, следовательно, $d является ссылкой на анонимный массив.
Во-вторых, здесь мы имеем пример неявного создания ссылки, о котором говорилось в предыдущем разделе. Ссылка $d не была ранее создана явным образом, но ее существование предполагается в операции присваивания. Поэтому компилятор создаст ссылку $d на анонимный массив, поместит в нее адрес массива и по этому адресу сохранит значение первого элемента, равное 7.
Все сказанное можно отнести к шестой строке с единственным отличием: вместо ссылки на анонимный массив здесь фигурирует ссылка $h на анонимный хэш-массив.

Блоки в операциях разыменования ссылок

Если ссылка является не простой скалярной переменной, а, например, элементом массива или ассоциативного массива, то для ее разыменования нельзя применить правило предыдущего раздела. В этом случае следует заключить ссылку в фигурные скобки и полученный блок использовать в качестве имени переменной в выражениях. Вообще говоря, во всех случаях разыменования ссылок в качестве имени объекта можно использовать блок, результатом выполнения которого является ссылка соответствующего типа.
${$d[0]} = 7;
${$h{"one"}} = 1;
${&f()}[1] = 3;
Разберем первую строку. Начальный символ $ является признаком скалярной переменной, за которым должно следовать ее имя. Вместо имени используется блок, следовательно, выражение внутри блока интерпретируется как ссылка. В данном случае осуществляется разыменование ссылки $d[0], являющейся элементом массива @d. Подобным же образом во второй строке осуществляется обращение к скалярной переменной, на которую указывает ссылка $h{"one"}, являющаяся элементом ассоциативного массива %h. В третьей строке блок, возвращающий ссылку, состоит из одного обращения к функции f( ). Ее значение интерпретируется как ссылка на массив, и второму элементу этого массива присваивается значение 3.

Операция разыменования

Применение правила разыменования предыдущего раздела может привести к появлению громоздких выражений, содержащих множество вложенных друг в друга блоков и очень сложных для визуального восприятия. Непростыми являются уже вышеприведенные примеры. При построении же более сложных структур выражения становятся почти необозримыми. Даже достаточно простые конструкции требуют определенного усилия для того, чтобы понять, что они означают:
${$а[0]}[1] = 17;
${$b[0]}{"one"} = 1;
В первой строке осуществляется обращение к отдельному элементу массива массивов, во второй — к отдельному элементу массива хэш-массивов.
ПРИМЕЧАНИЕ В действительности речь идет соответственно о массиве, элементами которого являются ссылки на анонимные массивы, и о массиве, элементами которого являются ссылки на анонимные хэш-массивы. Но для краткости в подобных случаях мы будем употреблять сочетания «массив массивов», «массив хэш-массивов» и т. д.
Несколько упростить запись и улучшить наглядность можно, используя операцию -> («стрелка»).
Операнд слева от стрелки может быть любым выражением, возвращающим ссылку на массив или хэш-массив.
Если левосторонний операнд является ссылкой на массив, то операнд справа от стрелки - индекс, заключенный в квадратные скобки и определяющий элемент этого массива.
Если левосторонний операнд является ссылкой на хэш-массив. то операнд справа от стрелки - значение ключа, помещенное в фигурные скобки и определяющее элемент этого хэш-массива.
Результатом операции -> является соответственно значение элемента массива или хэш-массива. Предыдущий пример можно более компактно записать в виде:
$а[0]->[1] = 17;
$b[0]->{"one"} = 1;
Конструкция $а[0]->[1] обозначает второй элемент массива, определяемого ссылкой $а[0]. Конструкция $b[0]->{"one"} обозначает элемент, соответствующий ключу "one" хэш-массива, задаваемого ссылкой $b[0].
В общем случае, если $arr_ref — ссылка на массив, то $arr_ref->[$i] обозначает i-й элемент этого массива. Если $hash_ref — ссылка на хэш-массив, то $hash_ref->{"key"} обозначает элемент этого хэш-массива, соответствующий ключу "key".
Если бы в последнем примере вместо именованных массивов @а и @b использовались ссылки на массив, например $ref_a и $ref_b, то соответствующие операции присваивания имели бы вид:
$ref_a->[0]->[1] = 17;
$ref_b->[0]->{"one"} = 1;
Здесь мы снова сталкиваемся с неявным созданием ссылок. По контексту элемент массива $ref_a->[0] должен быть ссылкой на массив, a $ref_b->[0] — ссылкой на хэш-массив. Обе ссылки ранее не были определены, но их существование предполагается в контексте выражения. Данные ссылки будут созданы автоматически.
Операция -> позволяет для обращения к отдельному элементу составного массива или хэш-массива использовать более простые выражения, например:
$a[$i]->[$j]->[$k] вместо ${${$a[$i]}[$j]}[$k], 
$b[$i]->{"key"}->[$j] вместо ${${$b[0]}{>key>}}[$j]
Дальнейшее упрощение связано с тем, что при обращении к элементам сложных структур, представляющих собой комбинации вложенных массивов и хэш-массивов, можно опустить символы -> между квадратными и/или фигурными скобками, содержащими индексы или ключи элементов. Предыдущие выражения примут еще более простой вид:
$a[$i][$j][$k] и $b[$i]{"key "}[$j]
соответственно.

Следующая страница Содержание главы




2011-05-03 15:16:09 DRON

Спасибо.




Оставить комментарий:
Ваше Имя:
Email:
Антибот: *  
Ваш комментарий: