How do I use the conditional operator (? :) in Ruby?

前端 未结 7 2523
無奈伤痛
無奈伤痛 2020-11-22 10:34

How is the conditional operator (? :) used in Ruby?

For example, is this correct?

<% question = question.size > 20 ? question.ques         


        
7条回答
  •  一向
    一向 (楼主)
    2020-11-22 11:06

    @pst gave a great answer, but I'd like to mention that in Ruby the ternary operator is written on one line to be syntactically correct, unlike Perl and C where we can write it on multiple lines:

    (true) ? 1 : 0
    

    Normally Ruby will raise an error if you attempt to split it across multiple lines, but you can use the \ line-continuation symbol at the end of a line and Ruby will be happy:

    (true)   \
      ? 1    \
      : 0
    

    This is a simple example, but it can be very useful when dealing with longer lines as it keeps the code nicely laid out.

    It's also possible to use the ternary without the line-continuation characters by putting the operators last on the line, but I don't like or recommend it:

    (true) ?
      1 :
      0
    

    I think that leads to really hard to read code as the conditional test and/or results get longer.

    I've read comments saying not to use the ternary operator because it's confusing, but that is a bad reason to not use something. By the same logic we shouldn't use regular expressions, range operators ('..' and the seemingly unknown "flip-flop" variation). They're powerful when used correctly, so we should learn to use them correctly.


    Why have you put brackets around true?

    Consider the OP's example:

    <% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
    

    Wrapping the conditional test helps make it more readable because it visually separates the test:

    <% question = (question.size > 20) ? question.question.slice(0, 20)+"..." : question.question %>
    

    Of course, the whole example could be made a lot more readable by using some judicious additions of whitespace. This is untested but you'll get the idea:

    <% question = (question.size > 20) ? question.question.slice(0, 20) + "..." \
                                       : question.question 
    %>
    

    Or, more written more idiomatically:

    <% question = if (question.size > 20)
                    question.question.slice(0, 20) + "..."
                  else 
                    question.question 
                  end
    %>
    

    It'd be easy to argument that readability suffers badly from question.question too.

提交回复
热议问题