Тернарный оператор?: Определен как метод в Ruby? - PullRequest
0 голосов
/ 26 августа 2018

Я новичок в Ruby и немного озадачен тем, как работает троичный оператор ?:.

Согласно книге Инженерное программное обеспечение как услуга: гибкий подход с использованием облачных вычислений :

каждая операция является вызовом метода для некоторого объекта и возвращает значение.

В этом смысле, если троичный оператор представляет операцию, это вызов метода для объекта с двумя аргументами. Однако я не могу найти какой-либо метод, который троичный оператор представляет в Документация Ruby . Представляет ли троичный оператор операцию в Ruby? Является ли вышеупомянутое утверждение, сделанное упомянутой книгой, неправильным? Является ли троичный оператор в Ruby действительно синтаксическим сахаром для операторов if ... then ... else ... end?

Обратите внимание: Мой вопрос связан с Как использовать условный оператор (? :) в Ruby? , но не такой, как этот. Я знаю, как использовать троичный оператор так, как описано в этом посте. Мой вопрос о том, где троичный оператор определен в Ruby и если троичный оператор определен как метод или методы.

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

Является ли троичный оператор в Ruby действительно синтаксическим сахаром для if ... then ... else ... end операторов?

(еще один) да .

Вотдерево разбора для 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

Вот дерево разбора для 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

Они идентичны.

Во многих языках ?: является выражением , тогда как if-then-else является выражением .В Ruby оба являются выражениями.

0 голосов
/ 26 августа 2018

Является ли троичный оператор в Ruby действительно синтаксическим сахаром для операторов if ... then ... else ... end?

Да.

С doc/syntax/control_expressions.rdoc

Вы также можете написать выражение if-then-else, используя ? и :. Это троичный, если:

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

То же самое, что и это if выражение:

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

" Согласно этой книге," каждая операция является вызовом метода для некоторого объекта и возвращает значение. "В этом смысле, если троичный оператор представляет операцию, это вызов метода для объекта с двумя аргументы."

if, unless, while и until не являются операторами, они являются управляющими структурами. Их версии модификаторов появляются в таблице приоритетов операторов , потому что они должны иметь приоритет для анализа. Они просто проверяют, является ли их условие истинным или ложным. В Ruby это просто, только false и nil являются ложными. Все остальное правда.

Операторами являются такие вещи, как !, +, * и []. Они унарные или двоичные . Вы можете увидеть их список, вызвав .methods.sort на различных объектах. Например ...

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

Обратите внимание, что в Smalltalk , из которого Ruby активно заимствует, все на самом деле является вызовом метода. Включая управляющие структуры .

...