我使用子调用作为另一个子的参数。示例代码:
test(isInString(), 'second parameter', 'third parameter');
sub test {
my ($boolean, $second, $third) = @_;
print "boolean: $boolean\n second: $second\n third: $third\n";
}
sub isInString {
my $searchFor = 'a';
my $searchIn = 'bcd';
return ($searchFor && $searchIn && ($searchIn =~ $searchFor));
}
在上面的例子中,我希望“isInString”中的return语句计算为false(''或undef或perl中的任何内容),这将作为参数#1传递给“Test”,你基本上已经
了Test(undef, 'second parameter', 'third parameter');
但事实并非如此。 isInString返回一个空数组,基本上你得到的是
Test('second parameter', 'third parameter');
从perl调试器中的isInString返回:
从main :: isInString返回列表上下文: 空数组
我假设这是一个perl上下文的东西,我可以先分配一个标量变量,它可以正常工作:
my $bool = isInString();
Test($bool, 'second parameter', 'third parameter');
调试器给出 - 标量上下文从main :: isInString返回:''
编辑我删除了所有具有相同结果的parens:
sub isInString {
my $searchFor = 'a';
my $searchIn = 'bcd';
return $searchFor && $searchIn && $searchIn =~ $searchFor;
}
调试器仍然给出:
从main :: isInString返回列表上下文: 空数组
有人可以解释为什么它会在这种情况下返回列表上下文/空数组吗?
答案 0 :(得分:7)
您的return
在列表上下文中进行评估,因为该函数是在列表上下文中调用的。布尔运算符(如&&
)执行而不是强制标量上下文。
引用perlop on &&
:
标量或列表上下文向下传播 如果是的话,到右边的操作数 评价。
由于匹配运算符在列表上下文中失败时返回一个空列表,这就是你得到的。如果要强制使用标量上下文,请在scalar
语句中或在调用函数时使用return
运算符。
此外,括号强制列表上下文(由其他一些答案建议)的想法是一种常见的误解。他们没有。列表上下文是默认值; 可以列出上下文的任何内容都是列表上下文。这就是为什么没有list
运算符与scalar
对应的原因。 parens“强制”列出上下文的一个地方是重复运算符。 'a' x 3
表示'aaa'
,但('a') x 3
表示('a', 'a', 'a')
。但这实际上不是强制列表上下文,它只是the x
operator的一个特例。
答案 1 :(得分:3)
如果要强制使用“布尔上下文”,可以使用双阴影“运算符”:!!
,如下所示:
test( !!isInString(), 'second parameter', 'third parameter' );
通过在参数列表中调用它,您已将其强制转换为“列表上下文”。你可以用这样的东西强制它。一次爆炸(!
)在布尔上下文中对其进行评估,并使其为1或''
。但既然你没有测试补充,而是价值本身,把另一个爆炸放在那里可以让你回到你想要的价值。
但是,因为从函数体中可以清楚地看到你返回一个布尔值,并且你在列表上下文中调用它(参数的列表是列表上下文),可能想在那里强制定义的值。像这样:
return ($searchFor && $searchIn && $searchIn =~ $searchFor) || 0;
任何undef
都会导致false值,它会跳转到或返回0,列表上下文不会忽略undef
。
答案 2 :(得分:0)
与您的问题无关,但index()
isInString()