Come richiamare le classi in modo dinamico senza l'utilizzo di eval?
Domanda
È possibile sbarazzarsi di eval istruzione, di seguito?Il codice riportato di seguito filtra tutte le classi che derivano dal tipo di BaseClass.Successivamente, le classi sono istanziati e metodo 'ciao' è chiamato.
module MySpace
class BaseClass
def hello; print "\nhello world"; end
end
class A<BaseClass
def hello; super; print ", class A was here"; end
end
class B<BaseClass
def hello; super; print ", I'm just a noisy class"; end
end
MySpace.constants.each do | e |
c=eval(e)
if c < BaseClass
c.new.hello
end
end
end
Così, dopo l'esecuzione l'output è:
ciao mondo, sono solo un pò di classe
ciao mondo, la classe A è stato qui
Penso che l'uso inutile di eval è il male.E io non sono sicuro se l'uso di eval è obbligatorio qui.C'è un modo più intelligente nel richiamare tutte le classi dal tipo "BaseClass" in modo dinamico?
Soluzione
c = MySpace.const_get(e)
Altri suggerimenti
eval è l'unico modo che conosco per trasformare una stringa in una costante.Suo anche il modo in cui le rotaie fa:http://api.rubyonrails.com/classes/Inflector.html#M001638
La cosa strana è che le costanti restituisce stringhe.
Hai guardato class_eval
invece?
------------------------------------------------------ Module#class_eval mod.class_eval(string [, filename [, lineno]]) => obj mod.module_eval {|| block } => obj ------------------------------------------------------------------------ Evaluates the string or block in the context of _mod_. This can be used to add methods to a class. +module_eval+ returns the result of evaluating its argument. The optional _filename_ and _lineno_ parameters set the text for error messages. class Thing end a = %q{def hello() "Hello there!" end} Thing.module_eval(a) puts Thing.new.hello() Thing.module_eval("invalid code", "dummy", 123) produces: Hello there! dummy:123:in `module_eval': undefined local variable or method `code' for Thing:Class