为什么变量不可用?

时间:2014-10-31 13:58:58

标签: perl

在下面的代码块中我收到此错误

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行。

2 个答案:

答案 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不能用于捕获。