Это команда perlref, которую можно запустить в бесплатном хостинг-провайдере OnWorks, используя одну из наших многочисленных бесплатных онлайн-рабочих станций, таких как Ubuntu Online, Fedora Online, онлайн-эмулятор Windows или онлайн-эмулятор MAC OS.
ПРОГРАММА:
ИМЯ
perlref - ссылки Perl и вложенные структуры данных
ЗАМЕТКА
Это полная документация по всем аспектам ссылок. Для более короткого руководства
Введение только в основные функции см. в perlreftut.
ОПИСАНИЕ
До выпуска 5 Perl было трудно представить сложные структуры данных, потому что
все ссылки должны были быть символическими - и даже тогда было сложно ссылаться на переменную
вместо записи в таблице символов. Perl теперь не только упрощает использование символических
ссылки на переменные, но также позволяет иметь "жесткие" ссылки на любой фрагмент данных или
код. Любой скаляр может содержать жесткую ссылку. Поскольку массивы и хэши содержат скаляры,
теперь вы можете легко создавать массивы массивов, массивы хэшей, хэши массивов, массивы
хеши функций и так далее.
Жесткие ссылки - это умно - они автоматически отслеживают количество ссылок.
освобождает указанную вещь, когда ее счетчик ссылок становится равным нулю. (Количество ссылок
для значений в самореферентных или циклических структурах данных не может быть нулевым без
небольшая помощь; см. «Циркулярные ссылки» для подробного объяснения.) Если это произойдет
чтобы быть объектом, объект разрушается. См. Perlobj для получения дополнительной информации об объектах. (В
в смысле, все в Perl является объектом, но мы обычно оставляем за собой слово для ссылок на
объекты, которые были официально «благословлены» в пакет класса.)
Символьные ссылки - это имена переменных или других объектов, а также символическая ссылка в
Файловая система Unix содержит просто имя файла. Обозначение * glob - это что-то вроде
символическая ссылка. (Символические ссылки иногда называют «мягкими ссылками», но
пожалуйста, не называйте их так; ссылки достаточно сбивают с толку без бесполезных синонимов.)
Напротив, жесткие ссылки больше похожи на жесткие ссылки в файловой системе Unix: они используются
для доступа к базовому объекту, не беспокоясь о его (другом) имени. Когда
слово "ссылка" используется без прилагательного, так как в следующем абзаце оно
Обычно говорят о жесткой ссылке.
Ссылки на Perl легко использовать. Есть только один главный принцип: в общем,
Perl не делает неявных ссылок или разыменований. Когда скаляр содержит ссылку,
он всегда ведет себя как простой скаляр. Он не волшебным образом начинает быть массивом или хешем
или подпрограмма; вы должны явно указать ему это сделать, разыменовав его.
Тем не менее, имейте в виду, что Perl версии 5.14 вводит исключение из правила для
синтаксическое удобство. Экспериментальный массив и поведение функции хеш-контейнера позволяет
ссылки на массив и хэш, которые будут обрабатываться Perl, как если бы они были явно
синтаксически разыменован. См. «Синтаксические улучшения» в perl5140delta и perlfunc
для получения информации.
Создание Рекомендации
Ссылки можно создавать несколькими способами.
1. Используя оператор обратной косой черты для переменной, подпрограммы или значения. (Это много работает
как оператор & (адрес из) в C.) Обычно это создает другой ссылка на
переменная, потому что ссылка на переменную уже есть в таблице символов.
Но ссылка на таблицу символов может исчезнуть, и вы все равно будете иметь ссылку,
обратная косая черта вернулась. Вот некоторые примеры:
$ scalarref = \ $ foo;
$ arrayref = \ @ARGV;
$ hashref = \% ENV;
$ coderef = \ & обработчик;
$ globref = \ * foo;
Невозможно создать настоящую ссылку на дескриптор ввода-вывода (дескриптор файла или дескриптор)
с помощью оператора обратной косой черты. Максимум, что вы можете получить, - это ссылку на typeglob,
что на самом деле представляет собой полную запись в таблице символов. Но см. Объяснение
* foo {THING} синтаксис ниже. Однако вы по-прежнему можете использовать глобусы типов и глобусы как
хотя это были ручки ввода-вывода.
2. Ссылку на анонимный массив можно создать с помощью квадратных скобок:
$ arrayref = [1, 2, ['a', 'b', 'c']];
Здесь мы создали ссылку на анонимный массив из трех элементов, последний
Элемент сам по себе является ссылкой на другой анонимный массив из трех элементов. (В
Для доступа к нему можно использовать многомерный синтаксис, описанный ниже. Например,
после указанного выше "$ arrayref -> [2] [1]" будет иметь значение "b".)
Ссылка на нумерованный список - это не то же самое, что использовать квадрат.
скобки - это то же самое, что создать список литературы!
@list = (\ $ a, \ @b, \% c);
@list = \ ($ a, @b,% c); # то же самое!
В качестве особого случая "\ (@ foo)" возвращает список ссылок на содержимое @foo, а не
ссылка на сам @foo. То же самое для% foo, за исключением того, что ключевые ссылки на
копии (поскольку ключи - это просто строки, а не полноценные скаляры).
3. Ссылку на анонимный хеш можно создать с помощью фигурных скобок:
$ hashref = {
'Adam' => 'Ева',
'Clyde' => 'Бонни',
};
Подобные анонимные составители хешей и массивов могут свободно смешиваться, чтобы создавать как
усложняйте структуру как хотите. Многомерный синтаксис, описанный ниже
работает и для них. Приведенные выше значения являются литералами, но переменные и выражения
будет работать так же хорошо, потому что операторы присваивания в Perl (даже внутри местный() or
мой()) являются исполняемыми операторами, а не объявлениями времени компиляции.
Поскольку фигурные скобки (скобки) используются для нескольких других вещей, включая БЛОКИ,
иногда вам может потребоваться устранить неоднозначность фигурных скобок в начале оператора
поставив "+" или "возврат" впереди, чтобы Perl понял, что открывающая скобка не
запуск БЛОКА. Экономичность и мнемоническая ценность использования завитушек оправданы.
это случайные лишние хлопоты.
Например, если вы хотите, чтобы функция создавала новый хеш и возвращала ссылку на него,
у вас есть следующие варианты:
дополнительный хешем {{@_}} # неверно написано
дополнительный хешем {+ {@_}} # ок
дополнительный хешем {return {@_}} # ок
С другой стороны, если вам нужно другое значение, вы можете сделать это:
sub showem {{@_}} # неоднозначно (сейчас нормально,
# но может измениться)
sub showem {{; @_ } } # в порядке
sub showem {{return @_}} # ок
Ведущие "+ {" и "{;" всегда служат для устранения неоднозначности выражения, чтобы означать либо
ссылка HASH или БЛОК.
4. Ссылку на анонимную подпрограмму можно создать с помощью «sub» без
дополнительное имя:
$ coderef = sub {print "Boink! \ n"};
Обратите внимание на точку с запятой. За исключением того, что код внутри не выполняется немедленно, "sub
{} "- это не столько объявление, сколько оператор, например," do {} "или" eval {} ".
(Однако независимо от того, сколько раз вы выполняете эту конкретную строку (если вы не в
an "eval (" ... ")"), в $ coderef по-прежнему будет ссылка на то же анонимный
подпрограмма.)
Анонимные подпрограммы действуют как закрытие по отношению к мой() переменные, то есть
переменные, лексически видимые в текущей области видимости. Замыкание - это идея, выходящая из
Мир Лиспа, который говорит, что если вы определяете анонимную функцию в конкретном лексическом
context, он делает вид, что работает в этом контексте, даже когда он вызывается вне контекста.
Говоря человеческим языком, это забавный способ передачи аргументов подпрограмме, когда вы определяете
это так же хорошо, как когда вы это называете. Это полезно для настройки небольших фрагментов кода для запуска
позже, например, обратные вызовы. С ним можно даже делать объектно-ориентированные вещи, хотя Perl
уже предоставляет другой механизм для этого - см. perlobj.
Вы также можете думать о закрытии как о способе написания шаблона подпрограммы без использования
eval (). Вот небольшой пример того, как работают замыкания:
суб газета {
мой $ x = сдвиг;
return sub {мой $ y = shift; print "$ x, $ y! \ n"; };
}
$ h = newprint ("Привет");
$ g = newprint ("Приветствую");
# Время проходит...
& $ h ("мир");
& $ g ("земляне");
Это печатает
Привет, мир!
Привет, земляне!
Обратите особое внимание на то, что $ x продолжает ссылаться на значение, переданное в newprint ()
несмотря на "my $ x" вышел из области видимости к моменту запуска анонимной подпрограммы.
Вот что такое закрытие.
Кстати, это относится только к лексическим переменным. Динамические переменные продолжают
работают так, как работали всегда. Закрытие - это не то, что большинство программистов Perl
нужно побеспокоиться о самом начале.
5. Ссылки часто возвращаются специальными подпрограммами, называемыми конструкторами. Perl
объекты - это просто ссылки на особый тип объекта, который знает, какой
пакет, с которым он связан. Конструкторы - это просто специальные подпрограммы, которые умеют
чтобы создать эту ассоциацию. Они делают это, начиная с обычной ссылки, и это
остается обычной ссылкой, даже если она также является объектом. Конструкторы
часто называют «новый ()». Ты называть их косвенно:
$ objref = new Doggie (Tail => 'short', Ears => 'long');
Но в некоторых случаях это может привести к неоднозначному синтаксису, поэтому часто лучше использовать
подход прямого вызова метода:
$ objref = Doggie-> new (Tail => 'short', Ears => 'long');
используйте Term :: Cap;
$ terminal = Term :: Cap-> Tgetent ({OSPEED => 9600});
используйте Tk;
$ main = MainWindow-> новый ();
$ menubar = $ main-> Frame (-relief => "приподнятый",
-borderwidth => 2)
6. Ссылки соответствующего типа могут появиться, если вы разыменуете их.
в контексте, предполагающем, что они существуют. Потому что мы не говорили о разыменовании
пока что мы не можем показать вам никаких примеров.
7. Ссылку можно создать с помощью специального синтаксиса, с любовью известного как
Синтаксис * foo {THING}. * foo {THING} возвращает ссылку на слот THING в * foo (который
это запись таблицы символов, которая содержит все, что известно как foo).
$ scalarref = * foo {SCALAR};
$ arrayref = * ARGV {ARRAY};
$ hashref = * ENV {HASH};
$ coderef = * обработчик {КОД};
$ ioref = * STDIN {IO};
$ globref = * foo {GLOB};
$ formatref = * foo {ФОРМАТ};
$ globname = * foo {ИМЯ}; # "фу"
$ pkgname = * foo {ПАКЕТ}; # "главный"
Большинство из них говорят сами за себя, но * foo {IO} заслуживает особого внимания. Это
возвращает дескриптор ввода-вывода, используемый для дескрипторов файлов ("open" в perlfunc), сокетов ("socket"
в perlfunc и "socketpair" в perlfunc) и дескрипторы каталогов ("opendir" в
perlfunc). Для совместимости с предыдущими версиями Perl * foo {FILEHANDLE} является
синоним * foo {IO}, хотя он устарел с версии 5.8.0. Если предупреждения об устаревании
действуют, он предупредит о его использовании.
* foo {THING} возвращает undef, если это конкретное THING еще не использовалось, за исключением
случай скаляров. * foo {SCALAR} возвращает ссылку на анонимный скаляр, если $ foo
еще не использовался. Это может измениться в будущем выпуске.
* foo {NAME} и * foo {PACKAGE} являются исключением, поскольку они возвращают строки, а
чем ссылки. Они возвращают пакет и имя самого typeglob, скорее
чем тот, который был ему назначен. Итак, после "* foo = * Foo :: bar" * foo станет
"* Foo :: bar" при использовании в качестве строки, но * foo {PACKAGE} и * foo {NAME} продолжат
производят «main» и «foo» соответственно.
* foo {IO} - альтернатива механизму * HANDLE, описанному в "Typeglobs и
Файловые дескрипторы "в perldata для передачи дескрипторов файлов в подпрограммы или из них, или
хранение в более крупных структурах данных. Его недостаток в том, что он не создает новый
filehandle для вас. Его преимущество в том, что у вас меньше риск заткнуть более чем
вы хотите с назначением typeglob. (Он по-прежнему объединяет файл и каталог
обрабатывает, тем не менее.) Однако, если вы присвоите входящее значение скаляру вместо
typeglob, как мы это делаем в примерах ниже, риска этого нет.
брызги (* STDOUT); # передать весь шар
брызги (* STDOUT {IO}); # передать дескрипторы файла и каталога
суб трещать {
мой $ fh = shift;
напечатайте $ fh "ее ну а хммм \ n";
}
$ rec = get_rec (* STDIN); # передать весь шар
$ rec = get_rec (* STDIN {IO}); # передать дескрипторы файла и каталога
суб get_rec {
мой $ fh = shift;
вернуть скаляр <$ fh>;
}
. Рекомендации
Вот и все, что касается создания ссылок. К настоящему времени вы, вероятно, очень хотите знать, как использовать
ссылки, чтобы вернуться к давно утерянным данным. Есть несколько основных методов.
1. В любом месте вы поместите идентификатор (или цепочку идентификаторов) как часть переменной или
имя подпрограммы, вы можете заменить идентификатор простой скалярной переменной
содержащий ссылку правильного типа:
$ bar = $$ scalarref;
push (@ $ arrayref, $ filename);
$$ arrayref [0] = «Январь»;
$$ hashref {"КЛЮЧ"} = "ЗНАЧЕНИЕ";
& $ coderef (1,2,3);
print $ globref "output \ n";
Важно понимать, что мы конкретно разыменование $ arrayref [0]
или $ hashref {"KEY"} там. Разыменование скалярной переменной происходит до it
выполняет поиск по ключевым словам. Все, что сложнее простой скалярной переменной, должно
используйте методы 2 или 3 ниже. Однако «простой скаляр» включает идентификатор, который
сам использует метод 1 рекурсивно. Поэтому следующие отпечатки «привет».
$ refrefref = \\\ "привет";
print $$$$ refrefref;
2. В любом месте вы поместите идентификатор (или цепочку идентификаторов) как часть переменной или
имя подпрограммы, вы можете заменить идентификатор на БЛОК, возвращающий ссылку на
правильный тип. Другими словами, предыдущие примеры можно было бы записать так:
$ bar = $ {$ scalarref};
push (@ {$ arrayref}, $ filename);
$ {$ arrayref} [0] = "Январь";
$ {$ hashref} {"КЛЮЧ"} = "ЗНАЧЕНИЕ";
& {$ coderef} (1,2,3);
$ globref-> print ("вывод \ п"); # iff IO :: Handle загружен
По общему признанию, использовать завитки в этом случае немного глупо, но БЛОК может
содержать любое произвольное выражение, в частности, выражения с индексами:
& {$ dispatch {$ index}} (1,2,3); # вызываем правильную процедуру
Из-за возможности опустить завитки в простом случае $$ x, люди часто
совершают ошибку, рассматривая символы разыменования как правильные операторы, и удивляются
об их приоритете. Если бы это было так, вы могли бы использовать круглые скобки вместо
подтяжки. Это не так. Обратите внимание на разницу ниже; case 0 - это сокращение
вариант кейса 1, 2 случае:
$$ hashref {"КЛЮЧ"} = "ЗНАЧЕНИЕ"; # СЛУЧАЙ 0
$ {$ hashref} {"КЛЮЧ"} = "ЗНАЧЕНИЕ"; # ДЕЛО 1
$ {$ hashref {"КЛЮЧ"}} = "ЗНАЧЕНИЕ"; # СЛУЧАЙ 2
$ {$ hashref -> {"КЛЮЧ"}} = "ЗНАЧЕНИЕ"; # СЛУЧАЙ 3
Случай 2 также обманчив, поскольку вы обращаетесь к переменной с именем% hashref, а не
разыменование через $ hashref на хэш, на который он предположительно ссылается. Это было бы
Дело 3.
3. Вызов подпрограмм и поиск отдельных элементов массива возникают достаточно часто, чтобы
становится неудобно использовать метод 2. В качестве синтаксического сахара примеры для
метод 2 можно записать:
$ arrayref -> [0] = "Январь"; # Элемент массива
$ hashref -> {"КЛЮЧ"} = "ЗНАЧЕНИЕ"; # Хэш-элемент
$ coderef -> (1,2,3); # Вызов подпрограммы
Левая сторона стрелки может быть любым выражением, возвращающим ссылку, включая
предыдущее разыменование. Обратите внимание, что $ array [$ x] - это то же, что и "$ array -> [$ x]"
здесь:
$ array [$ x] -> {"foo"} -> [0] = "Январь";
Это один из случаев, о которых мы упоминали ранее, когда ссылки могут возникать
существование в контексте lvalue. До этого оператора $ array [$ x] мог быть
неопределенный. Если это так, он автоматически определяется с помощью ссылки на хэш, чтобы мы могли
найдите в нем "{" foo "}". Аналогично "$ array [$ x] -> {" foo "}" автоматически получит
определяется ссылкой на массив, чтобы мы могли найти в нем "[0]". Этот процесс
которые называются автоживление.
И еще кое-что. Стрелка не обязательна между скобки нижние индексы, так что вы можете
сжать выше до
$ array [$ x] {"foo"} [0] = "Январь";
Что в вырожденном случае использования только обычных массивов дает вам
многомерные массивы, такие как C:
$ оценка [$ x] [$ y] [$ z] + = 42;
Ну да ладно, на самом деле не совсем как массивы C. C не знает, как вырастить
массивы по запросу. Perl делает.
4. Если ссылка является ссылкой на объект, то, вероятно, существуют методы.
чтобы получить доступ к упомянутым вещам, и вам, вероятно, следует придерживаться этих методов
если вы не находитесь в пакете классов, который определяет методы объекта. Другими словами,
будьте внимательны и не нарушайте инкапсуляцию объекта без уважительной причины.
Perl не требует инкапсуляции. Мы здесь не тоталитаристы. Мы действительно ожидаем
хотя бы немного вежливости.
Использование строки или числа в качестве ссылки дает символьную ссылку, как объяснено выше.
Использование ссылки в качестве числа дает целое число, представляющее его место хранения в
объем памяти. Единственное, что с этим можно сделать, это сравнить две ссылки.
численно, чтобы увидеть, относятся ли они к одному и тому же месту.
if ($ ref1 == $ ref2) {# дешевое числовое сравнение ссылок
print "ссылки 1 и 2 относятся к одному и тому же \ n";
}
Использование ссылки в виде строки дает как ее референтный тип, так и любой пакет
blessing, как описано в perlobj, а также числовой адрес, выраженный в шестнадцатеричном формате. В
ref () оператор возвращает только тип объекта, на который указывает ссылка, без
адрес. См. «Ref» в perlfunc для деталей и примеров его использования.
The благословить() может использоваться для связывания объекта, на который указывает ссылка, с
пакет, функционирующий как объектный класс. См. Perlobj.
Typeglob может быть разыменован так же, как и ссылка, потому что разыменование
синтаксис всегда указывает желаемый тип ссылки. Итак, "$ {* foo}" и "$ {\ $ foo}" оба
указывают на ту же скалярную переменную.
Вот трюк для интерполяции вызова подпрограммы в строку:
print "Моя подпрограмма вернула @ {[mysub (1,2,3)]} в тот раз. \ n";
Это работает так: когда "@ {...}" встречается в строке, заключенной в двойные кавычки, это означает, что
оценивается как блок. Блок создает ссылку на анонимный массив, содержащий
результаты вызова mysub (1,2,3). Таким образом, весь блок возвращает ссылку на
array, который затем разыменовывается с помощью "@ {...}" и вставляется в строку, заключенную в двойные кавычки.
Эта хитрость также полезна для произвольных выражений:
print "Это дает виджеты @ {[$ n + 5]} \ n";
Точно так же выражение, которое возвращает ссылку на скаляр, может быть разыменовано через
"$ {...}". Таким образом, приведенное выше выражение можно записать как:
print "Это дает $ {\ ($ n + 5)} виджетов \ n";
Круговой Рекомендации
В Perl можно создать «циклическую ссылку», что может привести к утечке памяти. А
круговая ссылка возникает, когда две ссылки содержат ссылку друг на друга, например
это:
мой $ foo = {};
мой $ bar = {foo => $ foo};
$ foo -> {bar} = $ bar;
Вы также можете создать круговую ссылку с одной переменной:
мой $ foo;
$ foo = \ $ foo;
В этом случае счетчик ссылок для переменных никогда не достигнет 0, а ссылки
никогда не будет собираться мусором. Это может привести к утечке памяти.
Поскольку объекты в Perl реализованы как ссылки, можно использовать циклические
также ссылки с объектами. Представьте себе класс TreeNode, где каждый узел ссылается на свой
родительские и дочерние узлы. Любой узел с родительским элементом будет частью круговой ссылки.
Вы можете разбить циклические ссылки, создав «слабую ссылку». Слабая ссылка делает
не увеличивать счетчик ссылок для переменной, что означает, что объект может исчезнуть
объема и быть уничтоженным. Вы можете ослабить ссылку с помощью экспортированной функции "ослабить"
модулем Scalar :: Util.
Вот как мы можем сделать первый пример более безопасным:
используйте Scalar :: Util 'weaken';
мой $ foo = {};
мой $ bar = {foo => $ foo};
$ foo -> {bar} = $ bar;
ослабить $ foo -> {bar};
Ссылка с $ foo на $ bar была ослаблена. Когда переменная $ bar выходит из
область, он будет собран сборщиком мусора. В следующий раз, когда вы посмотрите на значение
Клавиша "$ foo -> {bar}" будет "undef".
Это действие на расстоянии может сбивать с толку, поэтому будьте осторожны при использовании
ослабить. Вам следует ослабить ссылку в переменной, которая выйдет за пределы области видимости. первый.
Таким образом, долгоживущая переменная будет содержать ожидаемую ссылку, пока не исчезнет.
объема.
Символический Рекомендации
Мы сказали, что ссылки возникают по мере необходимости, если они не определены, но мы
не сказал, что произойдет, если значение, используемое в качестве ссылки, уже определено, но Не a
жесткая ссылка. Если вы используете его как ссылку, он будет рассматриваться как символическая ссылка.
То есть значение скаляра принимается равным имя переменной, а не
прямая ссылка на (возможно) анонимное значение.
Люди часто ожидают, что это будет работать именно так. Так оно и есть.
$ name = "foo";
$$ name = 1; # Устанавливает $ foo
$ {$ name} = 2; # Устанавливает $ foo
$ {$ имя x 2} = 3; # Устанавливает $ foofoo
$ name -> [0] = 4; # Устанавливает $ foo [0]
@ $ name = (); # Очищает @foo
& $ имя (); # Вызовы & foo ()
$ pack = "ТО";
$ {"$ {pack} :: $ name"} = 5; # Устанавливает $ THAT :: foo без eval
Это мощно и немного опасно тем, что можно умышленно (с максимальной
искренность), чтобы использовать жесткую ссылку и случайно использовать вместо нее символическую ссылку. К
защищайся от этого, можно сказать
используйте строгие ссылки;
и тогда для остальной части включающего блока будут разрешены только жесткие ссылки. An
внутренний блок может отменить это с помощью
никаких строгих референсов;
Для символьных ссылок видны только переменные пакета (глобальные, даже если они локализованы).
Лексические переменные (объявленные с мой()) не находятся в таблице символов и поэтому невидимы для
этот механизм. Например:
локальное значение $ = 10;
$ ref = "значение";
{
мое значение $ = 20;
print $$ ref;
}
Это все равно будет печатать 10, а не 20. Помните, что местный() влияет на переменные пакета, которые
все являются «глобальными» для пакета.
Не очень символично Рекомендации
Скобки вокруг символьной ссылки могут просто служить для выделения идентификатора или переменной.
имя из остальной части выражения, как всегда в строке. За
пример,
$ push = "поп";
напечатать "$ {push} over";
всегда означало напечатать «всплывающее окно», даже несмотря на то, что «толкать» - зарезервированное слово. Это
обобщены для работы без двойных кавычек, так что
напечатать $ {push}. "над";
и даже
напечатать $ {push}. "над";
будет иметь такой же эффект. Эта конструкция считается символической ссылкой
когда вы используете строгие ссылки:
используйте строгие ссылки;
$ {bareword}; # Хорошо, означает $ bareword.
$ {"голое слово"}; # Ошибка, символьная ссылка.
Точно так же, поскольку все индексы выполняются с использованием отдельных слов, то же правило
применяется к любому голому слову, которое используется для индексирования хэша. Итак, теперь вместо того, чтобы писать
$ array {"aaa"} {"bbb"} {"ccc"}
ты можешь написать просто
$ array {aaa} {bbb} {ccc}
и не беспокойтесь о том, являются ли индексы зарезервированными словами. В том редком случае, когда вы
хочу сделать что-то вроде
$ array {shift}
вы можете заставить интерпретацию как зарезервированное слово, добавив все, что делает его более чем
голое слово:
$ массив {shift ()}
$ array {+ shift}
$ массив {shift @_}
Прагма "использовать предупреждения" или -w switch предупредит вас, если он интерпретирует зарезервированное слово
в виде строки. Но он больше не будет предупреждать вас об использовании строчных слов, потому что
строка эффективно заключена в кавычки.
Псевдо-хеши: . an массив as a хэш
Псевдохеши были удалены из Perl. Прагма fields остается доступной.
Функция Шаблоны
Как объяснялось выше, анонимная функция с доступом к видимым лексическим переменным
когда эта функция была скомпилирована, создает закрытие. Он сохраняет доступ к этим переменным
даже если он не запускается позже, например, в обработчике сигнала или обратном вызове Tk.
Использование замыкания в качестве шаблона функции позволяет нам сгенерировать множество функций, которые действуют
так же. Предположим, вам нужны функции, названные в честь цветов, которые генерируют шрифт HTML.
изменения для различных цветов:
выведите «Будь», красный («осторожный»), «с этим», зеленый («светлый»);
The красный() и зеленый() функции были бы аналогичными. Чтобы создать их, мы назначим закрытие
в typeglob имени функции, которую мы пытаемся построить.
@colors = qw (красный синий зеленый желтый оранжевый фиолетовый фиолетовый);
для моего $ name (@colors) {
никаких строгих референсов; # разрешить манипуляции с таблицей символов
* $ name = * {uc $ name} = sub {" @_ "};
}
Теперь кажется, что все эти разные функции существуют независимо. Вы можете позвонить красный(),
КРАСНЫЙ(), синий(), СИНИЙ(), зеленый()и т. д. Этот метод экономит время компиляции и память.
use, а также менее подвержен ошибкам, поскольку проверки синтаксиса выполняются во время компиляции. Это
важно, чтобы любые переменные в анонимной подпрограмме были лексическими, чтобы создать
правильное закрытие. Это причины для "my" в переменной итерации цикла.
Это одно из немногих мест, где создание прототипа укупорочного средства имеет смысл. Если
вы хотели наложить скалярный контекст на аргументы этих функций (вероятно, не
мудрая идея для этого конкретного примера), вы могли бы написать так:
* $ name = sub ($) {" $ _ [0] "};
Однако, поскольку проверка прототипа происходит во время компиляции, вышеупомянутое присвоение происходит
слишком поздно, чтобы быть полезным. Вы можете решить эту проблему, поместив весь цикл
присваивания внутри блока BEGIN, заставляя это происходить во время компиляции.
Доступ к лексическим словам, которые меняются с течением времени - например, в цикле "for" выше, в основном
псевдонимы элементов из окружающих лексических областей - работает только с анонимными подпрограммами,
не с именованными подпрограммами. Как правило, именованные подпрограммы не размещаются должным образом и
следует объявлять только в области основного пакета.
Это связано с тем, что именованные подпрограммы создаются во время компиляции, поэтому их лексические переменные
присваиваются родительским лексическим элементам после первого выполнения родительского блока. Если
родительская область видимости вводится второй раз, ее лексика создается снова, а вложенная
сабы по-прежнему ссылаются на старые.
Анонимные подпрограммы захватывают каждый раз, когда вы выполняете "вспомогательный" оператор, так как они есть
создается на лету. Если вы привыкли использовать вложенные подпрограммы в другом программировании
языков со своими собственными частными переменными, вам придется немного поработать над этим в Perl. В
интуитивно понятное кодирование такого рода вещей вызывает загадочные предупреждения о том, что "не останется
общий "по причинам, описанным выше. Например, это не сработает:
sub external {
мой $ x = $ _ [0] + 35;
sub inner {return $ x * 19} # НЕПРАВИЛЬНО
вернуть $ x + inner ();
}
Обход следующий:
sub external {
мой $ x = $ _ [0] + 35;
местный * внутренний = суб {возврат $ х * 19};
вернуть $ x + inner ();
}
Теперь внутренний() можно вызвать только изнутри внешний (), из-за временных командировок
анонимной подпрограммы. Но когда это произойдет, у него будет нормальный доступ к лексической
переменная $ x из области видимости внешний () во время вызова external.
Это дает интересный эффект создания функции, локальной для другой функции,
что-то обычно не поддерживается в Perl.
ПРЕДУПРЕЖДЕНИЕ
Вы не можете (с пользой) использовать ссылку в качестве ключа к хешу. Он будет преобразован в
строка:
$ х {\ $ а} = $ а;
Если вы попытаетесь разыменовать ключ, это не приведет к жесткому разыменованию, и вы не будете
выполнить то, что вы пытаетесь. Вы могли бы захотеть сделать что-нибудь вроде
$ r = \ @a;
$ х {$ г} = $ г;
И тогда, по крайней мере, вы можете использовать значения(), которые будут настоящими рефами, а не
ключи (), чего не будет.
Стандартный модуль Tie :: RefHash предоставляет удобный способ решения этой проблемы.
постфикс разыменовывают Синтаксис
Начиная с v5.20.0, доступен постфиксный синтаксис для использования ссылок. Он ведет себя как
описано в «Использование ссылок», но вместо префикса сигилы постфиксный сигил-и-
звезда используется.
Например:
$ r = \ @a;
@b = $ r -> @ *; # эквивалент @ $ r или @ {$ r}
$ r = [1, [2, 3], 4];
$ r -> [1] -> @ *; # эквивалент @ {$ r -> [1]}
Этот синтаксис должен быть включен с помощью «использовать функцию 'postderef'». Это экспериментально и будет
предупреждать по умолчанию, если не действует "no warnings 'experimental :: postderef'".
Разыменование Postfix должно работать во всех случаях, когда разыменование блока (циркумфикса)
работал и должен быть полностью эквивалентен. Этот синтаксис позволяет писать разыменование
и читайте полностью слева направо. Определены следующие эквиваленты:
$ sref -> $ *; # то же, что и $ {$ sref}
$ aref -> @ *; # то же, что и @ {$ aref}
$ aref -> $ # *; # то же, что и $ # {$ aref}
$ href ->% *; # то же, что и% {$ href}
$ cref -> & *; # то же, что и & {$ cref}
$ gref -> **; # то же, что и * {$ gref}
Обратите особое внимание на то, что "$ cref -> & *" эквивалентно "$ cref -> ()" и может обслуживать разные
целей.
Элементы глобуса могут быть извлечены с помощью функции разыменования постфикса:
$ gref -> * {СКАЛЯР}; # то же, что * {$ gref} {SCALAR}
Постфиксный массив и скалярное разыменование использоваться при интерполяции строк (двойные кавычки
или оператор «qq»), но только если включена дополнительная функция «postderef_qq».
постфикс Референции нарезка
Срезы значений массивов и хэшей также могут быть взяты с постфиксной нотацией разыменования,
со следующими эквивалентами:
$ aref -> @ [...]; # то же, что и @ $ aref [...]
$ href -> @ {...}; # то же, что и @ $ href {...}
Нарезка пар ключ / значение Postfix, добавленная в 5.20.0 и задокументированная в хеш-коде ключа / значения
Раздел Slices perldata также ведет себя так, как ожидалось:
$ aref ->% [...]; # то же, что и% $ aref [...]
$ href ->% {...}; # то же, что и% $ href {...}
Как и в случае с массивом постфиксов, разыменование среза значения постфикса использоваться при интерполяции
строки (двойные кавычки или оператор "qq"), но только если дополнительный "postderef_qq"
функция включена.
Назначение в Рекомендации
Начиная с v5.22.0, оператор ссылки может быть назначен. Он выполняет
операция псевдонима, так что имя переменной, указанное в левой части, становится
псевдоним для объекта, указанного справа:
\ $ a = \ $ b; # $ a и $ b теперь указывают на один и тот же скаляр
\ & foo = \ & bar; # foo () теперь означает bar ()
Этот синтаксис должен быть включен с помощью «использовать функцию 'refaliasing'». Это экспериментально, и
будет предупреждать по умолчанию, если не действует «no warnings 'experimental :: refaliasing'».
Эти формы могут быть присвоены, и правая часть будет вычислена в скалярной форме.
контекст:
\ $ скаляр
\@множество
\% хэш
\ & sub
\ мой $ скаляр
\ мой @ массив
\ мой% хэш
\ state $ scalar # или @array и т. д.
\ наш $ scalar # и т. д.
\ local $ scalar # и т. д.
\ local наш $ скаляр # и т. д.
\ $ some_array [$ индекс]
\ $ some_hash {$ ключ}
\ local $ some_array [$ index]
\ local $ some_hash {$ ключ}
состояние ? \ $ this: \ $ that [0] # и т. д.
Операции нарезки и круглые скобки приводят к тому, что правая часть оценивается в списке
контекст:
\ @array [5..7]
(\ @array [5..7])
\ (@ массив [5..7])
\ @hash {'foo', 'bar'}
(\ @hash {'foo', 'bar'})
\ (@ hash {'foo', 'bar'})
(\ $ скаляр)
\ ($ скаляр)
\ (мой $ скаляр)
\ my ($ скаляр)
(\@множество)
(\% хэш)
(\ & sub)
\ (& sub)
\ ($ foo, @bar,% baz)
(\ $ foo, \ @bar, \% baz)
Каждый элемент с правой стороны должен быть ссылкой на датум правильного типа.
Круглые скобки, непосредственно окружающие массив (и, возможно, также
"мое" / "состояние" / "наш" / "локальный") сделает каждый элемент массива псевдонимом для
соответствующий скаляр, указанный в правой части:
\ (@ a) = \ (@ b); # @a и @b теперь имеют одинаковые элементы
\ мой (@a) = \ (@ b); # так же
\ (мой @a) = \ (@ b); # так же
нажмите @a, 3; # но теперь в @a есть лишний элемент, которого нет в @b
\ (@ a) = (\ $ a, \ $ b, \ $ c); # @a теперь содержит $ a, $ b и $ c
Комбинируя эту форму с "local" и помещая круглые скобки непосредственно вокруг хеша,
запрещено (потому что непонятно, что им делать):
\ local (@array) = foo (); # НЕПРАВИЛЬНЫЙ
\ (% hash) = bar (); # неправильный
Отнесения к ссылкам и не-ссылки могут быть объединены в списки и условные
тернарные выражения, пока значения в правой части являются правильным типом для
каждый элемент слева, хотя это может привести к обфусцированию кода:
(мой $ tom, \ my $ dick, \ my @harry) = (\ 1, \ 2, [1..3]);
# $ tom сейчас \ 1
# $ dick теперь 2 (только для чтения)
# @harry - это (1,2,3)
мой $ type = ref $ thingy;
($ type? $ type == 'ARRAY'? \ @foo: \ $ bar: $ baz) = $ thingy;
Цикл "foreach" также может принимать ссылочный конструктор для своей переменной цикла, хотя
синтаксис ограничен одним из следующих, с необязательным "my", "state" или "our" после
обратная косая черта:
\ $ s
\ @a
\%час
\ & c
Скобки не допускаются. Эта функция особенно полезна для массивов массивов,
или массивы хэшей:
foreach \ my @a (@array_of_arrays) {
frobnicate ($ a [0], $ a [-1]);
}
foreach \ my% h (@array_of_hashes) {
$ h {gelastic} ++, если $ h {type} == 'смешно';
}
ПРЕДОСТЕРЕЖЕНИЕ: Псевдонимы некорректно работают с замыканиями. Если вы попытаетесь использовать псевдоним лексический
переменных из внутренней подпрограммы или "eval", алиасинг будет виден только внутри
эта внутренняя подпрограмма и не повлияет на внешнюю подпрограмму, в которой объявлены переменные.
Это странное поведение может измениться.
Используйте perlref онлайн с помощью сервисов onworks.net