为什么要使用速记"如果"使用" include?"搜索子字符串时,语法不会评估

时间:2017-01-13 21:11:13

标签: ruby conditional-operator

我尝试使用简写来获得基于子字符串存在的响应,而不是预期的字符串响应,它被评估为" false。"在我的第二个更简单的例子中,打印了期望字符串。

#fails

puts "test".include? "s" ? "yep" : "nope" 

#SUCCESS

puts 1>2 ? "1 is greater than 2" : "1 is not greater than 2"

2 个答案:

答案 0 :(得分:6)

这是precedence问题。

解决方案

你需要:

puts "test".include?("s") ? "yep" : "nope"
#=> yep

为什么?

不带括号的方法调用介于优先级表中的defined?or之间,因此它低于三元运算符。这意味着

puts "test".include? "s" ? "yep" : "nope"

被解析为

puts "test".include?("s" ? "yep" : "nope")

puts "test".include?("yep")

false

警告

"s" ? "yep" : "nope"

显示警告:

warning: string literal in condition

因为三元运算符需要一个布尔值,而一个字符串总是很简单。

1> 2

这是有效的原因

puts 1>2 ? "1 is greater than 2" : "1 is not greater than 2"

是三元运算符的优先级高于puts:

puts ( 1>2 ? "1 is greater than 2" : "1 is not greater than 2" )

评估为:

puts ( "1 is not greater than 2" )

最后一个提示

当您遇到优先问题时,使用不带括号的puts可能会使问题变得更糟。您可以启动IRB并直接查看结果。

以下是一个例子:

# in a script :
puts [1,2,3].map do |i|
  i * 2
end
#=> #<Enumerator:0x0000000214d708>

使用IRB:

[1,2,3].map do |i|
  i * 2
end
# => [2, 4, 6]

答案 1 :(得分:2)

看起来ruby无法解析这个,因为你没有一点帮助。它认为你正在做

puts "test".include?("s" ? "yep" : "nope")

您需要在参数

周围使用(可选)parens
puts "test".include?("s") ? "yep" : "nope"

或强制将测试表达式解释为整体:

puts ("test".include?"s") ? "yep" : "nope"