Как я могу локализовать переменные Perl в другом фрейме стека?

StackOverflow https://stackoverflow.com/questions/200578

  •  03-07-2019
  •  | 
  •  

Вопрос

У меня есть некоторый автоматически сгенерированный код, который эффективно записывает следующее в нескольких разных местах некоторого кода:

no warnings 'uninitialized';
local %ENV = %ENV;
local $/   = $/;
local @INC = @INC;
local %INC = %INC;
local $_   = $_;
local $|   = $|;
local %SIG = %SIG;
use warnings 'uninitialized';

При автоматической генерации кода некоторые утверждают, что нет строгой необходимости в том, чтобы код был "красивым", но я бы хотел перенести это в подпрограмму.Однако это позволило бы локализовать эти переменные в этой подпрограмме.Есть ли способ локализовать эти переменные в вызывающем фрейме стека?

Обновить:В аналогичном ключе было бы неплохо иметь возможность запускать eval в более высоком фрейме стека.Я думаю, что у Python это уже есть.Было бы неплохо, если бы Perl тоже это сделал.

Это было полезно?

Решение

Возможно, вы можете организовать, чтобы код, использующий эти локальные файлы, генерировался в качестве замыкания?Тогда вы могли бы

sub run_with_env {
    my ($sub, @args) = @_;
    no warnings 'uninitialized';
    local %ENV = %ENV;
    local $/   = $/;
    local @INC = @INC;
    local %INC = %INC;
    local $_   = $_;
    local $|   = $|;
    local %SIG = %SIG;
    use warnings 'uninitialized';  
    $sub->(@args);
}

run_with_env(sub {
    # do stuff here
});

run_with_env(sub {
    # do different stuff here
});

Другие советы

Не уверен, почему QuantumPete отвергают, но, похоже, в этом он прав.Ты не можешь сказать наверняка local для инициализации переменных в вызывающем блоке.Его функциональность особенная, и инициализация / демонтаж, которые он выполняет, работает только в том блоке, где он был запущен.

Есть несколько экспериментальных модулей, таких как Sub:: Верхний уровень и Разработка::runBlock которые позволяют вам пытаться "обмануть" caller() для подпрограмм или выполнять "возврат длинных переходов" значений в более высокие кадры стека (соответственно), но ни один из них ничего не делает, чтобы повлиять на то, как local обрабатывает переменные (я пробовал.:)

Так что на данный момент, похоже, вам действительно придется жить с локальными объявлениями в той области, где они вам нужны.

Я не очень хорошо знаком с Perl, так что простите меня, если это действительно возможно.Но обычно переменные, локальные для фрейма стека, доступны только внутри этого фрейма стека.Вы не можете получить к ним доступ ни с более высокого, ни с более низкого уровня (если только вы не выполните какую-нибудь хакерскую арифметику указателей, но это никогда не гарантирует успеха).К сожалению, вам придется жить с большими блоками объявлений переменных.

Количественный скачок

perldoc перлгутс говорит:

   The "Alias" module implements localization of the basic types within
   the caller's scope.  People who are interested in how to localize
   things in the containing scope should take a look there too.

Фу-у-у.Я недостаточно внимательно изучал Alias.pm, чтобы понять, насколько это может быть просто.

В TCL вы можете использовать верхний уровень.Что касается Perl, я не знаю.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top