Whenever I try to run the program, an error pops up saying "string literal in condition (on line 10)". What am I doing wrong?
puts "Welcome to the best calculator there is. Would you like to (a) calculate the area of a geometric shape or (b) calculate the equation of a parabola? Please enter an 'a' or a 'b' to get started."
response = gets.chomp
if response == "a" or "A"
puts "ok."
elsif response == "b" or "B"
puts "awesome."
else
puts "I'm sorry. I did not get that. Please try again."
end
You have to specify the full condition on both sides of the or
.
if response == "a" or response == "A"
The two sides of the or
are not connected; Ruby makes no assumptions about what's on the right based on what's on the left. If the right side is the bare string "A"
, well, anything other than false
or nil
is considered "true", so the whole expression evaluates as "true" all the time. But Ruby notices that it's a string and not actually a boolean value, suspects you might not have specified what you meant to, and so issues the warning in the question.
You can also use a case
expression to make it simpler to do multiple tests against a single value; if you supply a list of multiple possibilities in a single when
, they are effectively or
ed together:
case response
when "a","A"
puts "ok"
when "b","B"
puts "awesome."
else
puts "I'm sorry. I did not get that. Please try again."
end
For the specific situation of ignoring alphabetic case, you could also just convert to either upper or lower before testing:
case response.upcase
when "A"
puts "ok"
when "B"
puts "awesome."
else
puts "I'm sorry, I did not get that. Please try again."
end
It is not wrong syntactically; it is wrong in the sense that it is useless. The expression response == "a" or "A"
is interpreted as (response == "a") or "A"
, which is always truthful because of "A"
, so it is useless to put that in a condition.
if response == "a" or "A"
is equivalent to if (response == "a") or "A"
. And "A" is a string literal, that's why the ruby interpreter complains.
That's not an error, it's a warning.
You have the condition
response == "a" or "A"
Well, response == "a"
is either true
or false
. If it is true
, the condition reduces to
true or "A"
which is
true
If it is false
, the condition reduces to
false or "A"
which is
"A"
which is truthy, since everything except false
and nil
is truthy.
So, regardless of the contents of response
, the condition will always be true.
And that's what the warning is warning you about: string literals are always truthy, it just doesn't make sense to use them in a condition.