perl - 在 Continue 块中使用 For 循环中声明的词法变量
问题描述
我无法让我的一个模块编译看起来是一个变量范围问题,但我不明白为什么。
示例代码:
PATH: foreach my $path (@paths) {
open(my $file, '<', $path) or next PATH;
my %properties;
LINE: while (<$file>) {
$_ =~ /$property_regex/ or next LINE;
$properties{$1} = $2;
}
foreach (@property_keys) {
unless ($properties{$_}) {
# do stuff
next PATH;
}
if ( $irrelevant_condition ) {
# do stuff
next PATH;
}
foreach my $new_var (@new_list) {
# do stuff (does not iterate PATH loop)
}
} continue {
if (defined $file) { close($file) or die; }
}
转换为上面的精简代码,我得到的错误是:
全局符号“$file”在第 25 行需要明确的包名
也就是说,它似乎在抱怨底部块中的$file
使用。continue
如您所见,$file
在第 2 行中,在外部 foreach 循环(标记为 PATH)内将其声明为词法变量。
但是,基于perldoc for continue,我希望$file
仍在范围内:
[...] 它总是在条件即将被再次评估之前执行,就像 C 中 for 循环的第三部分一样。因此它可以用来增加循环变量,即使循环已经继续[...]
为了能够增加循环变量,是否将 continue 块视为与其所附加的循环相同的词法范围的一部分?
我错过了什么?
注意:这个模块是一个 Moo 类,所以虽然我在任何地方都没有明确的use strict
声明,但当你使用 Moo 时,我们启用了 strict 和 warnings。
解决方案
您的$path
变量仍在 内的范围内continue BLOCK
,但for
BLOCK 内的内容超出范围,因为您已经到达该 BLOCK 的末尾(您已经打到了大括号/退出了大括号)。但是,$path
变量不在大括号内,因此可以在大括号内可见continue BLOCK
(即使在大括号之外不可见)。
如果语法是这样的:
for (...)
{
$x = stuff();
continue { more_stuff($x) }
}
那么我希望$x
是可见的。IIRC,perl 6 有这样的东西,但在 perl 5 中,continue BLOCK
在循环块之外,因此看不到该块内的词法变量。
推荐阅读
- javascript - JavaScript 对象属性引用问题
- sharepoint-2013 - 添加 SharePoint 列表项,但不查看
- ios - UIBarButtonItem 标题文本对齐
- pact-jvm - 如何更新 pact jvm requestFilter 中的传入请求?
- php - 按用户实体参考视图过滤不起作用
- java - 应用性能监控工具 Spring Boot
- ios - Swift 闭包中“弱自我”的 Objective-C 等价物是什么?
- python - 无法安装 pip install ibm-db
- wpf - 拖放到可编辑的组合框上
- asp.net-identity - Identity Server 4 和保护内部保留角色