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

2023-12-20

我有以下 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 找到如文件::查找 https://perldoc.perl.org/File::Find


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

此外,这会产生一个问题,因为“内部”子例程应该关闭变量@xml_files它使用的,在每次新调用时都会重新定义,是词法的。但是 sub 是在编译时构建的,而不是词法闭包,只保留对第一次调用时的值的引用,因此它仅在第一次调用外部 sub 时才能正常工作(merge_xml here).

不过我们确实收到了警告。和use diagnostics;(或者看到它在 perldiag 中 https://perldoc.perl.org/perldiag#Variable-%22%25s%22-will-not-stay-shared)

变量“$x”不会在 -e 第 1 行 (#1) 保持共享
(W 闭包)内部(嵌套)命名子例程引用 在外部命名子例程中定义的词法变量。

当调用内部子程序时,它会看到 外部子例程的变量在之前和期间first调用外部子程序;在这种情况下,在第一次调用之后 外部子程序完成后,内部和外部子程序将不再存在 不再共享变量的共同值。换句话说, 变量将不再被共享。

这个问题通常可以通过编写内部子程序来解决 匿名,使用 sub {} 语法。当内部匿名订阅者 创建外部子程序中的引用变量,它们 会自动反弹到此类变量的当前值。

所以拉出那个“内部”子(match_xml)并从“外部”正常使用它(merge_xml)。一般来说,您将传递对数组的引用(@xml_files) 到它;或者,因为在这种情况下无法传递到File::Find's find,可以将数组置于这样的范围内,以便根据需要进行查看。

或者说,既然目的是match_xmlfind 的“想要的”功能 https://perldoc.perl.org/File::Find#The-wanted-function,可以为此目的使用匿名子程序,因此不需要单独的命名子程序

find( sub { ... }, @dirs );

或者将该 coderef 存储在变量中,如下所示艾德·希尔的回答 https://stackoverflow.com/a/65174755/4653379

my $wanted_coderef = sub { ... };
find( $wanted_coderef, @dirs );
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获取变量“@xml_files”不会在...行保持共享 的相关文章

随机推荐