4

我正在尝试使用这个工具。(Perl 版本)但是,当我尝试使用推荐的命令运行它时perl bin/SWOG.pl --input=examples/simple.swog --toPng=simple,它会显示以下警告(添加use diagnostics希望它可以阐明如何修复它)

Variable "$np" will not stay shared at (re_eval 8) line 2 (#1)

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

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

这个问题通常可以通过使用 sub {} 语法使内部子例程匿名来解决。当创建引用外部子例程中的变量的内部匿名子时,它们会自动重新绑定到此类变量的当前值。

我已经对 Google: link进行了尽职调查,但仍然不明白如何在我的情况下应用它。

我还回到了导致此问题的代码片段的来源。为了便于参考,下面再次生成了该片段:

    # 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导致了这个警告。

请帮忙。谢谢!

4

1 回答 1

5

你有类似的东西

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

(??{...})编译模式时捕获其中的词法。

在您的情况下,由于模式是常量,因此在qr//编译qr//自身时会编译 regex 模式。不幸的是,$np每次函数运行时都会创建一个新的。

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

sub f {
   local our $np;
   $np = qr/...(??{ $np }).../;
   ... /$np/ ...
}

或者通过将模式设置为变量来强制在执行 qr// 时编译正则表达式模式。

sub f {
   my $var = '';
   my $np;
   $np = qr/...(??{ $np })...$var/;
   ... /$np/ ...
}

但是为什么要qr//重复执行一个恒定的模式呢?最好的解决方案是将模式移出潜艇。

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

sub f {
   ... /$np/ ...
}
于 2013-10-18T16:21:08.407 回答