Ruby: if değişkeni vs if değişkeni.nil?


11

Ruby'de yeniyim ve tüm nesnelerin sıfır ve yanlış dışında doğru olduğunu öğrendiğimde şaşırdım. 0 bile doğrudur.

Dilin bu özelliği hakkında güzel bir şey yazabilmenizdir:

if !variable
  # do stuff when variable is nil
end

Daha deneyimli Ruby geliştiricileri olan meslektaşlarım, .nil kullanmak yerine bunu seçmem konusunda ısrar ediyorlar. şöyle:

if variable.nil?
  # do stuff when variable is nil
end

Bununla birlikte, ikincisinin iki nedenden dolayı daha iyi bir seçenek olduğuna inanıyorum: 1. Bence özellikle nesne her şeyin bir nesne ve mesaj alışverişi olduğu Ruby gibi bir dilde daha nesne odaklı. 2. Benim görüşüme göre, daha az kompakt olsa bile, daha okunabilir.

Burada bir "acemi" hatası mı yapıyorum?


4
Nil için test ediyor musun? ya da yanlış bir değer?

Nil için test ediyorum. Temelde değişken nil ise, bir şey yaparım (ya da değil)
Javier Holguera

3
Nil için test yapıyorsanız, neden false için testin bu bloğa girmesini istersiniz?

Kabul ediyorum, bunu .nil'i tercih etmek için başka bir neden olarak işaret ettim. Ancak "if do x if"
ifadesinin

Yanıtlar:


17

Ne demek istediğini yaz. Ne yazdığınızı kastedin.

Farklı bir test yapalım. .vowel?

if char == 'a'
   # do stuff
end

vs

if char.vowel?
   # do stuff
end

Şimdi, bunların aynı şeyi yapmadığı açıktır. Ama sadece bekliyor Eğer charolması aveya bişe yarayacak. Ancak bir sonraki geliştiriciyi karıştırır - ikinci blok, karakterin olduğu koşullar için de girilecektir [eiou]. Ancak a, düzgün çalışacaktır.

Evet, bu durumda nilve falseRuby sadece falsy değerlerdir. Ancak, test nilederek test nil || falseediyorsanız, demek istediğiniz bu değil.

Bu, bir sonraki geliştiricinin (ev adresinizi bilen çılgın bir balta cinayeti olur) kodu okuyacağı ve neden falseoraya girmesi gerektiğini merak edeceği anlamına gelir .

Tam olarak ne demek istediğinizi ileten kodu yazın .


3

Aşağıdakileri göz önünde bulundur:

response = responses.to_a.first

Bu responses, veya öğesinin ilk öğesini döndürür nil. Çünkü koşullu ifadeler yazabildiğimiz nilgibi davrandığından false:

response = responses.to_a.first
if response
  # do something ('happy path')
else
  # do something else
end

Hangi daha okunabilir:

if response.nil?
  # do something else
else
  # do something ('happy path')
end

if (object)Desen Yakut kodunda çok yaygındır. Aynı zamanda güzelce yeniden düzenlemeye yol açar, örneğin:

if response = responses.to_a.first
  do_something_with(response)
else
  # response is equal to nil
end

Ayrıca, Ruby yönteminin nilvarsayılan olarak döndüğünü unutmayın. Yani:

def initial_response
  if @condition
    @responses.to_a.first
  else
    nil
  end
end

basitleştirilebilir:

def initial_response
  if @condition
    @responses.to_a.first
  end
end

Böylece daha fazla refactor yapabiliriz:

if response = initial_response
  do_something_with(response)
else
  # response is equal to nil
end

Artık geri dönmenin nilher zaman en iyi fikir olmadığını iddia edebilirsiniz , çünkü nilher yerde kontrol etmek anlamına gelir . Ama bu başka bir balık su ısıtıcısı. Nesne "varlığı ya da yokluğu" için test yapılmasının çok sık bir gereklilik olduğu düşünüldüğünde, nesnelerin gerçekliği, dile yeni gelenler için şaşırtıcı olsa da, Ruby'nin yararlı bir yönüdür.


2

Sadece if variable.nil?doğal dil gibi değil , aynı zamanda yanlışlıkla bir falsedeğer atayan ve ifadenize düşen bir programcıya karşı da koruma sağlar if, çünkü Ruby gevşek bir şekilde yazılmış bir dildir.


1
Orijinal sorudaki ilk yorum yanlış mıydı? "Değişken sıfır veya yanlış olduğunda bir şeyler yapmalı" mıydı? Yorumla eşleşmeyen kod bir hata olduğu için hemen bir hata mı var?
gnasher729

Doğru. Basit bir doğruluk testi mantık hatalarına neden olabilir.
Greg Burghardt

0

Deyimsel olarak, unless variabletercih edilir if !variable. Olumsuz ififadeler genellikle kod çözme sırasında olumsuzluğu kaçırmak daha kolay olduğu için bir kod kokusu olarak kabul edilir.

Buradaki daha büyük resim, bunun nilgibi kontroller yapmanın bir kod kokusu olması. Düzgün OO için, bu tür bir kontrole asla ihtiyaç duyulmaması için null nesne modelini kullanmayı hedefleyin. http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness/

Nesnelere ne yapmaları gerektiğini söyleyin, ne olduklarını sormayın. Bu bazen söyleme sorma olarak bilinir

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.