我无法理解,如果我取消注释返回行,那么输出将是"CODE",否则"SCALAR"..为什么会这样?
use strict;
sub test {
my ($abc,$grab) = @_;
print 'i m here';
print $abc;
## return []; if uncommented then output will be "REF" else "SCALAR"
}
my $pass= "i m good";
my %my_hash = ();
$my_hash{'fun'} = \&test($pass);
print ref($my_hash{'fun'})
Run Code Online (Sandbox Code Playgroud)
您没有参考函数.
当你写:
\&test($pass);
Run Code Online (Sandbox Code Playgroud)
这是一个函数调用(你有一个参数列表).
因此,test使用参数调用该函数$pass,然后引用返回的值(&除非您知道并特别希望它执行的操作,否则不应为函数调用添加前缀).
如果你想要引用test,你应该使用
$my_hash{'fun'} = \&test; ### (1)
Run Code Online (Sandbox Code Playgroud)
如果要引用test使用当前范围内的参数调用的函数,$pass则应使用:
$my_hash{'fun'} = sub { test($pass) }; ### (2)
Run Code Online (Sandbox Code Playgroud)
请注意,后者将在当前的范围变量中创建一个闭包$pass.要调用(1),请使用$my_hash{fun}->($some_arg).要调用(2),请使用$my_hash{fun}->().
在没有隐式的情况下return,子例程返回最后一个表达式的值.print成功时返回1,即标量.
\&test($pass)是相同的\ test($pass),即它评估对sub返回的值的引用test.如果它返回1 print,你将获得SCALAR,如果它返回[],你将获得REF,因为你有一个对数组的引用的引用.您也可以通过解除引用来验证它:
print ${ $my_hash{fun} }, ': ', ref $my_hash{fun}, "\n";
Run Code Online (Sandbox Code Playgroud)