【问题标题】:Perl Anonymous Subroutine/Function errorPerl 匿名子程序/函数错误
【发布时间】:2013-02-21 13:02:07
【问题描述】:

我有以下一段代码:(为了这个问题的目的非常简化,但完美地说明了我遇到的问题)

#!/usr/bin/perl

use strict;
use warnings;

&outer;
my $connected_sub;

sub outer {
    print "HELLO\n";

    &$connected_sub;
    $connected_sub = sub {
        print "GOODBYE\n";
    }
}

程序运行时会给出以下输出和错误:

HELLO
Use of uninitialized value in subroutine entry at subTesting line 13.
Can't use string ("") as a subroutine ref while "strict refs" in use at subTesting.pl line 13.

我在这里完全忽略了什么吗?我无法理解或弄清楚这是什么问题。

【问题讨论】:

  • &outer; 有一个非常特殊的含义(甚至比&outer() 更特殊)。不要那样做。使用outer()
  • 请将粗体字的使用限制在非常重要的事情上。没有人喜欢一直被大喊大叫。
  • @darch - 好吧,我发现当事物被明确分开/或标题时更容易阅读和理解,这就是我这样做的原因,但我很欣赏其他人可能不会,所以我会忍受记住,谢谢

标签: perl nested anonymous-function anonymous subroutine


【解决方案1】:

澄清一下:

子程序定义发生在编译阶段。因此,这样的代码将起作用:

foo();

sub foo { print "No need to declare me before calling!"; }

赋值直到调用那行代码才真正发生。这就是为什么这不起作用:

my $foo;

&$foo();

$foo = sub { print "Foo hasn't been set to me when you try to call me." }

【讨论】:

    【解决方案2】:

    我假设您在这里尝试做的是为变量$connected_sub 分配一个匿名子。这不是一个好方法。

    您正在做的是获取一个空变量,尝试将其用作代码引用,为其分配代码引用,然后退出子程序并然后使用my 声明该变量。不是最好的做事顺序。

    您可能想要做的是返回一个可以分配给变量的值,如下所示:

    my $connected = outer();
    $connected->();
    
    sub outer {
        print "HELLO\n";
        my $sub = sub { print "GOODBYE\n"; }
        return $sub;
    }
    

    我认为在子例程中使用词法变量有点令人困惑。除了使用全局变量的一般缺点外,子程序还在代码执行和变量声明之前编译。

    另外,当调用一个子程序时,这样做的标准方式是

    name(@args);
    

    @args 是您的参数列表。使用& 是旧式perl,使用它有特殊意义(覆盖原型)。在变量中使用匿名子时,请使用 ->() 表示法。

    【讨论】:

    • 感谢您将->() 与匿名子例程一起使用,以后会记住这一点
    • 实际上,声明发生在编译时。 初始化发生在运行时。是的,这意味着my $x = 5; 同时具有编译时和运行时效果。
    【解决方案3】:

    $connected_sub 未初始化。尝试分配给匿名子:

    my $connected_sub = sub {
       print "The code you need to run\n";
    }
    

    在定义处,并在 &$connected_sub 调用之后删除代码

    这是修改后的完整示例:

    #!/usr/bin/perl
    use strict;
    use warnings;
    
    
    my $connected_sub = sub {
       print "GOODBYE\n";
    };
    
    &outer;
    
    sub outer
    {
            print "HELLO\n";
            &$connected_sub;
     } 
    

    【讨论】:

      【解决方案4】:

      看起来您在初始化之前正在使用$connected_stub。尝试将初始化向上移动,例如:

          $connected_sub = sub {
          print "GOODBYE\n";
      
          }
          &$connected_sub;
      

      【讨论】:

        猜你喜欢
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-07
        • 1970-01-01
        相关资源
        最近更新 更多