为什么使用三元运算符会出现语法错误?

时间:2013-10-29 23:00:02

标签: ruby ternary-operator

我写了一个if-then-else程序,但在更改代码以使用三元运算符时,我收到语法错误,无法弄清楚它为什么不起作用:

def are_you_over_21
  puts"How old are you?"
  age = gets.chomp.to_i
  age>=21 ? puts"You're over 21!" : puts"You're too young."
end

are_you_over_21

3 个答案:

答案 0 :(得分:13)

你必须考虑Ruby解析器。

这样可以正常工作:

age >= 21 ? puts("You're over 21!") : puts("You're too young.")

原因是如果你使用不带括号的puts方法,解析器就不会理解之后出现的:令牌;它没有意识到它早先与三元运算符相关联。你也可以这样做:

puts age >= 21 ? "You're over 21!" : "You're too young."

这没关系 - 解析器不会遇到任何含糊之处。

你也可以这样做:

puts "You're #{ age >= 21 ? 'over 21!' : 'too young.' }"

这就是歧义发生的原因。假设您有两个函数xa,如下所示:

2.0.0-p195 :033 > def x(y)
2.0.0-p195 :034?>   y + 1
2.0.0-p195 :035?>   end
 => nil 
2.0.0-p195 :036 > def a(b)
2.0.0-p195 :037?>   b + 2
2.0.0-p195 :038?>   end
 => nil 

括号在这里没有区别:

2.0.0-p195 :039 > x a 1
 => 4 
2.0.0-p195 :040 > x a(1)
 => 4 
2.0.0-p195 :041 > x(a(1))
 => 4 
2.0.0-p195 :042 > x(a 1)
 => 4 

但如果x可以使用多个参数?现在你必须帮助解析器:

2.0.0-p195 :043 > def x(y, z)
2.0.0-p195 :044?>   y + z + 1
2.0.0-p195 :045?>   end

让我们像以前一样打个电话:

2.0.0-p195 :047 > x a 1, 2 

您是否将a(1), 2传递给x,或者您是否打算致电a(1, 2)并将结果传递给x?按照惯例,Ruby假设您尝试调用a(1, 2),但a只接受一个参数,因此您会收到错误:

ArgumentError: wrong number of arguments (2 for 1)
  from (irb):36:in `a'

所以你需要括号:

2.0.0-p195 :052 > x a(1), 2
 => 6 

答案 1 :(得分:5)

试试这个:

age>=21 ? puts("You're over 21!") : puts("You're too young.")

当给定选项没有括号的函数调用时,三元运算符会感到困惑。

你也可以这样做:

puts age>=21 ? "You're over 21!" : "You're too young."

答案 2 :(得分:1)

比在三元组中做无条件puts更好,这是一个条件语句,为什么不puts三元组的结果呢?

def are_you_over_21                                
  puts"How old are you?"                           
  age = gets.to_i                                  
  age >= 21 ? "You're over 21!" : "You're too young."
end                                                

puts are_you_over_21 

此外,它不是错误,但数字的性质(在您的情况下为整数)意味着它永远不需要chomp,因为数字没有新行。您永远不需要使用chomp.to_ichomp.to_f

请注意,该方法现在返回String的实例,而不是nil。在这种情况下,现在可以使用puts显示终端。

比较运算符周围的空格使其更易于阅读。

如果要提示,获取数据和报告,方法本身也可能不是一种方法。你也可以删除方法定义,并将其作为运行代码。

我已经重构了这个:

def are_you_over_21(age)
  age >= 21 ? "You're over 21!" : "You're too young."
end

[18, 20, 21, 22, 100].each do |age|
  puts are_you_over_21(age)
end

# >> You're too young.
# >> You're too young.
# >> You're over 21!
# >> You're over 21!
# >> You're over 21!

希望有所帮助。