2010-02-01 13 views
67

Czy istnieje idiom ruby ​​dla "Jeśli to zrobię" i "zrób to", tak jak proste polecenie?Potrójny operator potrójny Ruby bez innego:

na przykład, jestem aktualnie robi

object.method ? a.action : nil 

opuścić klauzuli jeszcze pusta, ale czuję się tam pewnie bardziej idiomatycznych sposobem w ten sposób, że nie pociąga za sobą konieczności określenia na nil koniec. (I alternatywnie, czuję się podejmowania wielu linii kodu byłoby marnotrawstwem w tym przypadku.

+0

To zależy od kontekstu, ale czasami jest to bardziej eleganckie czytać if/podczas/rozpocząć bloku z tylko jedną linię w organizmie niż coś bardziej zwartego/lapidarnego. –

Odpowiedz

105
a.action if object.method? 
14

odpowiedź Grega jest najlepszy, ale dla porządku, a nawet więcej niż w C, wyrażenia i zdania są równoważne w Ruby, więc oprócz a.action if o.m? można również robić takie rzeczy jak:

object.method? && a.action 

Możesz napisać (a; b; c) if d lub nawet

(a 
b 
c 
) if d 

lub dla tej matowej R: (x; y; z) ? (a; b c) : (d; e; f)

Nie ma sytuacja w Ruby, gdzie dozwolone jest tylko jedno oświadczenie lub wyrażenie ...

131

Jako ogólną zasadę: nigdy dość dużo potrzebować potrójny operatora w Ruby. Powodem, dla którego jest to potrzebne w C, jest to, że w C if jest instrukcja, więc jeśli chcesz zwrócić wartość, musisz mieć, aby użyć operatora trójskładnikowego, który jest wyrażeniem.

W Ruby, wszystko jest wyrazem nie żadnego oświadczenia, co sprawia, że ​​potrójny operator prawie zbędne. Zawsze można zastąpić

cond ? then_branch : else_branch 

z

if cond then then_branch else else_branch end 

Tak w przykładzie:

object.method ? a.action : nil 

jest równoważna

if object.method then a.action end 

który jako @Greg Campbell zwraca uwagę, jest z kolei równoznaczne z końcem if modyfikator forma

a.action if object.method 

Również od operatorów logicznych w Ruby nie tylko powrócić true lub false, ale wartość ostatnim ocenianym wypowiedzi, można je wykorzystać do kontroli przepływu. Jest to idiom importowane z Perl, i będzie wyglądać następująco:

object.method and a.action 
+12

To jest WIELKA odpowiedź! –

+5

potrójny operator 'cond? a: b' jest krótszy niż 'if cond then a else b end', który sam powoduje, że używam go do zapisania 11 znaków ;-) – Markus

+0

[Ruby Style Guide] (https://github.com/bbatsov/ruby Style Guide) -guide # ternary-operator) stwierdza: "Korzystaj z potrójnego operatora ('?: ') przez konstrukty' if/then/else/end', które są bardziej powszechne i oczywiście bardziej zwięzłe ". –

2

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

value = 1 result = (value == 1 && 'one') || 'two' result #=> 'one' Wyjaśnienie: wartość == 1 & & 'jeden' # => zwraca wynik ostatniego wyrażenia, wartość jest równe 1 tak i sekcja zostanie oceniona i zwróci "jeden".

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

Wyjaśnienie: wartość = 1 „i” ekspresja nie będą oceniane, ale instad zostaną wykorzystane „lub” ekspresja i zwraca „dwa”

0

Innym sposobem można to zrobić na tej samej linii to:

if object.method; a.action end 

ten jest uważany za zły styl przez Rubocop ponieważ wykorzystuje średnik wypowiedzieć wyrażenie, ale uważam, że bardziej czytelny w pewnych warunkach niż sklejaniu na if na końcu. Łatwiej jest przeoczyć instrukcję if na końcu i nie zawsze chcę zwrócić coś, jeśli warunek nie jest prawdziwy (jak jesteś zmuszony do współpracy z potrójnym operatorem).

Możesz być również nieco bardziej rozwlekły i rubocop przyjazny:

if object.method then a.action end 
Powiązane problemy