我有以下代码:(对于这个问题的目的非常简化,但完美地说明了我遇到的问题)
#!/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.
我完全忽略了什么吗?我无法理解或弄清楚这个问题是什么。
答案 0 :(得分: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." }
答案 1 :(得分:5)
我认为你在这里尝试做的是为变量$connected_sub
分配一个匿名子。这不是一个好方法。
您正在做的是获取一个空变量,尝试将其用作代码引用,为其分配代码引用,然后退出sub和然后使用{{1}声明变量}。不是最好的做事顺序。
您可能想要做的是返回一个可以分配给变量的值,如下所示:
my
我认为在子程序中使用词法变量有点令人困惑。除了使用全局变量的一般缺点之外,子例程也在代码执行和声明变量之前编译。
此外,在调用子程序时,标准的方法是
my $connected = outer();
$connected->();
sub outer {
print "HELLO\n";
my $sub = sub { print "GOODBYE\n"; }
return $sub;
}
name(@args);
是你的参数列表。使用@args
是旧式perl,使用它具有特殊含义(覆盖原型)。在变量中使用匿名子时,请使用&
表示法。
答案 2 :(得分: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;
}
答案 3 :(得分:2)
在初始化之前,您似乎正在使用$connected_stub
。尝试移动初始化,例如:
$connected_sub = sub {
print "GOODBYE\n";
}
&$connected_sub;