programacion - variable de clase ruby
¿Es posible obtener todas las clases propias en Ruby? (3)
Dudo que esto es lo que quieres, pero debería devolver todas las clases propias:
eigens = ObjectSpace.each_object.collect { |obj| class << obj; self; end }
Eso ciertamente asignará una matriz de todas las clases propias a los eigen variables. La cuestión es que las implementaciones de Ruby probablemente no creen una clase de genes a menos que sea necesaria, y este código (en mi opinión) creará las clases propias incluso para los objetos en los que no se necesita uno.
Si la búsqueda de una mejor manera es importante, enviaría un tweet a uno de los implementadores de cualquiera de las implementaciones de Ruby (@yukihiro_matz, @evanphx, @headius, por nombrar algunas que se le ocurran). Si alguien supiera, lo harían.
Obtener una lista de todos los módulos es fácil en Ruby:
ObjectSpace.each_object(Module).to_a
Sin embargo, ¿es posible obtener una lista de todas las clases propias (también conocidas como clases simples o metaclases)? ¿O son eigenclasses invisibles?
Lo intenté
str = "foo"
my_metaclass = class << str; self; end
my_metaclass.class == Class # my_metaclass'' class is Class
ObjectSpace.each_object(Class).include?(my_metaclass) # false
ObjectSpace.each_object.include?(my_metaclass) # still false
# Just to show each_object works
ObjectSpace.each_object(Class).include?(String) # true
Estoy tratando de obtener eigenclasses porque quiero enumerar todos los métodos que están definidos dentro de un script. Podría buscar todos los métodos de instancia definidos por módulos y clases, y luego buscar métodos singleton de módulos y clases (o de todos los objetos, si quiero masticar CPU), pero eso parece un poco hackish.
Si se refiere a objetos que tienen métodos singleton, esto debería funcionar.
eigens = []
ObjectSpace.each_object do |object|
eigens << object unless object.singleton_methods.empty?
end
Si no, ¿podrías aclarar? Usé esta discusión como referencia:
A partir de MRI 1.9, la enumeración de las clases propias NO parece ser compatible. Como una (semi) consecuencia, no hay una manera fiable del 100% de iterar sobre todos los métodos. La mejor aproximación para un enumerador de método general es la siguiente
methods = []
ObjectSpace.each_object { |x|
if x.kind_of?(Module)
methods += x.public_instance_methods(false) +
x.protected_instance_methods(false) +
x.private_instance_methods(false)
end
methods += x.singleton_methods(false)
}
Sin embargo, este código NO enumerará
- métodos privados propiedad de 1st clases propias,
- métodos propiedad de 2nd, 3rd, ... eigenclasses.