Perl 修复此警告的正确方法是什么?

Perl 修复此警告的正确方法是什么?,perl,Perl,我正试着用这个。(Perl版本)但是,当我尝试使用推荐的命令Perl-bin/SWOG.pl--input=examples/simple.SWOG--toPng=simple运行它时,它会显示以下警告(添加use diagnostics,希望它能对如何修复它有所帮助) 变量“$np”将不会在(重新评估8)第2行(#1)中共享。 (W闭包)内部(嵌套)命名子例程正在引用 在外部命名子例程中定义的词法变量 当调用内部子例程时,它将看到 外部子例程的变量在第一次 调用外部子例程;在这种情况下,在第一

我正试着用这个。(Perl版本)但是,当我尝试使用推荐的命令
Perl-bin/SWOG.pl--input=examples/simple.SWOG--toPng=simple
运行它时,它会显示以下警告(添加
use diagnostics
,希望它能对如何修复它有所帮助)

变量“$np”将不会在(重新评估8)第2行(#1)中共享。

(W闭包)内部(嵌套)命名子例程正在引用 在外部命名子例程中定义的词法变量

当调用内部子例程时,它将看到 外部子例程的变量在第一次 调用外部子例程;在这种情况下,在第一次调用 外部子例程完成后,内部子例程和外部子例程将不再显示 更长时间共享变量的公共值。换句话说 变量将不再被共享

这个问题通常可以通过制作内部子程序来解决 匿名,使用sub{}语法。当内部匿名潜艇 创建外部子例程中的引用变量时 自动恢复到此类变量的当前值

sub f {
   local our $np;
   $np = qr/...(??{ $np }).../;
   ... /$np/ ...
}
我已经对谷歌做了尽职调查,但仍然不知道如何将其应用到我的案例中

我还回到了导致此问题的代码段的开头。下面再次生成代码段,以便于参考:

    # parentheses balance pattern
    # @ http://www.unix.org.ua/orelly/perl/prog3/ch05_10.htm
    $np= qr{
       \(
       (
       (?:
          (?> [^()]+ )    # Non-parens without backtracking
        |
          (??{ $np })     # Group with matching parens
       )*
       )                    
       \)
    }x;
我认为,在同一变量
$np
的定义中嵌套的
$np
导致了此警告


请帮忙。谢谢

你有

sub f {
   my $np;
   $np = qr/...(??{ $np }).../;
}
(??{…})
在编译模式时捕获其中的词法

在您的例子中,因为模式是常量,所以当编译
qr/
本身时,就会编译
qr/
中的正则表达式模式。不幸的是,每次函数运行时都会创建一个新的
$np

您可以通过避免使用词汇变量来解决此问题

sub f {
   local our $np;
   $np = qr/...(??{ $np }).../;
   ... /$np/ ...
}
或者,在执行qr//时,通过使模式变为变量,强制编译regex模式

sub f {
   my $var = '';
   my $np;
   $np = qr/...(??{ $np })...$var/;
   ... /$np/ ...
}
但是为什么要重复执行
qr/
以获得恒定的模式呢?最好的解决方案是将图案移出子对象

my $np;
$np = qr/...(??{ $np }).../;

sub f {
   ... /$np/ ...
}

您的第一个建议是使用
local-our
而不是
my
有效。然而,我似乎无法让你的下一个建议修复工作。原始形式是
$np=qr{…(?{$np})…}x
,包装在一个
子解析树{}
——我应该把它改成什么?是
$np=qr{…}x中的尾随
x
相当于$var?不,关键是要使模式变为非常量,以防止只编译一次。所有这些修复都是不必要的复杂:为了实现递归,
(?{$np})
可以替换为
(?R)
(?0)
@amon,第二个注意,
(?R)
(?0)
递归整个模式,但这是一个子模式。可能不知道正确的号码。