2016-11-23 68 views
1

嗨,我对Perl很陌生。我有一个包含子例程的Perl哈希。我试图用我在网上找到的各种方式运行它。但似乎没有任何工作。 我的代码:不能在子程序的哈希里面激活子程序perl

%hashfun = (

start=>sub { print 'hello' }, 
end=>sub { print 'bye' } 

); 

而且我尝试了以下多。

print "\n $hashfun{start} \n"; 

这导致以下输出:

CODE(<十六进制值>)

然后我试图

print "\n $hashfun{start}->() \n"; 

这导致以下

CODE(<十六进制值>) - >()

如何解决?

+5

您不能在字符串插值内运行coderef。 – simbabque

+1

另请参阅['perlop'](http://perldoc.perl.org/perlop.html#Quote-and-Quote-like-Operators)中的*“Quote and Quote-Like Operators”*以获取有关在字符串内插入。 –

+0

谢谢队友我会@HåkonHægland –

回答

7

你最后的尝试是正确的语法,但在错误的地方。您不能在字符串插值内运行代码。将它移到双引号""之外。

print "\n"; 
$hashfun{start}->(); 
print"\n"; 

print$hashfun{start}的实际调用是非常重要的,因为这将返回1。这是因为Perl中的sub总是返回sub中最后一条语句的返回值(可以是return)。这里是print。如果打印成功,print的返回值为1。所以print "\n", $hashfun{start}->(), "\n";将输出

 
hello 
1 


1)其实你可以,但你真的不应该。 print "\[email protected]{[&{$hashfun{start}}]}\n";将工作。这很神奇,你真的不应该那样做。

因为数组可以内插到字符串中,所以数组deref在双引号内起作用。 deref里面的东西正在运行,所以&$hashfun{start}(这是一种调用coderef的不同方式)运行。但是因为它返回1,这不是一个数组ref,我们需要将它包装在[]中,以便将它放入数组ref,然后解除引用。 请不要使用!

+0

是的,这是正确的答案。谢谢。当我应用此修复程序时,编号1显示在打印值后面。这是为什么?并以任何方式摆脱它。我的意思是我得到输出为'hello1'和'bye1' –

+0

@Ihsan我已经解释了'1'来自哪里。我实际上已经预计它会直接落后于文本,如果你看[答案的最初版本](http://stackoverflow.com/revisions/40762327/1),我已经这样做了。但在我的Perl 5.20.1上,它并没有这样做。我不知道为什么。它与评估东西的顺序有关。 'print'被调用,它有三个参数。第二个参数是代码ref,它可以运行。这是'打印'你好'。所以有输出。然后它返回传递给'print'的'1'。这两个''\ n“'也是...... – simbabque

+0

..传递给'print'。我不清楚参数列表是连接在一起并在内部打印,还是分别打印出来。这也可能受到'$ |'的影响,但我真的不知道。也许有更深入的内部知识的人会在后面解释。 – simbabque