2010-12-15 8 views
5

En mi aplicación, tengo¿Cómo me refiero a la "ruta completa" de un submódulo en ruby?

VeryUniqueModule::Foo 
# and… 
VeryUniqueModule::Bar 

Foo y Bar son cada uno por un servicio diferente. Parte de mi aplicación tiene que calcular de forma dinámica qué módulo para referirse a los que se hace hábilmente, así:

def service_api 
    # @relevant_object.service is a string that is either 'Foo' or 'Bar' 
    VeryUniqueModule.const_get(@relevant_object.service) 
end 

Más sobre esto más adelante.

Acabo de actualizar una biblioteca, y ahora tiene su propia clase de nivel superior Foo (que es un mal diseño de su parte). Ahora cuando intento invocar @relevant_object.service_api::A_CONSTANT, mi aplicación se queja de que la biblioteca Foo no tiene A_CONSTANT.

Volver a service_api anterior - Pensé que const_get devolvía la clase. De hecho, sé que es. Si lo enciendo en irb todo es como esperaba, el valor de retorno es la clase en sí, y puedo invocar cosas en la clase. Entonces ...

  1. ¿Cómo es posible que haya un conflicto de espacio de nombres en primer lugar? Estoy buscando A_CONSTANT en el objeto Clase devuelto por service_api, no en una cadena que soy ing eval o algo funky como que - no debería haber ningún problema de espacio de nombres, me refiero directamente a un objeto !
  2. Si esto es realmente un problema, ¿cómo puedo arreglar service_api para que devuelva el, erm, "ruta completa"?
+0

Lo que estás haciendo parece estar bien. Probablemente haya un error en otro lugar. –

Respuesta

0

Usted puede tratar esto:

VeryUniqueModule.const_get('::VeryUniqueModule::' + @relevant_object.service) 

Y si eso no funciona, puede intentar pasar por service_api y hacer esto siempre que se necesite A_CONSTANT:

Object.const_get('::VeryUniqueModule::' + @relevant_object.service + '::A_CONSTANT') 

Nota del :: antes VeryUniqueModule. No creo que sea estrictamente necesario en este caso, pero podría ser útil porque garantiza que Ruby buscará VeryUniqueModule en el espacio de nombres global y no en algún otro módulo.

+0

No hay forma de que esto funcione. 'const_get' solo acepta el nombre de constante, cualquier' :: 'debe tratarse de otras maneras. Por ejemplo: 'clase A; B = 42; fin; Object.const_get ("A :: B") # => NameError: nombre de la constante incorrecta A :: B' –

Cuestiones relacionadas