2

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
4

3 に答える 3

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.' }"

曖昧さが生じる理由はここにあります。次のように、xとの 2 つの関数があるとします。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), 2ていますか、それとも呼び出して結果を に渡そxうとしていますか? 慣例により、Ruby は を呼び出そうとしていると想定しますが、引数を 1 つしかとらないため、エラーが発生します。a(1, 2)xa(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

Better than doing the unconditional puts in the ternary, which is a conditional statement, why not puts the result of the ternary?

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 

Also, it isn't an error, but the nature of a number (Integer in your case) means that it will never need a chomp, as numbers do not have new lines. You never need to use chomp.to_i or chomp.to_f.

Notice that the method now returns an instance of String, rather than nil. It can now be used as you would like, in this case, using puts to display to the terminal.

Spaces around the comparison operator makes it easier to read.

The method itself may as well not be a method if you are going to prompt, get data, and report. You would be doing just as well to remove the method definition and just have this as running code.

I have refactored this to be that way:

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!

Hope that helps.

于 2013-10-30T02:51:52.420 に答える