web-dev-qa-db-fra.com

Ruby opérateur ternaire sans autre

Existe-t-il un Ruby idiome pour "If do-this" et "do-this" juste comme une simple commande?

par exemple, je fais actuellement

object.method ? a.action : nil

laisser la clause else vide, mais j'ai l'impression qu'il y a probablement une façon plus idiomatique de le faire qui n'implique pas d'avoir à spécifier un zéro à la fin. (et alternativement, j'ai l'impression que prendre plusieurs lignes de code serait un gaspillage dans ce cas.

73
RyanCacophony
a.action if object.method?
111
Greg Campbell

En règle générale: vous n'avez pratiquement jamais besoin de l'opérateur ternaire dans Ruby. La raison pour laquelle vous en avez besoin en C, c'est parce qu'en C if est une instruction, donc si vous voulez renvoyer une valeur, vous avez pour utiliser l'opérateur ternaire, qui est une expression .

En Ruby, tout est une expression, il n'y a y a aucune instruction, ce qui rend l'opérateur ternaire à peu près superflu. Vous pouvez toujours remplacer

cond ? then_branch : else_branch

avec

if cond then then_branch else else_branch end

Donc, dans votre exemple:

object.method ? a.action : nil

est équivalent à

if object.method then a.action end

qui, comme le souligne @Greg Campbell, est à son tour équivalent à la forme modificatrice if de fin

a.action if object.method

De plus, puisque les opérateurs booléens de Ruby renvoient non seulement true ou false, mais la valeur de la dernière expression évaluée, vous pouvez les utiliser pour le flux de contrôle C'est un idiome importé de Perl, et ressemblerait à ceci:

object.method and a.action
136
Jörg W Mittag

La réponse de Greg est la meilleure, mais pour mémoire, et encore plus qu'en C, les expressions et les déclarations sont équivalentes en Ruby, donc en plus de a.action if o.m? vous pouvez aussi faire des choses comme:

object.method? && a.action

Tu peux écrire (a; b; c) if d ou même

(a
 b
 c
) if d

ou d'ailleurs: (x; y; z) ? (a; b c) : (d; e; f)

Il n'y a pas de situation en Ruby où une seule instruction ou expression est autorisée ...

16
DigitalRoss

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

value = 1 result = (value == 1 && 'one' ) || 'two' result #=> 'one' Expliquez: valeur == 1 && 'one' # => renvoie le résultat de la dernière expression, la valeur est égale à 1 et la section sera évaluée, et retournera 'one'.

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

Expliquez: valeur! = 1 et 'et' l'expression ne sera pas évaluée, mais instad sera utilisé 'ou' expression et elle renvoie 'deux'

2
omakoleg

Une autre manière de procéder sur la même ligne est:

if object.method; a.action end

Ceci est considéré comme un mauvais style par Rubocop car il utilise un point-virgule pour terminer l'expression, mais je le trouve plus lisible dans certaines conditions que de clouer sur l'instruction if à la fin. Il est plus facile d'oublier une instruction if à la fin et je ne veux pas toujours retourner quelque chose si la condition n'est pas vraie (comme vous êtes obligé de le faire avec un opérateur ternaire).

Vous pouvez également être un peu plus bavard et convivial avec rubocop:

if object.method then a.action end
1
Allison