Хороший, плохой, злой лексического $ _ в Perl 5.10 +

Начиная в Perl 5.10, теперь возможно лексически определить объем переменной контекста $_, любой явно как my $_; или в a given / when создать.

Имеет любого найденного хорошим использованием лексического $_? Это делает какие-либо конструкции более простыми / более безопасный / быстрее?

Что относительно ситуаций, что это делает более сложным? Имеет лексическое $_ введенный какие-либо ошибки в Ваш код? (так как управляющие структуры та запись к $_ будет использовать лексическую версию, если это будет в объеме, это может изменить поведение кода, если это содержит какие-либо вызовы подпрограммы (из-за потери динамического контекста)),

В конце я хотел бы создать список, который разъясняет, когда использовать $_ как лексическое, как глобальное, или когда это не имеет значения вообще.


NB: с perl5-5.24 этими экспериментальными функциями больше не является часть жемчуга.

19
задан G. Cito 18 April 2016 в 15:37
поделиться

3 ответа

ИМО, из лексического $ _ следует извлечь одну замечательную вещь - это новый символ прототипа _ .

Это позволяет вам указать подпрограмму так, чтобы она принимала один скаляр или, если ничего не указано, захватывала $ _ .

Поэтому вместо того, чтобы писать:

sub foo {
    my $arg = @_ ? shift : $_;

    # Do stuff with $_
}

Я могу написать:

sub foo(_) {
    my $arg = shift;

    # Do stuff with $_ or first arg.
}

Небольшое изменение, но это намного проще, когда я хочу такое поведение. Удаление Boilerplate - это хорошо.

Конечно, это влияет на изменение прототипов нескольких встроенных функций (например, chr ), что может привести к поломке некоторого кода.

В целом я приветствую лексический $ _ . Это дает мне инструмент, который я могу использовать для ограничения случайного искажения данных и причудливых взаимодействий между функциями. Если я решу использовать $ _ в теле функции, путем лексикализации, я могу быть уверен, что какой бы код я ни вызвал, $ _ не будет изменен в вызывающем коде. .

Динамическая область видимости интересна, но по большей части мне нужна лексическая область видимости. Добавьте к этому сложности, связанные с $ _ . Я слышал ужасные предупреждения о нецелесообразности простого выполнения local $ _; - вместо этого лучше использовать для ($ foo) {} . Лексикализованный $ _ дает мне то, что я хочу в 99 случаях из 100, когда я локализовал $ _ любыми способами. Lexical $ _ делает большое удобство и удобочитаемость более надежной.

Основная часть моей работы была связана с Perl 5.8, поэтому я не имел удовольствия играть с лексическим $ _ в более крупных проектах.Тем не менее, похоже, что это во многом сделает использование $ _ более безопасным, и это хорошо.

8
ответ дан 30 November 2019 в 05:12
поделиться

Однажды я обнаружил проблему (ошибка была бы слишком сильным словом), которая возникла, когда я играл с Inline модулем. Этот простой скрипт:

use strict qw(vars subs);
for ('function') {
    $_->();
}
sub function {
  require Inline;
  Inline->bind(C => <<'__CODE__');
void foo() 
{
}
__CODE__
}

терпит неудачу с Попытка модификации значения, доступного только для чтения, в /usr/lib/perl5/site_perl/5.10/Inline/C.pm строка 380. сообщение об ошибке. Глубоко во внутренностях модуля Inline находится подпрограмма, которая хотела изменить $_, что привело к сообщению об ошибке выше.

Использование

for my $_ ('function') { ...

или иное объявление my $_ является приемлемым обходным решением этой проблемы.

(Модуль Inline был исправлен для устранения этой конкретной проблемы).

3
ответ дан 30 November 2019 в 05:12
поделиться

Здесь не было никаких проблем, хотя я склонен следовать некоторой политике «Не спрашивай, не говори», когда дело касается магии Perls. Т.е. от подпрограмм не обычно ожидается, что они будут полагаться на то, что их коллеги используют нелексические данные в качестве побочного эффекта, и не позволяют им.

Я тестировал код на различных версиях Perl 5.8 и 5.10, время от времени используя версию 5.6 с описанием Camel. Проблем не было. Большая часть моих вещей изначально была сделана для perl 5.8.8.

0
ответ дан 30 November 2019 в 05:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: