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
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
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)
x
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
これを試して:
age>=21 ? puts("You're over 21!") : puts("You're too young.")
指定されたオプションに括弧なしの関数呼び出しがあると、三項演算子が混乱します。
これを行うこともできます:
puts age>=21 ? "You're over 21!" : "You're too young."
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.