简体   繁体   中英

In Ruby, why doesn't ternary operator work when using a puts function inside an each statement?

Given that you write the code on IRB:

array = [1,2,3]
array.each {|x| x > 2 ? puts "lower" : puts "higher"}

The program doesn't execute the line and it somehow according to the program is an incomplete line. Any help would be appreciated.

This is caused by ambiguous arguments. Ruby, unlike many other languages such as JavaScript, is really lax about requiring brackets puts x and puts(x) are equivalent. Where this breaks down is when it's not clear which are arguments, and which are part of other syntax.

For example, if f is a method that takes 1-3 arguments and x and y are variables, then what is the meaning of:

f x, f x, y

Is that f(x, f(x,y)) , f(x), f(x), y or f(x, f(x), y) ? Ruby throws an error rather than presume the wrong thing.

Easy fix is to eliminate the duplication of effort here and use a single puts with a ternary used to determine the value:

array = [1,2,3]
array.each { |x| puts x > 2 ? "lower" : "higher"}

Now it works because there's no ambiguity on arguments, there's only one method call so it's easy.

The previous answer explains clearly what is happening. However you may note that this syntax will also work, but here you are duplicating the method call on both sides of the ternary operator:

array.each {|x| x > 2 ? (puts "lower") : (puts "higher")}

By wrapping the duplicate method call on both sides, that code is executed on both sides. But it definitely is better style to do it the more correct way where you are passing the result of ternary to puts

array.each { |x| puts x > 2 ? "lower" : "higher"}

which is the same as:

array.each { |x| puts (x > 2 ? "lower" : "higher") }

The puts method takes a single string argument and that's what we are passing it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM