Reputation: 817
I attempted to use the shorthand to get a response based on the existance of a sub-string, instead of the expected string response, it evaluated to "false." In my second simpler example the expect string was printed.
#fails
puts "test".include? "s" ? "yep" : "nope"
#success
puts 1>2 ? "1 is greater than 2" : "1 is not greater than 2"
Upvotes: 1
Views: 44
Reputation: 7743
It looks like ruby is unable to parse this as you're expecting without a little help. It thinks you're doing
puts "test".include?("s" ? "yep" : "nope")
You need to either use the (optional) parens around the argument
puts "test".include?("s") ? "yep" : "nope"
or force the test expression to be interpreted as a whole:
puts ("test".include?"s") ? "yep" : "nope"
Upvotes: 2
Reputation: 54233
It's a precedence problem.
You need :
puts "test".include?("s") ? "yep" : "nope"
#=> yep
Method call without parenthesis is somewhere between defined?
and or
in the precedence table, so it is lower than the ternary operator. It means that
puts "test".include? "s" ? "yep" : "nope"
is parsed as
puts "test".include?("s" ? "yep" : "nope")
which is
puts "test".include?("yep")
which is
false
"s" ? "yep" : "nope"
displays a warning :
warning: string literal in condition
because ternary operator expects a boolean, and a String is always truthy.
The reason this works
puts 1>2 ? "1 is greater than 2" : "1 is not greater than 2"
is that the ternary operator has a higher precedence than puts :
puts ( 1>2 ? "1 is greater than 2" : "1 is not greater than 2" )
It is evaluated as :
puts ( "1 is not greater than 2" )
When you have precedence problem, using puts
without parenthesis might just make the problem worse. You can fire up IRB and see what the result is directly.
Here's an example :
# in a script :
puts [1,2,3].map do |i|
i * 2
end
#=> #<Enumerator:0x0000000214d708>
With IRB :
[1,2,3].map do |i|
i * 2
end
# => [2, 4, 6]
Upvotes: 6