2

I wrote an if-then-else program, but when changing the code to use the ternary operator I am getting a syntax error and cannot figure out why it will not work:

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
4

3 回答 3

13

您将不得不考虑 Ruby 解析器。

这将正常工作:

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

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

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

这很好——解析器在这里没有遇到任何歧义。

你也可以这样做:

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

这就是发生歧义的原因。假设你有两个函数,x并且a,像这样:

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), 2x,还是试图调用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 
于 2013-10-29T23:07:40.130 回答
5

尝试这个:

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

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

你也可以这样做:

puts age>=21 ? "You're over 21!" : "You're too young."
于 2013-10-29T23:07:28.307 回答
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 

此外,这不是错误,但数字的性质(在您的情况下为整数)意味着它永远不需要 a chomp,因为数字没有新行。你永远不需要使用chomp.to_ior chomp.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!

希望有帮助。

于 2013-10-30T02:51:52.420 回答