2
votes

I am new to Ruby and a bit confused about how the ternary operator, ?:, works.

According to the book Engineering Software as a Service: An Agile Approach Using Cloud Computing:

every operation is a method call on some object and returns a value.

In this sense, if the ternary operator represents an operation, it is a method call on an object with two arguments. However, I can't find any method of which the ternary operator represents in Ruby's documentation. Does a ternary operator represent an operation in Ruby? Is the above claim made by the book mentioned wrong? Is the ternary operator in Ruby really just a syntactic sugar for if ... then ... else ... end statements?

Please note: My question is related to How do I use the conditional operator (? :) in Ruby? but not the same as that one. I know how to use the ternary operator in the way described in that post. My question is about where ternary operator is defined in Ruby and if the ternary operator is defined as a method or methods.

2
@ElliottFrisch My question is related to that one but not the same as that one. I know how to use the ternary operator in the way described in that post. My question is about where ternary operator is defined in Ruby and if the ternary operator is defined as a method or methods.Isaac To
This table may be useful. Not all operators in Ruby are methods on an object. techotopia.com/index.php/…Marc Baumbach
@MarcBaumbach According to that table, the ternary operator is not implemented as a method. I guess the claim in the book I read is wrong. What do you think? Do you think I interpreted the claim in the book incorrectly?Isaac To
I don't think you're interpreting it incorrectly, I think the book is incorrect or not specific enough. Generally speaking, Ruby does treat nearly everything as an object where other languages typically don't. nil being a great example.Marc Baumbach

2 Answers

8
votes

Is the ternary operator in Ruby really just a syntactic sugar for if ... then ... else ... end statements?

Yes.

From doc/syntax/control_expressions.rdoc

You may also write a if-then-else expression using ? and :. This ternary if:

input_type = gets =~ /hello/i ? "greeting" : "other"

Is the same as this if expression:

input_type =
  if gets =~ /hello/i
    "greeting"
  else
    "other"
  end

"According to this book, "every operation is a method call on some object and returns a value." In this sense, if the ternary operator represents an operation, it is a method call on an object with two arguments."

if, unless, while, and until are not operators, they are control structures. Their modifier versions appear in the operator precedence table because they need to have precedence in order to be parsed. They simply check if their condition is true or false. In Ruby this is simple, only false and nil are false. Everything else is true.

Operators are things like !, +, *, and []. They are unary or binary. You can see a list of them by calling .methods.sort on various objects. For example...

2.4.3 :004 > 1.methods.sort
 => [:!, :!=, :!~, :%, :&, :*, :**, :+, :+@, :-, :-@, :/, :<, :<<, :<=, :<=>, :==, :===, :=~, :>, :>=, :>>, :[], :^, :__id__, :__send__, etc...

Note that in Smalltalk, from which Ruby borrows heavily, everything really is a method call. Including the control structures.

3
votes

Is the ternary operator in Ruby really just a syntactic sugar for if ... then ... else ... end statements?

(another) yes.

Here's the parse tree for a ? b : c:

$ ruby --dump=parsetree -e 'a ? b : c'
###########################################################
## Do NOT use this node dump for any purpose other than  ##
## debug and research.  Compatibility is not guaranteed. ##
###########################################################

# @ NODE_SCOPE (line: 1)
# +- nd_tbl: (empty)
# +- nd_args:
# |   (null node)
# +- nd_body:
#     @ NODE_PRELUDE (line: 1)
#     +- nd_head:
#     |   (null node)
#     +- nd_body:
#     |   @ NODE_IF (line: 1)
#     |   +- nd_cond:
#     |   |   @ NODE_VCALL (line: 1)
#     |   |   +- nd_mid: :a
#     |   +- nd_body:
#     |   |   @ NODE_VCALL (line: 1)
#     |   |   +- nd_mid: :b
#     |   +- nd_else:
#     |       @ NODE_VCALL (line: 1)
#     |       +- nd_mid: :c
#     +- nd_compile_option:
#         +- coverage_enabled: false

Here's the parse tree for if a then b else c end:

$ ruby --dump=parsetree -e 'if a then b else c end'
###########################################################
## Do NOT use this node dump for any purpose other than  ##
## debug and research.  Compatibility is not guaranteed. ##
###########################################################

# @ NODE_SCOPE (line: 1)
# +- nd_tbl: (empty)
# +- nd_args:
# |   (null node)
# +- nd_body:
#     @ NODE_PRELUDE (line: 1)
#     +- nd_head:
#     |   (null node)
#     +- nd_body:
#     |   @ NODE_IF (line: 1)
#     |   +- nd_cond:
#     |   |   @ NODE_VCALL (line: 1)
#     |   |   +- nd_mid: :a
#     |   +- nd_body:
#     |   |   @ NODE_VCALL (line: 1)
#     |   |   +- nd_mid: :b
#     |   +- nd_else:
#     |       @ NODE_VCALL (line: 1)
#     |       +- nd_mid: :c
#     +- nd_compile_option:
#         +- coverage_enabled: false

They are identical.

In many languages ?: is an expression whereas if-then-else is a statement. In Ruby, both are expressions.