Ruby: nazikçe? instance_of? is_a mı?


487

Fark ne? Hangisini ne zaman kullanmalıyım? Neden bu kadar çok var?


18
Neden hem gelince is_a?ve kind_of?vardır: Ben Ruby'nin tasarım felsefesi 's kısmını varsayalım. Python, bir şey yapmanın tek bir yolu olması gerektiğini söylerdi; Ruby genellikle eşanlamlı yöntemlere sahiptir, böylece daha iyi görünen yöntemi kullanabilirsiniz. Bu bir tercih meselesi. Kısmen Japon etkisinden kaynaklanıyor olabilir: Güzel görünmesi için cümle bağlı olarak aynı sayı için farklı bir kelime kullanacakları söylendi. Matz bu fikri dil tasarımına taşımış olabilir.
Nathan Long

@NathanLong Japon sayaçlarının bununla çok fazla ilgisi olduğunu düşünmüyorum; tüm dillerin bir tür anlaşması vardır ve bir sayacı çoğu zaman bir başkasıyla değiştiremezsiniz (örneğin, silindir sayacını düz nesneler için kullanamazsınız; bu sadece yanlış). Ve anlambilimle, euphony'den daha fazlası vardır.
Casey

Yanıtlar:


621

kind_of?ve is_a?eşanlamlıdır.

instance_of?diğer ikisinden farklıdır, çünkü yalnızca truenesne bir alt sınıf değil, tam sınıfın bir örneğiyse döner .

Misal:

  • "hello".is_a? Objectve "hello".kind_of? Objectdönüş trueçünkü "hello"bir Stringve Stringbir alt sınıfıdır Object.
  • Ancak "hello".instance_of? Objectgeri döner false.

77
Bazen daha iyi okunur. Düşün @honda.kind_of? Carve @person.is_a? AdministratorRuby'nin estetiğe dair her şeyi. Aslında, dilbilgisi hatasına dikkat edin ... aktif destekle şunları yazabilirsiniz:) @person.is_an? Administrator... Bu şimdiye kadar Ruby çekirdeğine dönüşmüş olabilir aslında.
rfunduk

2
heh ilginç bir sebep. Bunu kırabilir misin, sen? gibi geçersiz kılabilirsin kind_of?ama değil is_a?mi?
Claudiu

3
@ thenduks, is_an?ruby-1.9.2-p0 içinde değil. @Claudiu, hayır. is_a?sadece bir takma addırkind_of? . Her iki yöntem de aynı c işlevini çağırır rb_obj_is_kind_of.
11:57

9
@Matt: Diğer adı geçersiz kılma işlevini geçersiz kılmadan geçersiz kılabilirsiniz. Yani evet, geçersiz kind_of?kılmadan geçersiz kılabilirsiniz is_a?.
sepp2k

4
Bu ActiceSupport is_an?yöntemi nerede ?! Mevcut raylar sürümünde değil ve google'da da kullanımdan kaldırıldığına dair bir şey bulamıyorum.
Tom Lord

22

Fark ne?

Belgelerden:

- ( Boole )instance_of?(class)
Verilen sınıfın bir örneği olup trueolmadığını döndürür obj.

ve:

- ( Boolean ) is_a?(class)
- ( Boolean )kind_of?(class)
Sınıfının veya sınıfının üst sınıflarından veya modüllerinden birinin sınıfı olup trueolmadığını döndürür .classobjclassobjobj

Bu net değilse, tam olarak neyin belirsiz olduğunu bilmek güzel olur , böylece dokümantasyon iyileştirilebilir.

Hangisini ne zaman kullanmalıyım?

Asla. Bunun yerine polimorfizm kullanın.

Neden bu kadar çok var?

Ben iki "çok" demezdim. İki tane var, çünkü iki farklı şey yapıyorlar.


3
Sanırım karışıklığım 3 olduğu ve bu ikisinin aynı şeyi yapması ve farklı isimlere sahip olmasıydı. Çok biçimlilik kullanma hakkında - Katılıyorum, ama yakut standart kütüphane bunların her birinin kullanımıyla dolu
Claudiu

4
Polimorfizm ile ne demek istiyorsun? Ördek yazmakla aynı mı?
Andrew Grimm

2
Evet, hepsi aynı. Ördek yazımı bir çeşit polimorfizmdir.
SpaceGhost

3
Polimorfizm yapmak genellikle daha iyidir, evet, ancak dosyalarla uğraşırken olduğu gibi belirli bir sınıfınızın olduğunu gerçekten bilmek istediğiniz sınır durumları vardır.
Automatico

6

Nesneleri kullanarak ihtiyacınız olan bir yönteme yanıt verip vermediklerini sormak Ruby'ye daha benzerdir respond_to?. Bu, hem minimal arayüz hem de uygulamadan habersiz programlama sağlar.

Tabii ki her zaman uygulanamaz, bu nedenle, sorduğunuz yöntemleri kullanarak, sınıf veya temel sınıf olan "tip" in daha muhafazakar bir şekilde anlaşılmasını isteme olasılığı vardır.


5
Duruma göre değişir. Hem Yorum hem de Blog oluşturulan_at öğesine yanıt verebilir. Böyle bir durumda? daha uygun IMHO
penkovsky

Bu bir anlam ifade etmez, bir Yorum ile bir Blog nesnesini birbirinden ayırmanız gerekiyorsa, bunu yapmak için create_at kullanamazsınız. Bu, created_at öğesine yanıt veren bir nesneyi alan bir yöntem yazabileceğiniz anlamına gelmez. İşini yapmak için başka bir şeye ihtiyaç duymazsa, Yorumda veya Blog'da veya diğer herhangi bir ActiveRecord modelinde güvenle kullanabilirsiniz.
Kingdon

3

Ayrıca iki tane çok çağırmam ( is_a?ve kind_of?aynı yöntemin takma adları), ancak daha fazla olasılık görmek istiyorsanız, dikkatinizi #classyönteme çevirin :

A = Class.new
B = Class.new A

a, b = A.new, B.new
b.class < A # true - means that b.class is a subclass of A
a.class < B # false - means that a.class is not a subclass of A
# Another possibility: Use #ancestors
b.class.ancestors.include? A # true - means that b.class has A among its ancestors
a.class.ancestors.include? B # false - means that B is not an ancestor of a.class

1
Teşekkür - ı gerçekten "what çalışma zamanı tür bilgileri Ruby toplandı ve nasıl olabilir" genel anlamda soruyordu - ve bu yeterli örnekler sağlar
Claudiu
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.