/ / dlaczego miałbym .is_a? i .class dają sprzeczne wyniki? - rubin

dlaczego miałbym .is_a? i .class dają sprzeczne wyniki? - rubin

Mam trzy obiekty, które są tej samej klasy. Jeden został stworzony za pośrednictwem Item.new a pozostałe dwa zostały wyciągnięte z bazy danych (Mongoid). Przekazuję jeden / dowolny z tych obiektów do innej metody i sprawdzam typ w tej metodzie przez is_a?:

def initialize (item, attrs = nil, options = nil)
super(attrs, options)
raise "invalid item object" unless item.is_a?(Item)

Cóż, ta podwyżka zostaje trafiona. Sprawdzam więc klasę, is_a i instance_of w konsoli rails. Mam sprzeczne wyniki, dlaczego mieliby to samo class ale tylko jeden z nich może być instance_of który class?

>> i0.is_a? Item
=> false
>> i1.is_a? Item
=> false
>> i2.is_a? Item
=> true

>> i0.class
=> Item
>> i1.class
=> Item
>> i2.class
=> Item

>> i0.instance_of?(Item)
=> false
>> i1.instance_of?(Item)
=> false
>> i2.instance_of?(Item)
=> true

Czy istnieje lepszy sposób na sprawdzenie tego typu danych wejściowych? Dlaczego trzy rzeczy należące do tej samej klasy nie byłyby instancjami tej klasy?

Odpowiedzi:

3 dla odpowiedzi № 1

Nie znam Mongoida, ale zazwyczaj w dostępie do DBbiblioteki, nie otrzymujesz rzeczywistego obiektu z bazy danych, ale raczej obiekt proxy, który działa jako stand-in dla obiektu przechowywanego w bazie danych. Ponieważ Ruby nie ma funkcji do implementacji idealnego przezroczystego proxy, czasami będziesz widzieć wyniki nieparzyste, zwłaszcza w przypadku korzystania z odbicia lub wokół tożsamości obiektu.


2 dla odpowiedzi nr 2

Zainspirowany komentarzem @ KL-7, musi się to wydarzyć:

class Item; end
class PseudoItem; end

# PseudodItem think it"s an Item:
class << PseudoItem
def inspect
"Item"
end
end

i0 = Item.new
i1 = PseudoItem.new

i0.class         #=> Item (correct!)
i1.class         #=> Item (wrong, due to redefinition of inspect!)

i0.is_a? Item    #=> true
i1.is_a? Item    #=> false, as it is a PseudoItem

0 dla odpowiedzi № 3

Tak, ten sam problem tutaj ...

Problem rozwiązany (ominięty) z brzydką:

i0.class.to_s==Item.to_s