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 № 1Nie 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