在下面的代码块中我收到此错误
Variable "$host" is not available at /comp/xx.pm line 404.
其中404行是代码块中的最后一行。
问题
我猜这是Capture
模块正在弄乱if (defined $host) { ...
,但我该如何解决这个问题?
use Capture::Tiny 'capture';
my $host = $::c{slaves}{$id} if (defined $id);
my ($stdout, $stderr, $exit) = capture {
if (defined $host) {
print "---delete $snap on host\n";
} else {
print "----delete $snap on master\n";
}
}; # line 404
更新
如果我评论第capture
行及其右括号,则会执行预期的print
行。
答案 0 :(得分:6)
问题在于这一行:
my $host = $::c{slaves}{$id} if (defined $id);
Perl目前不支持使用my $x = value if condition
。它有点工作,但有奇怪的角落案件。这是一个。
从变量声明中分离赋值:
my $host;
$host = $::c{slaves}{$id} if (defined $id);
您可以在the documentation for the related warning中阅读更多详情。
答案 1 :(得分:5)
有关说明,请参阅perldiag:
Variable "%s" is not available (W closure)
在编译期间,内部命名子例程或eval正在尝试捕获不是的外部词法 目前可用。出现这种情况的原因有两个。首先,外部词法可以在外部声明 尚未创建的匿名子例程。 (请记住,命名的subs是在编译时创建的,而匿名的subs是 在运行时创建。)例如,
sub { my $a; sub f { $a } }
在创建f时,它无法捕获$ a的当前值,因为匿名子例程尚未创建 然而。相反,以下不会发出警告,因为匿名子程序现在已经创建并且是实时的:
sub { my $a; eval 'sub f { $a }' }->();
第二种情况是由eval访问超出范围的变量引起的,例如
sub f { my $a; sub { eval '$a' } } f()->();
这里,当' $ a'在编译eval时,f()当前没有被执行,所以它的$ a不能用于捕获。