Ruby'de bir nesnenin türünü belirleme


364

Aradığım şeyin bir örneği olarak python kullanacağım (Python'u bilmiyorsanız sözde kod olarak düşünebilirsiniz):

>>> a = 1
>>> type(a)
<type 'int'>

Ruby'de yapabileceğimi biliyorum:

1.9.3p194 :002 > 1.class
 => Fixnum 

Ancak bu, nesnenin türünü belirlemenin uygun yolu mu?


5
@ JörgWMittag Yine de hafızam bulanık olsa da AFAICR Python'da `` type` '' yapıyor. isinstance Yanıtları kontrol etmeniz veya kontrol etmeniz gerekir . Ama basitçe "NOES !!!" gerçekten yararlı değil, şimdi, değil mi? Bunun yerine eğitici olmayı düşünün.
Dave Newton

4
@ JörgWMittag Sempatik olduğum halde OP, Ruby'de taklit etmek için kod sağladı. Aslında sürece eğitmek OP diyerek kabul etmeyenler IMO, yararlı değildir. Ve yapsanız bile, muhtemelen sadece bilgi amaçlı olacaktır, çünkü OP kod aracılığıyla ne istediğini tanımladı.
Dave Newton

5
@ JörgWMittag - Ruby'de her şey bir Nesnedir, bu yüzden Python'da (int, long, boolean vb.) Olduğu gibi ilkel tipler yoktur, Ruby'de sonuç olarak sınıflar tip tanımlarıdır. Bu Ruby ile de sınırlı değildir, sınıf ve tür kelimesi diğer bazı dillerde ve daha geniş olarak OOP teorisinde eş anlamlıdır.
ocodo

6
Burada Ruby hakkında gerçekten konuştuğumuz için, Türler ve Sınıflar eşanlamlıdır, bununla ilgili bir tartışma yoktur, tüm değerler Nesnelerdir. Yani basitçe Ruby hakkında konuşurken herkes için, Sınıflar olan tipleri. - ref: ruby-lang.org/en/about
ocodo

2
@ JörgWMittag Bu deneme şu ana kadar oldukça bilgilendirici ve bir şans bulduğumda geri kalanını okuyacağım. Özellikle Cook, Python, Ruby ve diğer dinamik olarak yazılmış dillerin " gerçekten nesne olmadığını" iddia etmenin (profesörlerimden biri gibi) neden yanlış olduğunu oldukça iyi ifade ediyor (ve benden daha fazla arka plan bilgisine sahip). yönelimli "(muhtemelen farkında olmadan, ADT odaklı olmamalarıydı). Ancak Ruby statik olarak yazılmamıştır, bu nedenle Cook'un tanımladığı anlamda ADT'leri yoktur, bu nedenle bu ayrım temelinde itirazlarınız yardımcı olmaz.
Kyle Strand

Yanıtlar:


607

Ruby dünyasında titrek bir terim olan bir nesnenin "türünü" belirlemenin doğru yolu çağırmaktır object.class.

Sınıflar diğer sınıflardan miras alabileceğinden, bir nesnenin "belirli bir türden" olup olmadığını belirlemek istiyorsanız, türden mi object.is_a?(ClassName)yoksa objecttürden ClassNamemi türediğini görmek için çağırabilirsiniz .

Normalde tür denetimi Ruby'de yapılmaz, bunun yerine nesneler genellikle " Ördek yazma " olarak adlandırılan belirli yöntemlere yanıt verme yeteneklerine göre değerlendirilir . Başka bir deyişle, istediğiniz yöntemlere yanıt veriyorsa, tür hakkında özel olmanız için bir neden yoktur.

Örneğin, object.is_a?(String)başka bir sınıf onu bir dizeye dönüştüren yöntemler uygulayabileceği veya String'in davranış biçimiyle aynı şekilde davranabileceği için çok katıdır. object.respond_to?(:to_s)söz konusu nesnenin istediğini yaptığını test etmenin daha iyi bir yolu olurdu.


13
-1. #classyok değil nesne türünü döndürür, onun döndüren sınıfını . İsim ölü bir hediye olmalı. Sınıf ve Tür, OO'da tamamen farklı iki kavramdır.
Jörg W Mittag

78
@ Jörg W Mittag: Katılıyorum. "Sınıf" ve "işlemci hızı" (örnek seçmek için) tamamen farklı iki kavramdır, ancak "sınıf" ve "tip" birbiriyle yakından ilişkili kavramlardır. Örneğin , Sınıf hakkındaki Wikipedia makalesi şöyle der: "Nesne yönelimli programlamada, sınıf, farklı bir türü tanımlamak için kullanılan bir yapıdır." tadman soru soran kişiye yardımcı oldu.
Teemu Leisti

18
@ JörgWMittag Ruby'de typeofC, JavaScript ve diğerlerine en yakın şey class. Ruby'de diğer dillerde olduğu gibi resmi bir protokol sistemi yoktur, Objective-C buna göre en yakın Smalltalk'tır. "Tür" olarak "kabul edilebilir sonuçlarla belirli bir yöntem kümesine yanıt veren" nesne olarak tanımlıyorsanız, bunu iddia etmenin hiçbir yolu yoktur. Çok gevşek. Çoğu zaman Ruby'de bir nesnenin türüne atıfta bulunurken, sınıftan bahsettiğiniz anlaşılmaktadır. Bu nedenle, terim türünü tırnak içinde kullandım.
tadman

14
@ Jörg W Mittag: Alıntıda gösterildiği gibi “sınıf” ve “tip” in OO'da kesinlikle tamamen farklı kavramlar olmadığını iddia etmeye devam ediyorum. (Ayrıca: nasıl vererek Java bir değişken ilan ediyorum ya türünü veya sınıfını ": Adından ardından değişkenin, int i" ya da " Integer jtadman hem soru soran tatmin gibiydi bir bakıma soruya".) ve genel izleyici, Ruby'nin kullandığı terminolojiyi açıklığa kavuştururken Nesneye yönelik terminolojinin daha ince noktaları üzerinde akademik saç ayrımına girmekle ilgilenmiyorum, bu yüzden lütfen son sözü söyleyin.
Teemu Leisti

11
@TeemuLeisti Buradaki sorunların çoğu, Ruby'deki her şeyin bir nesne olması ve dolayısıyla bir sınıfa sahip olmasından kaynaklanırken , hemen hemen her dilde , nesne olmayan ve sınıfı olmayan ilkel tipler , nesnelerin aksine. Saf bir tür diye bir şey olmadığında ve resmi olarak tanımlamanın bir yolu olmadığında, anlam Ruby dünyasında özellikle puslu hale gelir. Matz, buradakinden başka herhangi bir düşünce okuluna sıkı sıkıya bağlı değildir.
tadman

81

ayrıca deneyebilirsiniz: instance_of?

p 1.instance_of? Fixnum    #=> True
p "1".instance_of? String  #=> True
p [1,2].instance_of? Array #=> True

44

Genellikle Ruby'de, nesnenin sınıfının ne olduğunu umursamazsınız, aslında, sadece belirli bir yönteme cevap vermesini umursarsınız. Bu Ördek Yazma olarak bilinir ve her türlü Ruby kod tabanında görürsünüz.

Pek çok durumda (en çok değilse), Ördek Yazma'yı kullanarak en iyisi #respond_to?(method):

object.respond_to?(:to_i)

1
geçerli nokta. soruyu cevaplamıyor ama sorunun ruhuna çarpıyor.
user566245

@ user566245 iyi yanıt verir_to? (: the_question), ama dediğin gibi soruyu cevaplamıyor, sadece ilgili bilgileri veriyor. Cevapların soruyu cevaplaması gerektiğinden oldukça eminim.
R.Rincón

17

Evet derim". "Matz" görüşmelerinden birinde böyle bir şey söylediği gibi, "Ruby nesnelerinin türü yoktur." Hepsi değil, bize karşı karşıya gelmeye çalıştığı kısım. Neden herkes "Herşey bir Nesnedir" demişti? Eklemek için "Verilerin nesne değil Türleri var" dedi.

Yani bundan zevk alabiliriz.

https://www.youtube.com/watch?v=1l3U1X3z0CE

Ancak Ruby sadece sınıfın nesnesinin türünü önemsemiyor. Türleri değil sınıfları kullanıyoruz. Tüm verilerin bir sınıfı vardır.

12345.class

'my string'.class

Onların ataları da olabilir

Object.ancestors

Ayrıca meta sınıfları var ama size bununla ilgili ayrıntıları kaydedeceğim.

Sınıfı öğrendikten sonra, bunun için hangi yöntemleri kullanabileceğinizi arayabilirsiniz. Burada "veri türü" gereklidir. Eğer gerçekten ayrıntılara girmek istiyorsanız yukarı bak ...

"Yakut Nesne Modeli"

Bu, Ruby'nin nesneleri işleme biçiminde kullanılan terimdir. Her şey içseldir, bu yüzden bunların çoğunu gerçekten göremezsiniz ama bilmek güzel. Ama bu başka bir konu.

Evet! Sınıf, veri türüdür. Nesnelerin sınıfları ve verilerin türleri vardır. Veri tabanları hakkında bilgi sahibi olursanız, yalnızca sınırlı bir tür kümesi olduğunu bilirsiniz.

metin blokları numaraları


Örneğin,Object.ancestors # => [Object, Kernel, BasicObject]
Dorian
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.