Я натыкался на следующий шаблон несколько раз при разработке модулей Perl то использование AUTOLOAD
или другая подпрограмма диспетчеризирует методы:
sub AUTOLOAD {
my $self = $_[0];
my $code = $self->figure_out_code_ref( $AUTOLOAD );
goto &$code;
}
Это хорошо работает, и caller
видит корректный объем.
Теперь то, что я хотел бы сделать, должно локально установить $_
равный $self
во время выполнения &$code
. Который был бы чем-то вроде этого:
sub AUTOLOAD {
my $self = $_[0];
my $code = $self->figure_out_code_ref( $AUTOLOAD );
local *_ = \$self;
# and now the question is how to call &$code
# goto &$code; # wont work since local scope changes will
# be unrolled before the goto
# &$code; # will preserve the local, but caller will report an
# additional stack frame
}
Решения, которые включают обертывание caller
не приемлемы из-за проблем зависимости и производительности. Таким образом, это, кажется, исключает вторую опцию.
Пятясь к первому, единственный способ предотвратить новое значение $_
от выхода из объема во время goto
не должен был бы или локализовать изменение (не жизнеспособный вариант) или реализовать своего рода uplevel_local
или goto_with_local
.
Я играл вокруг со всеми видами вовлечения перестановок PadWalker
, Sub::Uplevel
, Scope::Upper
, B::Hooks::EndOfScope
и другие, но не смогли предложить надежное решение, которое моется $_
в нужное время, и не переносится caller
.
Кто-либо нашел шаблон, который работает в этом случае?
(ТАК вопрос: Как я могу локализовать переменные Perl в другом стековом фрейме? связан, но сохранение caller
не было требование, и в конечном счете ответ там должен был использовать другой подход, так, чтобы решение не было полезно в этом случае),