Рубиновый троичный оператор без остального - PullRequest
72 голосов
/ 01 февраля 2010

Существует ли рубиновая идиома для "Если сделаешь это" и "сделай это" как простая команда?

например, я сейчас делаю

object.method ? a.action : nil

, чтобы оставить предложение else пустым, но я чувствую, что, возможно, есть более идиоматический способ сделать это, не требующий указания nil в конце (и альтернативно, я чувствую, что в этом случае использование нескольких строк кода будет расточительным.

Ответы [ 5 ]

136 голосов
/ 01 февраля 2010

Как правило: вам почти никогда не нужен троичный оператор в Ruby. Причина, по которой вам это нужно в C, заключается в том, что в C if есть оператор, поэтому, если вы хотите вернуть значение, у вас есть для использования троичного оператора, который является выражением.

В Ruby все является выражением, в нет операторов, что делает тернарный оператор в значительной степени излишним. Вы всегда можете заменить

cond ? then_branch : else_branch

с

if cond then then_branch else else_branch end

Итак, в вашем примере:

object.method ? a.action : nil

эквивалентно

if object.method then a.action end

, который, как указывает @Greg Campbell, в свою очередь эквивалентен завершающей if форме модификатора

a.action if object.method

Кроме того, поскольку логические операторы в Ruby не только возвращают true или false, но и значение последнего оцененного выражения, их можно использовать для потока управления. Это идиома, импортированная из Perl, и будет выглядеть так:

object.method and a.action
110 голосов
/ 01 февраля 2010
a.action if object.method?
16 голосов
/ 01 февраля 2010

Ответ Грега лучший, но для записи, и даже больше, чем в C, выражения и операторы эквивалентны в Ruby, так что кроме a.action if o.m? вы также можете делать такие вещи:

object.method? && a.action

Вы можете написать (a; b; c) if d или даже

(a
 b
 c
) if d

или в этом отношении: (x; y; z) ? (a; b c) : (d; e; f)

В Ruby не существует ситуации, когда допускается только одно выражение или выражение ...

2 голосов
/ 26 августа 2012

result = (<expression> && <true value>) || <false value>

value = 1 result = (value == 1 && 'one' ) || 'two' result #=> 'one' Объясните: value == 1 && 'one' # => возвращает последний результат выражения, значение равно 1, поэтому раздел будет оценен и вернет 'one'.

value = 0 result = (value == 1 && 'one' ) || 'two' result #=> 'two'

Объясните: значение! = 1 и выражение 'и' не будут оцениваться, но будет использовано выражение instad 'или', и оно возвращает 'two'

1 голос
/ 31 октября 2016

Другой способ сделать это можно в той же строке:

if object.method; a.action end

Это считается плохим стилем для Rubocop, потому что он использует точку с запятой для завершения выражения, но я считаю, что в некоторых условиях он более читабелен, чем использование оператора if в конце. Проще пропустить оператор if в конце, и я не всегда хочу что-то возвращать, если условие не выполняется (как вы вынуждены использовать троичный оператор).

Вы также можете быть более многословным и дружелюбным к рубокопу:

if object.method then a.action end
...