Ruby: kind_of? frente a instancia_de? ¿contra is_a?

¿Cuál es la diferencia? ¿Cuándo debería usar cuál? ¿Por qué hay tantos de ellos?

kind_of? y is_a? son sinónimos instance_of? es diferente de los otros dos en que solo devuelve true si el objeto es una instancia de esa clase exacta, no una subclase.

Ejemplo: "hello".is_a? Object "hello".is_a? Object y "hello".kind_of? Object "hello".kind_of? Object devuelve true porque "hello" es un String and String es una subclase de Object . Sin embargo, "hello".instance_of? Object "hello".instance_of? Object devuelve false .

¿Cuál es la diferencia?

De la documentación:

– ( Boolean ) instance_of?(class)
Devuelve true si obj es una instancia de la clase dada.

y:

– ( booleano ) is_a?(class)
– ( booleano ) kind_of?(class)
Devuelve true si class es la clase de obj , o si class es una de las superclases de obj o módulos incluidos en obj .

Si no está claro, sería bueno saber qué es exactamente lo que no está claro, para que la documentación se pueda mejorar.

¿Cuándo debería usar cuál?

Nunca. Usa polymorphism en su lugar.

¿Por qué hay tantos de ellos?

No llamaría dos “muchos”. Hay dos de ellos, porque hacen dos cosas diferentes.

Es más parecido a Ruby preguntar a los objetos si responden a un método que necesites o no, usando respond_to? . Esto permite tanto una interfaz mínima como una implementación que desconoce la progtwigción.

No siempre es aplicable, por supuesto, por lo que todavía hay una posibilidad de preguntar acerca de una comprensión más conservadora del “tipo”, que es clase o clase base, utilizando los métodos que está preguntando.

Tampoco llamaría dos muchos ( is_a? Y kind_of? Son alias del mismo método), pero si quiere ver más posibilidades, dirija su atención al método #class :

 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