1

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

#!/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.

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

4

4 回答 4

10

澄清:

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

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." }
于 2013-02-21T13:11:12.880 回答
5

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

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

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

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

sub outer {
    print "HELLO\n";
    my $sub = sub { print "GOODBYE\n"; }
    return $sub;
}

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

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

name(@args);

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

于 2013-02-21T13:13:01.853 回答
4

$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;
 } 
于 2013-02-21T13:05:04.900 回答
2

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

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

    }
    &$connected_sub;
于 2013-02-21T13:08:12.297 回答