perl - 获取变量“@xml_files”将不会在 ... 行保持共享
问题描述
我有以下 Perl 代码:
sub merge_xml {
foreach my $repository ('repo1', 'repo2') {
my @xml_files;
sub match_xml {
my $filename = $File::Find::dir . '/' . $_;
if ($filename =~ m%/(main|test)\.xml$%) {
push(@xml_files, $filename);
}
}
find(\&match_xml, $repository);
print Dumper(\@xml_files);
}
}
我收到警告:
Variable "@xml_files" will not stay shared at ./script/src/repair.pl line 87.
如何解决这个问题?
PS 查找文件::查找
解决方案
“嵌套”命名的子程序实际上不是——它们被编译为单独的子例程,因此将它们写为“嵌套”只会产生误导。
此外,这会产生一个问题,因为“内部”子例程应该关闭@xml_files
它使用的变量,该变量在每次新调用时都会重新定义,是词法的。但是 sub 在编译时构建并且不是词法闭包,仅在第一次调用时保留对值的引用,因此它仅在第一次正常工作。
我们确实收到了警告。和use diagnostics;
变量 "$x" 不会在 -e 第 1 行 (#1)
(W 闭包) 保持共享 内部(嵌套)命名子例程正在引用在外部命名子例程中定义的词法变量。当调用内部子程序时,它将看到外部子程序变量的值,就像它在第一次 调用外部子程序之前和期间一样;在这种情况下,在对外部子例程的第一次调用完成后,内部子例程和外部子例程将不再共享该变量的公共值。换句话说,变量将不再被共享。
这个问题通常可以通过使用 sub {} 语法使内部子例程匿名来解决。当创建引用外部子例程中的变量的内部匿名子时,它们会自动重新绑定到此类变量的当前值。
因此,拉出那个“内部”子(match_xml
)并从“外部”子( )正常使用它merge_xml
。通常,您会将对数组 ( @xml_files
) 的引用传递给它;或者,由于在这种情况下无法传递给File::Find
's find
,因此可以将数组放在这样的范围内,以便根据需要进行查看。
或者,由于 的目的match_xml
是成为find 的“通缉”功能,因此可以使用匿名 sub 来实现该目的,因此不需要单独的命名 sub
find( sub { ... }, @dirs );
或者将该 coderef 存储在一个变量中,如Ed Heal 的回答所示
my $wanted_coderef = sub { ... };
find( $wanted_coderef, @dirs );
推荐阅读
- python - Jupyter Notebook 上的 import librosa 命令问题
- matlab - Matlab 视频阅读器 - 在对象上绘制磁盘
- reactjs - 在我更新我的 mac OS 后,Watchman 不会让我启动任何我的 react native 项目
- python - 用python播放.wav文件的随机片段
- node.js - 如何从 ALB 中为 lambda 函数捕获事件并从中提取“主机”?
- xml - 将值列出到 xpath 中的多行
- c# - 如何配置两个 JSON 序列化器并根据路由选择正确的一个
- ios - 斯威夫特:为什么点击手势识别器不是每次都有效?
- visual-studio-2013 - Visual Studio 2013 数据集设计器刷新关系
- javascript - JavaScript:使用 jQuery 注入 CSS 代码