热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

获取变量“@xml_files”不会在…行保持共享

我有以下 Perl 代码:sub merge_xml { foreach my $repository ('repo1', 'repo2') { my @xml_files; sub m

我有以下 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 在File::Find 中查找

回答


“嵌套”命名的子程序实际上不是——它们被编译为单独的子例程,因此将它们编写为“嵌套”只会产生误导。

此外,这会产生一个问题,因为“内部”子例程应该关闭@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 { ... }, @dirs );

或者将该 coderef 存储在一个变量中,如Ed Heal 的回答所示

my $wanted_coderef = sub { ... };
find( $wanted_coderef, @dirs );






推荐阅读
author-avatar
李金铃519
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有