2010-02-01 16 views
67

Existe-t-il un idiome ruby ​​pour "If do-this" et "do-this" comme une simple commande?Ruby opérateur ternaire sans autre

par exemple, je suis en train de faire

object.method ? a.action : nil 

quitter la clause else vide, mais je me sens comme il y a probablement un moyen plus idiomatiques de faire ce qui n'implique pas avoir à spécifier un nul à la fin. (Et encore, je me sens comme prenant plusieurs lignes de code serait inutile dans ce cas.

+0

Cela dépend du contexte, mais il est parfois plus élégant de lire un si/alors/début du bloc avec une seule ligne dans le corps que quelque chose de plus dense/laconique. –

Répondre

105
a.action if object.method? 
14

réponse Greg est le meilleur, mais pour le compte rendu, et plus encore que dans C, expressions et déclarations sont équivalentes en Ruby, donc en plus a.action if o.m? vous pouvez aussi faire des choses comme:

object.method? && a.action 

vous pouvez écrire (a; b; c) if d ou même

(a 
b 
c 
) if d 

ou pour ce mat r: (x; y; z) ? (a; b c) : (d; e; f)

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

131

En règle générale, vous avez besoin à peu près jamais l'opérateur ternaire dans Ruby. La raison pour laquelle vous en avez besoin en C est parce que dans C if est une déclaration, donc si vous voulez retourner une valeur, avez pour utiliser l'opérateur ternaire, qui est une expression.

Dans Ruby, tout est une expression, il sont aucune déclaration, ce qui rend l'opérateur ternaire à peu près inutile. Vous pouvez toujours remplacer

cond ? then_branch : else_branch 

avec

if cond then then_branch else else_branch end 

Ainsi, dans votre exemple:

object.method ? a.action : nil 

est équivalent à

if object.method then a.action end 

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

a.action if object.method 

En outre, étant donné que les opérateurs booléens en Ruby pas seulement revenir true ou false, mais la valeur de la dernière expression évaluée, vous pouvez les utiliser pour le flux de contrôle. Ceci est un idiome importé de Perl, et ressemblerait à ceci:

object.method and a.action 
+12

Ceci est une excellente réponse! –

+5

opérateur ternaire 'cond? a: b' est plus court que 'si cond alors a autre b 'fin, cela seul me fait l'utiliser pour sauver 11 caractères ;-) – Markus

+0

[Ruby Style Guide] (https://github.com/bbatsov/ruby-style -guide # ternary-operator) indique: "Favoriser l'opérateur ternaire ('?: ') sur les constructions' if/then/else/end', c'est plus commun et évidemment plus concis ". –

2

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

value = 1 result = (value == 1 && 'one') || 'two' result #=> 'one' Expliquer: valeur == 1 & & 'un' # => renvoie le résultat dernière expression, la valeur est égal à égal 1 donc et la section sera évaluée, et retourner 'un'.

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

Expliquer: valeur = 1 et « et » expression ne sera pas évaluée, mais instad sera utilisé « ou » expression et renvoie « deux »

0

Une autre façon cela peut être fait sur la même ligne est la suivante:

if object.method; a.action end 

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

Vous pouvez aussi être un peu plus bavard et rubocop amical:

if object.method then a.action end