Ruby'de bir değişkenin bir dizge olup olmadığını kontrol edin


Yanıtlar:


205

Ben aradığınız düşünüyorum instance_of?. is_a?ve kind_of?türetilmiş sınıflardan örnekler için true döndürür.

class X < String
end

foo = X.new

foo.is_a? String         # true
foo.kind_of? String      # true
foo.instance_of? String  # false
foo.instance_of? X       # true

9
Sorunun amacını bilmeden, çoğu gerçek dünya programlama durumu için, is_a?aslında kullanılacak daha uygun deyim olduğunu söyleyebilirim (ve genellikle Andrew Grimm'in bahsettiği gibi bir ördek yazım denetimi daha da iyidir). Katı bir sınıf karşılaştırması genellikle bir kod kokusudur. en.wikipedia.org/wiki/Liskov_substitution_principle
mahemoff

Çabuk kenara: eğer bunu koşullu mantıkta kullanırsanız parantez kullanmanız gerekir; örneğin, eğer foo.is_a? (String) && ...
dan

Beklendiği gibi, bu yaklaşım yalnızca ile Stringdeğil, Integerve ile de çalışacaktır Float. Bunun için de çalışıyor Decimalmu? (yüce metin yorumlayıcısı sözdizimini farklı şekilde vurgular ve Decimalbu beni şüphelendirir)
stevec

29

Daha ördek yazarak bir yaklaşım söylemek olurdu

foo.respond_to?(:to_str)

to_str bir nesnenin sınıfının String'in gerçek bir soyundan gelmeyebileceğini, ancak nesnenin kendisinin daha çok dizeye benzer (stringy?) olduğunu belirtir.


Güzel. Bu durumda ben verdiğini biliyorum fooya olacak true, falseya da bir vanilya dize, ama onun iyi daha genel çözümler öğrenmek için.
davidchambers

nesnenin yanıt verip vermediğini kontrol ettikten sonra bunu bir to_s çağrısıyla birleştirin ve kendinize bir dizge elde edin!
seanmakesgames

1
@seanmakesgames Bunu mu demek istediniz to_str , veya to_s? İkisi biraz farklı.
Andrew Grimm


23

Yapabilirsin:

foo.instance_of?(String)

Ve daha genel:

foo.kind_of?(String)

4
kind_ofDaha genel yapan nedir ? Onlar eşanlamlı olarak görünmektedir: is_a.
davidchambers

2
@Davidchambers haklısın, 'kind_of?' is_a ile eşanlamlıdır.
steenslag

@davidchambers: Haklısın, instance_of?bunun yerine demek istedim is_a?.
Federico Builes

7
foo.instance_of? String

veya

foo.kind_of? String 

eğer sadece Stringmiras zincirinin yukarısında bir yerden alıkonulmasını umursuyorsan


4

Diğer yanıtlara ek olarak Class, bir nesnenin o sınıfın bir örneği olup olmadığını test etmek için === yöntemini tanımlar.

  • o.class sınıfı o.
  • o.instance_of? c, o.class == c olup olmadığını belirler
  • o.is_a? c o, c'nin bir örneği mi yoksa alt sınıflarından biri mi?
  • o.kind_of? c * is_a? * ile eşanlamlıdır
  • c === o Bir sınıf veya modül için, * o.is_a olup olmadığını belirleyin. c * ( String === "s" true değerini döndürür)

-1

Bence daha iyi bir yol, bazı yüklem metotları yaratmaktır. Bu aynı zamanda "Tek Kontrol Noktası" nızı da kaydedecektir.

class Object
 def is_string?
   false
 end
end

class String
 def is_string?
   true
 end
end

print "test".is_string? #=> true
print 1.is_string?      #=> false

Daha fazla ördek yazma yolu;)


2
neyin var "string".is_a?(String). Görünüşe göre tekerleği yeniden icat ediyorsun. Orada da class, instance_of, kind_of, maymun yama vb ... Kötü bir fikir Objectsınıfı, bu gereksiz söz değil.
Mohamad

Size tamamen katılıyorum :) Eğer odak noktanız yalnızca ilkel türler üzerindeyse ve ilkel türlerle ilgili proje gereksinimlerinizin asla değişmeyeceğini biliyorsanız (tamam, genellikle böyledir;)) iyisiniz. Ancak gereksinimlerin değiştiği bir durumda "Tek Kontrol Noktasına" sahip olmak daha iyidir. Örneğin, proje ortamınızda çok sayıda ön kontrolünüz var (1000 ve üzeri). pre_check("test".is_string?) Artık proje gereksiniminiz değişecek ve üç veya daha fazla karakter içeren her String artık String olarak tanımlanmayacak (sıradışı olduğunu biliyorum;)) Artık kendi yönteminizi kolayca değiştirebilirsiniz.
schlegel11
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.