gpt4 book ai didi

perl - eval 内出现词法变量为 "not available"的警告的原因是什么

转载 作者:行者123 更新时间:2023-12-02 03:04:22 24 4
gpt4 key购买 nike

eval语句位于词法变量的范围内时,该变量应该位于被求值 block 的词法上下文中。此外,词法变量应该在 subs 的词法上下文中可用。

但这不起作用:

use warnings;

{
package VLE;

my $ln10 = 2.302585092994045684017991454684;

sub reval {
say eval $_[0] if @_;
}
}

package VLE;

reval( q($ln10) );

结果是:

Variable "$ln10" is not available at (eval 1) line 1.

但是如果我(无用地)在 block 中的任何位置使用词法变量,它就会突然在 eval 中可用:

use warnings;

{
package VLE;

my $ln10 = 2.302585092994045684017991454684;

sub reval {
say eval $_[0] if @_;
my (undef) = $ln10;
return 0
}
}

package VLE;

reval( q($ln10) );

打印

2.30258509299405

为什么会发生这种情况?

编辑:

引用的破坏不是问题,因为此代码(维护对 $ln10 的引用)也会失败:

use warnings;

{
package VLE;

my $ln10 = 2.302585092994045684017991454684;

sub reval2 {
say eval $_[0] if @_;
my (undef) = $ln10;
return 0
}

sub reval {
say eval $_[0] if @_;
return 0
}
}

package VLE;

reval( q($ln10) ); # still fails
reval2( q($ln10) ); # works

最佳答案

子例程不会关闭(捕获)所有可见的词汇变量,而只会关闭(捕获)子例程体内引用的那些变量。这是引用计数正常工作的一个非常重要的部分。捕获哪些变量是在编译时确定的,并且在执行子例程定义时捕获变量(命名子程序的编译时,匿名子程序的运行时)。

此处您的第一个 reval 未捕获 $ln10 变量。因此,它在 eval 内部不可用。由于 eval 字符串是运行时值,因此在确定应捕获哪些变量时不能将其考虑在内。

更准确地说,当封闭 block 离开时,$ln10 变量将被销毁,因为不存在对其的进一步引用。所以这段代码可以工作,因为执行 eval 时 $ln10 变量仍然存在:

use warnings;
{
package VLE;
my $ln10 = 2.302585092994045684017991454684;

sub reval {
say eval $_[0] if @_;
}

reval(q($ln10));
# $ln10 variable exists until here
}

第二个 eval 确实捕获了变量,因此它的生命周期被延长,直到执行 eval 的时间点,并且一切都按预期工作。

关于perl - eval 内出现词法变量为 "not available"的警告的原因是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46589928/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com