perl – 使用Sub :: Quote弱化捕获
发布时间:2020-12-15 21:44:36 所属栏目:大数据 来源:网络整理
导读:我想削弱 Sub::Quote生成的代码中的捕获变量.例如,这里是未引用的替代方法: use 5.10.0;use Scalar::Util qw[ weaken ];{ my $s = 'foo'; my $x = sub { say $s }; weaken( my $y = $x ); my $bar = sub { $y }; $bar; $x = undef; $bar} 和输出: fooCan't
我想削弱
Sub::Quote生成的代码中的捕获变量.例如,这里是未引用的替代方法:
use 5.10.0; use Scalar::Util qw[ weaken ]; { my $s = 'foo'; my $x = sub { say $s }; weaken( my $y = $x ); my $bar = sub { &$y }; &$bar; $x = undef; &$bar } 和输出: foo Can't use an undefined value as a subroutine reference [...] 这是我的Sub :: Quote尝试: use 5.10.0; use Sub::Quote; use Scalar::Util qw[ weaken ]; { my $s = 'foo'; my $x = sub { say $s }; weaken( my $y = $x ); my $bar = quote_sub( '&$y',{ '$y' => $y } ); &$bar; $x = undef; &$bar; } 和输出: foo foo 显然,被捕获的$y并未被削弱.有没有办法改变生成的代码来削弱捕获的变量? 文档很稀疏,Sub :: Quote实现很复杂;我相信当前的代码是不可能的,但我希望被证明是错的. 解决方法my $bar = quote_sub( '&$y',{ '$y' => $y } ); 大致相同 my $bar = eval(q{ my $y = $y; sub { &$y } }); (它做得更多,但这些位与这个问题无关).如您所见,这为sub [1]创建了一个新的强引用. 作为一种解决方法,您可以添加一个间接层: my $bar = eval(q{ my $y_ref = $y; sub { &{ $$y_ref } } }); 这可以通过使用: my $bar = quote_sub( '&{$$y_ref}',{ '$y_ref' => $y } ); 如果Sub :: Quote创建的$y是$y的别名,则不会有任何问题.这可以使用Data :: Alias或5.22中引入的实验性功能来实现. 这可以通过以下方式证明: { package Sub::Quote; my $sub = sub { my ($from,$captures,$indent) = @_; join( '',"use feature qw( refaliasing );n","no warnings qw( experimental::refaliasing );n",map { /^([@%$])/ or croak "capture key should start with @,% or $: $_"; (' ' x $indent).qq{my ${_} = ${1}{${from}->{${quotify $_}}};n}; } keys %$captures ) }; no warnings qw( redefine ); *capture_unroll = $sub; } my $bar = quote_sub( '&$y',{ '$y' => $y } ); 您可以与模块的维护者讨论添加一个会导致使用别名的选项. >当您创建(强或弱)引用的副本时,它是一个强大的参考. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |