2012-07-03 15 views
5

Me gustaría extender un objeto Ruby con un módulo, pero quiero poder cambiar qué módulo usar en tiempo de ejecución y tengo la capacidad de variar esto por objeto. En otras palabras, me gustaría pasar el nombre del módulo al extend como un parámetro. ¿Cómo puedo hacer esto?¿Cómo puedo extender un objeto en ruby ​​con un módulo cuyo nombre se da en un parámetro?

He intentado lo siguiente:

module M1 
end 

module M2 
end 

class C 
    def initialize module_to_use 
    extend module_to_use 
    end 
end 

m = get_module_name_from_config_file 
c1 = C.new m 

(Suponiendo que el método get_module_name_from_config_file devuelve un String con el nombre del módulo deseado - aquí tampoco "M1" o "M2".)

Pero conseguir esto:

error: wrong argument type String (expected Module). 

porque m es de tipo String, no Module, obviamente. Lo intenté con m siendo un símbolo también, pero me sale el mismo problema (reemplace String con Symbol en el mensaje de error).

Entonces, ¿puedo convertir m en algo así como el tipo Module? ¿O hay otra forma en que puedo lograr esto?

Gracias de antemano.

+0

¿Funciona algo así con const_get? http://stackoverflow.com/questions/2361347/how-to-convert-a-string-to-a-constant-in-ruby – jstim

Respuesta

5

Usted puede hacerlo de esta manera (modificado para utilizar const_get por sugerencia de Jörg W Mittag)

module M1 
end 

module M2 
end 

class C 
    def initialize module_to_use 
    extend module_to_use 
    end 
end 

m = Module::const_get("M1") 
c1 = C.new m 

Usted tuvo algunos errores en el código anterior, por cierto - class y module debe estar en minúsculas.

+2

Por favor, no. No hay absolutamente ninguna necesidad de usar 'eval' aquí. Solo usa 'const_get'. –

+0

@ JörgWMittag: lo siento. fijo. – Peter

+0

Gracias chicos, eso funciona a la perfección. He corregido la capitalización en la pregunta original también. –

Cuestiones relacionadas