Ruby'de koşullu işleci (? :) nasıl kullanabilirim?


303

Koşullu işleç ( ? :) Ruby'de nasıl kullanılır?

Örneğin, bu doğru mu?

<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>

1
evet, sanırım, ama aynı zamanda bunu şu şekilde yapabileceğinizi düşünüyorum: question=question[0,20] Eğer 20'den küçükse, bunu değiştirmez.
DGM

Ayrıca uzunluk 20'den büyükse bir '...' eklemeliyim
Mithun Sreedharan

1
Belirli bir sütundaki bir satırı körü körüne kesmeye dikkat edin. Sonunda bir kelimeyi kesip sonra elipsis ('...') ekleyerek kötü görünüyor. Bunun yerine, yakındaki bir noktalama işaretini veya boşluk karakterini arayın ve orada kısaltın. Sadece yakınlarda daha iyi bir kırılma noktası yoksa, orta kelimeyi kısaltmalısınız.
Tin Man

Yanıtlar:


496

Öyle üçlü operatör ve (parantez gerekli değildir) C gibi çalışır. Şöyle çalışır:

if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this

Bununla birlikte, Ruby'de öncelik ififadeleri dışında şu şekilde bir ifadedir: if a then b else c end=== a ? b : c. Her ikisi de ifadedir.

Örnekler:

puts (if 1 then 2 else 3 end) # => 2

puts 1 ? 2 : 3                # => 2

x = if 1 then 2 else 3 end
puts x                        # => 2

İlk durumda parantez gereklidir (aksi takdirde Ruby karıştırılır, çünkü puts if 1bundan sonra ekstra bir önemsiz olduğunu düşünür ), ancak söz konusu sorun ortaya çıkmadığı için son durumda gerekli değildir.

Birden çok satırda okunabilirlik için "uzun süre" formunu kullanabilirsiniz:

question = if question.size > 20 then
  question.slice(0, 20) + "..."
else 
  question
end

0 koyar mı? Sonuç olarak 2: 3 de 2 verir. Neden?
X_Trust

18
@X_Trust Ruby'de tek sahte değerler nilve false. Gerçekten çok olağan değil.
Kroltan

35
puts true ? "true" : "false"
=> "true"


puts false ? "true" : "false"
=> "false"

Terse ama ne yaptığını açıklıyor.
Kalay Adam

4
puts (true ? "true" : "false")Parantez ile küçük düzenleme . Aksi takdirde işlemlerin sırası net değildir. Bunu ilk okuduğumda, (puts true) ? "true" : "false"daha putssonra dize değeri haline gelen boole'yi döndürmeyi beklediğim gibi okudum .
Fresheyeball

26

ERB kullanımınız Rails içinde olduğunuzu gösterir. Öyleyse truncate, işi sizin için yapacak yerleşik bir yardımcıyı düşünün:

<% question = truncate(question, :length=>30) %>

Bu harika! tam olarak ne yapmak istiyorum !!
Mithun Sreedharan

11
Bu yıllar geçti, ama tüm sözdizimsel yönleri geçip sorgulayıcının gerçekleştirmeye çalıştığı şeye doğru gittiğinden bu cevaptan çok etkilendim.
Mike Buckbee

2
+1, ancak erb mutlaka raylar (Sinatra, bağımsız ERB, vb.) Anlamına gelmez.
Fox Wilson

17

@pst harika bir cevap verdi, ancak Ruby'de üçlü operatörün, birden çok satıra yazabileceğimiz Perl ve C'nin aksine, sözdizimsel olarak doğru olması için bir satır üzerine yazıldığını belirtmek isterim:

(true) ? 1 : 0

Normalde Ruby, birden çok satıra bölmeye çalışırsanız bir hata oluşturur, ancak \bir satırın sonunda satır devam sembolünü kullanabilirsiniz ve Ruby mutlu olacaktır:

(true)   \
  ? 1    \
  : 0

Bu basit bir örnektir, ancak kodu güzel bir şekilde düzenlediği için daha uzun satırlarla uğraşırken çok yararlı olabilir.

Üçlüyü, satır sonlandırma karakterleri olmadan, operatörleri en son satırda koyarak kullanmak da mümkündür, ancak bunu sevmiyorum veya önermiyorum:

(true) ?
  1 :
  0

Koşullu test ve / veya sonuçlar uzadıkça bu kodu okumak gerçekten zor olduğunu düşünüyorum.

Üçlü operatörü kullanmamayı söyleyen yorumları okudum çünkü kafa karıştırıcı, ama bu bir şey kullanmamak için kötü bir neden. Aynı mantıkla düzenli ifadeler, aralık operatörleri (' ..' ve görünüşte bilinmeyen "flip-flop" varyasyonu) kullanmamalıyız. Doğru kullanıldıklarında güçlüdürler, bu yüzden doğru kullanmayı öğrenmeliyiz.


Neden köşeli parantez koydunuz true?

OP örneğini düşünün:

<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>

Koşullu testin sarılması, testi görsel olarak ayırdığı için daha okunabilir olmasına yardımcı olur:

<% question = (question.size > 20) ? question.question.slice(0, 20)+"..." : question.question %>

Tabii ki, tüm örnek, bazı boşlukların eklenmesi kullanılarak çok daha okunabilir hale getirilebilir. Bu test edilmemiştir, ancak şu fikri elde edersiniz:

<% question = (question.size > 20) ? question.question.slice(0, 20) + "..." \
                                   : question.question 
%>

Ya da daha deyimsel olarak daha çok yazılmış:

<% question = if (question.size > 20)
                question.question.slice(0, 20) + "..."
              else 
                question.question 
              end
%>

Okunabilirliğin question.questionde çok sıkıntı çektiğini iddia etmek kolay olurdu .


1
Çok satırlıysa, neden sadece ... başka ... son ise kullanmıyorsunuz?
Wayne Conrad

1
Perl ve C'de uzun yıllar çalıştığı için mi? Duruma ve birinin görsel olarak diğerinden daha net olup olmadığına bağlı olarak da kullanıyorum. Bazen çok / ayrıntılı ise, bazen?: Çirkin.
Tin Man

1
@WayneConrad Eğer bu cevapta açıklanan en az bir sorun varsa: stackoverflow.com/a/4252945/2597260 / ternary if / ternary operatörü kullanmanın birkaç yolunu karşılaştırın: gist.github.com/nedzadarek/0f9f99755d42bad10c30
Darek Nędza

Neden köşeli parantez koydunuz true?
Zac

1
Çünkü trueaslında trueveya olarak değerlendirilen bir ifade için oturuyor false. Üçlü ifadeler hızlı bir şekilde görsel gürültüye dönüşerek sürdürülebilirliği etkileyen okunabilirliği azaltabildiğinden, bunları görsel olarak sınırlamak daha iyidir.
Tin Man

3

Operatörün oyuncunun kimliğinin 1 olup olmadığını kontrol ettiği ve sonuca bağlı olarak düşman kimliğini ayarladığı basit bir örnek

player_id=1
....
player_id==1? enemy_id=2 : enemy_id=1
# => enemy=2

Konuyla ilgili oldukça yararlı görünen bir yazı buldum .


4
Neden olmasın enemy_id = player_id == 1 ? 2 : 1?
Aaron Blenkush

1
@AaronBlenkush Zarif giriş için teşekkürler. Hala çaylak seviyesindeyim, muhtemelen nedeni budur :)
devwanderer

0

Kod condition ? statement_A : statement_Bşuna eşdeğerdir:

if condition == true
  statement_A
else
  statement_B
end

0

En kolay yol:

param_a = 1
param_b = 2

result = param_a === param_b ? 'Same!' : 'Not same!'

o zamana param_aeşit olmadığından param_b, resultdeğeriNot same!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.