2012-02-06 16 views
6

Tengo tres objetos que son todos de la misma clase. Uno fue creado a través de Item.new y los otros dos fueron extraídos de la base de datos (Mongoid). Estoy pasando uno/ninguno de estos objetos a otro método y la comprobación del tipo en que el método a través is_a?:¿por qué would .is_a? y .class dan resultados contradictorios?

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

Pues bien, este aumento está siendo golpeado. Así que compruebo la clase, is_a y instance_of en la consola de rails. Estoy obteniendo resultados conflictivos. ¿Por qué tendrían el mismo class pero solo uno de ellos sería un instance_of que 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 

¿Hay alguna manera mejor de hacer este tipo de comprobación de mis entradas? ¿Por qué tres cosas que son de la misma clase no son todas instancias de esa clase?

+0

* ¿* Son la misma clase? Por ejemplo, las asociaciones de AR afirman que son Array, pero no lo son. –

+1

¿Se puede agregar la salida de 'i0.class.object_id' y lo mismo para otros objetos? Puede ser que tenga algo que ver con la recarga de clases y tienes dos instancias diferentes de la misma clase. –

+0

@DaveNewton bien, ¿hay una mejor manera de investigar una clase y es un tipo de cosas? – jcollum

Respuesta

3

No sé Mongoid, pero normalmente, en una biblioteca de acceso a base de datos, no se obtiene el objeto real de la base de datos, sino un objeto proxy que actúa como sustituto del objeto almacenado en el DB. Como a Ruby le faltan las funciones para implementar un proxy transparente perfecto, a veces verá resultados extraños, especialmente cuando utiliza la reflexión o alrededor de la identidad del objeto.

2

Inspirado en el @ KL-7 comentarios, debe estar pasando especie de que:

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

Ya, el mismo problema aquí ...

Problema resuelto (bypass) con am fea:

i0.class.to_s==Item.to_s 
Cuestiones relacionadas