Perl匿名子例程/函数错误

per*_*ser 1 perl nested anonymous anonymous-function subroutine

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

#!/usr/bin/perl

use strict;
use warnings;

&outer;
my $connected_sub;

sub outer {
    print "HELLO\n";

    &$connected_sub;
    $connected_sub = sub {
        print "GOODBYE\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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.
Run Code Online (Sandbox Code Playgroud)

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

小智 10

澄清:

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

foo();

sub foo { print "No need to declare me before calling!"; }
Run Code Online (Sandbox Code Playgroud)

但是,在调用该行代码之前,实际上并不会发生赋值.这就是为什么这不起作用:

my $foo;

&$foo();

$foo = sub { print "Foo hasn't been set to me when you try to call me." }
Run Code Online (Sandbox Code Playgroud)


TLP*_*TLP 5

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

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

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

my $connected = outer();
$connected->();

sub outer {
    print "HELLO\n";
    my $sub = sub { print "GOODBYE\n"; }
    return $sub;
}
Run Code Online (Sandbox Code Playgroud)

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

此外,在调用子程序时,这样做的标准方法是

name(@args);
Run Code Online (Sandbox Code Playgroud)

@args你的论点列表在哪里?使用&旧样式perl,使用它具有特殊含义(覆盖原型).在变量中使用匿名子时,请使用->()表示法.