2010-02-01 6 views
67

Есть ли рубиновая идиома для «If do-this» и «do-this» как простая команда?Ruby trernary operator without else

, например, я в настоящее время делаю

object.method ? a.action : nil 

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

+0

Это зависит от контекста, но иногда это более элегантно, чтобы прочитать, если/пока/начать блок только с одной линии в организме, чем что-то более плотное/короткое. –

ответ

14

ответ Грега является лучшим, но и для записи, и даже больше, чем в 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, где только одно выражение или разрешено ...

131

Как общее правило: вы в значительной степени не нужен тройной оператор в 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 Кэмпбелл указывает, является в свою очередь, эквивалентно задней if модификатор формы

a.action if object.method 

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

object.method and a.action 
+12

Это БОЛЬШОЙ ответ! –

+5

тернарный оператор 'cond? a: b' короче, чем 'if cond then a else b end', это только заставляет меня использовать его, чтобы сохранить 11 символов ;-) – Markus

+0

[Руководство по стилю Ruby] (https://github.com/bbatsov/ruby-style -guide # trernary-operator): «Выражайте поддержку тернарному оператору ('?: ') над конструкциями' if/then/else/end', более распространенным и, очевидно, более кратким ». –

2

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

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

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

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

0

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

if object.method; a.action end 

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

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

if object.method then a.action end