1

I would like to know the difference between the if else syntax and the ? syntax. I saw an example on the web where they used a question mark instead of an if else statement. I understand that if statements can be used on only one line

return true if 4 > 3

instead of

if 4 > 3
  return true
else
  return false
end

However, I'm confused about when you'd use a question mark in that case. Here is the example, I saw in a video.

@date = params[:month] ? Date.parse(params[:month]) : Date.today

On the surface this appears to be an alternative syntax for the if else statement. However, I've never seen it before and have no idea what it does.

I also know that methods can end in a question mark, indicating it should return either a true or false value like so

def is_multiple_of_4? (x)
  return true if x % 4 == 0
end

However, the above syntax is different. I would love to learn what that means and what the difference is between that and if else statements.

Artjom B.
  • 58,311
  • 24
  • 111
  • 196
  • `return true if 4 > 3` is not the same as the following `if..else` example you give. `return true if 4 > 3` does not have an `else` clause and does not `return` if the condition is not true. – deceze Jun 02 '14 at 15:06
  • That is a boolean expression I gave. Boolean expressions can only have two possible values (true and false). If one value was true, then by default, the other value has to be false. That's the only other possible value in a boolean expression. –  Jun 02 '14 at 15:14
  • Are you referring to `return true if 4 > 3`? That's not a boolean expression, there's no implicit `false`. That line literally tells Ruby to `return` `true` in case 4 should be larger than 3. If 4 should be smaller than 3, it will simply to nothing. – deceze Jun 02 '14 at 15:26
  • I see. Thanks for the clarification. –  Jun 02 '14 at 15:30

2 Answers2

2

The ?: is a ternary operator, and is from languages like C, C++ and Java (see here for origin - http://en.wikipedia.org/wiki/%3F: ).

Ruby borrows it for familiarity. Also, the ?: expression is more terse, but can get very unreadable for more complex situations, in which case the if-else construct may be preferred.

manojlds
  • 259,347
  • 56
  • 440
  • 401
1

This is the ternary operator that has been a staple of languages for a long time. My believe is it's inclusion in Ruby was in an effort to ease the transition to Ruby from other languages for developers.

It essentially reads

<condition> ? <result if true> : <result if false>

Its use primarily lies in those instances you have a simple condition with only two possible simple outcomes. It steamlines the if/else block into a single line. It is not quite as readable as an inline if statement.

The example statement: @date = params[:month] ? Date.parse(params[:month]) : Date.today Essentially breaks down into an assignment, condition, and true and false values. And effectively does this:

  1. assignment: @date = - set date to the value returned by the ternary statement
  2. condition: params[:month] - a month value - note: nil evaluates to false when used in a condition.
  3. true value: Date.parse(params[:month]) - Parse the month value as a date.
  4. false value: Date.today - default value used if there is no date.

In more longer form ruby this essentially does this (the condition is not the same, because it is calling out the explicit case inferred from the statement, i.e.: the one most likely to trigger the false case).

if ! params[:month].nil?
  @date = Date.today
else
  @date = Date.parse(params[:month])
end

As for your comment about question marks in method names, that is a convention that allows a developer to distinguish methods that a return a boolean quickly from other methods. Just like methods that end with an exclamation point indicate methods that modify their caller.

The syntax difference is in the space between the method name and the operator.

Whereas most infix operators can be used without spaces, between the first and second operators, the ternary operator requires a space, between the first argument (condition) and the question mark, because the question mark can be a valid part of a method or variable name.

EmFi
  • 23,137
  • 3
  • 55
  • 66
  • It does the same thing as a for block with an if else statement inside I gather? –  Jun 02 '14 at 15:13
  • @user3684392: It is completely separate from a for block, with an if/else statement. It is a short form for a specific type of if/else structure that is meant to be used in line. – EmFi Jun 02 '14 at 15:16
  • Response was edited to provide more detail about the statement the question used as an example. – EmFi Jun 02 '14 at 15:34
  • The equivalent `if` statement should read `if params[:month]` – Mark Thomas Jun 02 '14 at 15:59
  • In ruby, `if`...`else` constructs are *expressions*, not statements, so the equivalent to the ternary operator usage here is actually just `@date = if params[:month] then Date.parse(params[:month]) else Date.today end`, and they are semantically exactly equivalent (the difference is only in appearance, not in behaviour). Choosing between the two then, is purely a matter of style. – amnn Jun 02 '14 at 16:46