Me encanta the autoload functionality of Ruby; sin embargo, es going away in future versions of Ruby ya que nunca fue seguro para subprocesos.Clases de carga automática en Ruby sin su `autoload`
Así que en este momento me gustaría fingir que ya se ha ido y escribir mi código sin él, por implementando el mecanismo de carga lenta yo. Me gustaría implementarlo de la manera más sencilla posible (no me importa la seguridad de hilos en este momento). Ruby debería permitirnos hacer esto. inicio
Vamos mediante el aumento de una clase const_missing
:
class Dummy
def self.const_missing(const)
puts "const_missing(#{const.inspect})"
super(const)
end
end
Ruby llamar a este método especial cuando tratamos de hacer referencia a una constante bajo 'dummy' que le falta, por ejemplo, si tratamos de hacer referencia a "Dummy: : Hola ", llamará al const_missing
con el símbolo :Hello
. Esto es exactamente lo que necesitamos, así que vamos a ir más lejos:
class Dummy
def self.const_missing(const)
if :OAuth == const
require 'dummy/oauth'
const_get(const) # warning: possible endless loop!
else
super(const)
end
end
end
Ahora bien, si hacemos referencia "Dummy :: OAuth", se requerirá el archivo "maniquí/oauth.rb" que se espera para definir el " Dummy :: OAuth "constante. Existe la posibilidad de un ciclo infinito cuando llamamos al const_get
(ya que puede llamar al const_missing
internamente), pero evitar eso está fuera del alcance de esta pregunta.
El gran problema es que toda esta solución se rompe si existe un módulo llamado "OAuth" en el espacio de nombres de nivel superior. Al hacer referencia a "Dummy :: OAuth" se saltará el const_missing
y simplemente devolverá el "OAuth" del nivel superior. La mayoría de las implementaciones de Ruby también harán una advertencia acerca de esto:
warning: toplevel constant OAuth referenced by Dummy::OAuth
This was reported as a problem way back in 2003 pero no pudieron encontrar evidencia de que el equipo central Ruby era siempre preocupado por esto. Hoy en día, las implementaciones más populares de Ruby tienen el mismo comportamiento.
El problema es que const_missing
se salta silenciosamente a favor de una constante en el espacio de nombres de nivel superior. Esto no sucedería si se declarara "Dummy :: OAuth" con la funcionalidad de Ruby autoload
. ¿Alguna idea de cómo solucionar esto?
Esto parece como una sugerencia tonta, pero se puede mirar en la fuente de C 'autoload'? Estoy seguro de que puedes encontrarlo en alguna parte de la fuente de Ruby. Si no puede hacerlo en Ruby, existe la opción de crear una extensión C (que tiene acceso a la parte inferior del intérprete). – Linuxios
Es una opción. – mislav
suena como algo de fuerza bruta, pero ¿no podrías 'eliminar_contar' en la clase de nivel superior? – phoet