¿Cómo obtengo el nombre de la clase de los padres en Ruby?

85

Supongamos que tengo clases Ay Bdonde Bhereda A. ¿Cómo imprimo el nombre de la clase principal enB

class A
end

class B < A
end

Algunas cosas que he probado

>> B.new.class #=> B   #which is correct
>> B.new.parent  #=> Undefined method `parent`
>> B.parent   #=> Object
>> B.parent.class #=> Class

Gracias :)

Rahul Tapali
fuente
4
cuando B.methods.sortesté atascado así, intente siempre en irb. Tal vez algo le dé una pista sobre el nombre del método que busca.
Ivaylo Strandjev
@IvayloStrandjev Eso no ayudará. Hay demasiados métodos para revisar. Es una perdida de tiempo.
sawa
@sawa no es cierto. Me tomó 30 segundos. Lo suficiente para que otros usuarios sean más rápidos que yo, pero bastante rápidos.
Ivaylo Strandjev
8
@checkit: ¡mucho más simple! 8.methods.grep(/class/)Ni siquiera necesitas ordenar con este tipo de filtrado :)
Sergio Tulentsev
@SergioTulentsev ¡¡bueno !! será realmente útil :)
Rahul Tapali

Respuestas:

133
class A
end

class B < A
end

B.superclass # => A
B.superclass.name # => "A"
Sergio Tulentsev
fuente
62

Si desea la pila de ancestros completa, intente:

object.class.ancestors

Por ejemplo:

> a = Array.new
=> []
> a.class.ancestors
=> [Array, Enumerable, Object, Kernel, BasicObject]
James S.
fuente
1
Tenga en cuenta que también incluye módulos incluidos en una clase. Puede ver Arrayseguido de Enumerable, que no es un padre, sino un módulo incluido en Array . Si solo quieres las clases, puedes hacer algo como Array.ancestors.select { |ancestor| ancestor.is_a? Class } #=> [Array, Object, BasicObject].
3limin4t0r
18

Dado un objeto (clase instanciada) puede derivar la clase principal

>> x = B.new
>> x.class.superclass.name
=>"A"
wwright
fuente
16

En caso de que Google traiga a alguien que esté trabajando en Rails, lo que puede querer es base_class, ya superclassque atravesará la estructura de herencia de ActiveRecord también.

class A < ActiveRecord::Base
end

class B < A
end

> A.superclass
=> ActiveRecord::Base
> B.superclass
=> A

> A.base_class
=> A
> B.base_class
=> A

Aún más...

class C < B
end

> C.base_class
=> A

En otras palabras, base_classle da la parte superior del árbol de herencia, pero limitado al contexto de su aplicación. Sin embargo, una advertencia justa, en lo que respecta a Rails, "tu aplicación" incluye cualquier gema que estés usando, por lo que si tienes un modelo que subclasifica algo definido en una gema, base_classdevolverá la clase de la gema, no la tuya.

Joel Fouse
fuente
8

El término que estás buscando es superclass. Y de hecho puedes hacer B.superclasspara conseguirlo A. (También puede hacer B.ancestorspara obtener una lista de todas las clases y módulos de los que hereda, algo así como [B, A, Object, Kernel, BasicObject]).

Arrojar
fuente
2

La herencia es una relación entre dos clases. La herencia crea una relación padre-hijo entre clases. Es un mecanismo para la reutilización del código y para permitir extensiones independientes del software original a través de clases e interfaces públicas. El beneficio de la herencia es que las clases inferiores en la jerarquía obtienen las características de las superiores, pero también pueden agregar características específicas propias. .

En Ruby, una clase solo puede heredar de otra clase. (es decir, una clase puede heredar de una clase que hereda de otra clase que hereda de otra clase, pero una sola clase no puede heredar de muchas clases a la vez). La clase BasicObject es la clase padre de todas las clases en Ruby. Por lo tanto, sus métodos están disponibles para todos los objetos a menos que se anulen explícitamente.

Ruby supera la herencia de una sola clase de una vez usando el mixin.

Intentaré explicarlo con un ejemplo.

module Mux
 def sam
  p "I am an module"
 end
end
class A
  include Mux
end
class B < A
end
class C < B
end
class D < A
end

Puede rastrear usando class_name.superclass.name y hacer este proceso a menos que encuentre BasicOject en esta jerarquía. BasicObject es una superclase para todas las clases. supongamos que queremos ver el árbol de jerarquía de la clase C.

 C.superclass
   => B
 B.superclass
  => A
 A.superclass
  => Object
 Object.superclass
  => BasicObject

Puede ver toda la jerarquía de la clase C. Apunte a tener en cuenta que con este enfoque no encontrará módulos que estén incluidos o antepuestos en las clases principales.

Existe otro enfoque para encontrar la jerarquía completa, incluidos los módulos. Según los antepasados ​​de Ruby doc . Devuelve una lista de módulos incluidos / antepuestos en el mod (incluido el propio mod).

C.ancestors
 => [C, B, A, Mux, Object, Kernel, BasicObject]

Aquí, Mux y Kernel son módulos.

http://rubylearning.com/satishtalim/ruby_inheritance.html https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)

Mukesh Kumar Gupta
fuente