Sıfır mı yoksa sıfır mı olduğunu görmek için bir değeri kontrol etmenin kısa bir yolunu arıyorum. Şu anda şöyle bir şey yapıyorum:
if (!val || val == 0)
# Is nil or zero
end
Ama bu çok sakar görünüyor.
Yanıtlar:
or
Burada herhangi parens gerektirmez ve deneyimli bir Rubyist doğal tamamen okuyacaktır. Hiç ısırması sadece insanlar ||
karşı or
:) Perl programlanmış hiç insanlardır
val && val == 0
iyi olduğunu düşünüyorum .
Sonunda soru işareti olan yöntem adlarını gerçekten seviyorsanız:
if val.nil? || val.zero?
# do stuff
end
Çözümünüz, diğer çözümlerden birkaçı gibi gayet iyi.
Ruby, dikkatli değilseniz, her şeyi yapmanın güzel bir yolunu aramanızı sağlayabilir.
Ruby 2.3.0'dan itibaren, güvenli gezinme operatörünü ( &.
) Numeric#nonzero?
. &.
döndüren nil
örnek olsaydı nil
ve nonzero?
- sayı ise 0
:
unless val&.nonzero?
# Is nil or zero
end
Veya postfix:
do_something unless val&.nonzero?
unless val&.nonzero?
yapmazsak, bunun "değer sıfır mı yoksa sıfır mı" anlamına geldiğini anlamam biraz zaman alacaktı
do_something if val&.nonzero?
(yani sıfır val
değilse nil
ve sıfır değilse).
Öncelikle, bu belirli durumu kontrol etmenin en kısa yolu olduğunu düşünüyorum.
İkincisi, bana göre bu, tasarımınızda olası bir kusuru gösteren bir kod kokusu. Genel olarak sıfır ve sıfır aynı anlama gelmemelidir. Mümkünse, bu koda ulaşmadan önce, ya yöntemin başında ya da başka bir mekanizmada kontrol ederek, değerin sıfır olma olasılığını ortadan kaldırmaya çalışmalısınız.
Bunu yapmak için tamamen meşru bir nedeniniz olabilir, bu durumda kodunuzun iyi olduğunu düşünüyorum, ancak en azından mümkünse sıfır kontrolünden kurtulmayı düşünürüm.
Object.nil'i kullanabilir misiniz? sıfır için özel olarak test etmek (ve yanlış ve sıfır arasında kalmamak). Bir yöntemi Object'e de maymun yamalayabilirsiniz.
class Object
def nil_or_zero?
return (self.nil? or self == 0)
end
end
my_object = MyClass.new
my_object.nil_or_zero?
==> false
İş arkadaşlarınızın Nesne değişikliklerini izlemesi zor olduğundan ve kodunuzu başkaları için öngörülemez hale getirebileceğinden bu önerilmez.
nil?
her zaman yanlış döndürür. nil?
yalnızca NilClass üzerinde true döndürür.
Object
, NilClass
ve Numeric
. Object
dönecekti false
, NilClass
dönecekti true
ve Numeric
dönecekti zero?
.
nil.to_i sıfır döndürür, bu yüzden bunu sık sık yaparım:
val.to_i.zero?
Bununla birlikte, val, #to_i'ye yanıt vermeyen bir nesne ise bir istisna alırsınız.
"5".to_i == 5, but you're more or less right. Clever but doesn't actually work
Kodunuzun yanlış olduğuna inanıyorum; : bir bakıma bu testte üç değerler için olacak nil
, false
ve sıfır. Bunun nedeni, !val
ifadenin yanlış olan tüm değerler için doğru olmasıdır, Ruby'de nil
ve false
.
Şu anda bulabileceğim en iyi şey
if val == nil || val == 0
# do stuff
end
Elbette ki pek akıllıca değil, ama (çok) açık.
Benim çözümüm de Koşullar hariç Ayrıntılandırmaları kullanıyor.
module Nothingness
refine Numeric do
alias_method :nothing?, :zero?
end
refine NilClass do
alias_method :nothing?, :nil?
end
end
using Nothingness
if val.nothing?
# Do something
end
Rails bunu öznitelik sorgulama yöntemleriyle yapar; burada false ve nil'e ek olarak, 0 ve "" de false olarak değerlendirilir.
if (model.attribute?) # => false if attribute is 0 and model is an ActiveRecord::Base derivation
Bununla birlikte, aleyhte payına sahiptir. http://www.joegrossberg.com/archives/002995.html
#attribute
çünkü böyle bir şey bulamıyorum.
Mümkün olduğunca deyimsel olmak için bunu öneririm.
if val.nil? or val == 0
# Do something
end
Çünkü:
Kısa ve net
[0, nil].include?(val)
val.in? [0,nil]
En kısa ve en iyi yol olmalı
if val&.>(0)
# do something
end
İçin val&.>(0)
ne zaman val nil yana nil döner> temelde Ruby için yanlış eşit sıfırdır, aynı zamanda bir yöntemdir. Ne zaman yanlış döner val == 0
.
Bunu bir "var mı?" yöntem, daha sonra çeşitli sınıflarda farklı şekilde uygulayabilirim. Yani Array için "nedir?" "beden> 0" anlamına gelir; Fixnum için "self! = 0" anlamına gelir; String için "self! = ''" anlamına gelir. NilClass elbette "eşittir?" sadece sıfır olarak dönüyor.
İsterseniz kullanabilirsiniz case
:
case val with nil, 0
# do stuff
end
O zaman işe ===
yarayan her şeyi kullanabilirsiniz , ki bu bazen güzeldir. Veya bunun gibi bir şey yapın:
not_valid = nil, 0
case val1 with *not_valid
# do stuff
end
#do other stuff
case val2 with *not_valid, false #Test for values that is nil, 0 or false
# do other other stuff
end
Tam olarak iyi bir OOP değil, ama çok esnek ve işe yarıyor. Benim if
silerim genellikle case
zaten biter .
Tabii ki Enum.any?
/ Enum.include?
türden de işe yarar ... gerçekten şifreli olmayı seviyorsanız:
if [0, nil].include? val
#do stuff
end
Yapılması gereken doğru şey elbette bir yöntem veya işlev tanımlamaktır. Ya da aynı şeyi birçok değerle yapmanız gerekiyorsa, bu güzel yineleyicilerin bir kombinasyonunu kullanın.
Gerçekten Raylar gibi blank?
şeyler için bu tür yöntemle, ancak dönmeyecek true
için0
. Böylece yönteminizi ekleyebilirsiniz:
def nil_zero?
if respond_to?(:zero?)
zero?
else
!self
end
end
Ve bazı değerlerin sıfır mı yoksa 0 mı olduğunu kontrol edecek:
nil.nil_zero?
=> true
0.nil_zero?
=> true
10.nil_zero?
=> false
if val.nil_zero?
#...
end
Maymun bir sınıfa yama yapmak yerine, iyileştirmeler kullanabilirsiniz. Ruby 2.1'den başlayarak . İyileştirmeler maymun yamasına benzer; bu, sınıfı değiştirmenize izin verir, ancak değişiklik, onu kullanmak istediğiniz kapsam ile sınırlıdır.
Bu kontrolü bir kez yapmak istiyorsanız, bu aşırıdır, ancak kendinizi tekrarlıyorsanız, maymun yamasına harika bir alternatiftir.
module NilOrZero
refine Object do
def nil_or_zero?
nil? or zero?
end
end
end
using NilOrZero
class Car
def initialize(speed: 100)
puts speed.nil_or_zero?
end
end
car = Car.new # false
car = Car.new(speed: nil) # true
car = Car.new(speed: 0) # true
Kapsamı dosyaya eklenmek üzere son dakikada ayrıntılandırmalar değiştirildi . Yani daha önceki örnekler bunu göstermiş olabilir ve bu işe yaramayacaktır.
class Car
using NilOrZero
end
Bu çok kısa:
if (val || 0) == 0
# Is nil, false, or zero.
end
Bu sürece tedavi sakıncası olarak çalışıyor false
aynı nil
. Üzerinde çalıştığım projelerde, bu ayrım sadece arada bir önem taşıyor. Geri kalan zamanlarda kişisel olarak atlamayı .nil?
ve biraz daha kısa kod kullanmayı tercih ederim .
[ Güncelleme : Artık bu tür şeyler yazmıyorum. Çalışıyor ama çok şifreli. Yaptığım birkaç yeri değiştirerek suçlarımı düzeltmeye çalıştım.]
Bu arada, söz gelimi bir dizge ise .zero?
bir istisna yarattığı için kullanmadım val
. Ama .zero?
durumun böyle olmadığını bilirseniz iyi olur.
[edited]
val
Sıfır olsaydı bu ifadenin değerlendirileceğini nil == 0
(ve böylece geri döneceğini false
) düşündüm . Yine de öyle görünüyor ki aslında işe yarıyor, ancak çok okunabilir olduğunu düşünmüyorum.
Başka bir çözüm:
if val.to_i == 0
# do stuff
end
"5".to_i == 5
ama az ya da çok haklısın. Zekice ama aslında işe yaramıyor.
val ||= 0
if val == 0
# do something here
end
val
tutulması gerekiyorsa? Bu yöntemle giriş verilerini bozuyorsunuz ve sıfır veya sıfır olup olmadığını kontrol etmenin daha iyi, daha az yıkıcı yolları var.
false
?