Comment appeler dynamiquement des classes sans utiliser eval?
Question
Est-il possible de se débarrasser de la déclaration eval ci-dessous? Le code des filtres ci-dessous toutes les classes qui dérivent de BaseClass de type. Ensuite ces classes sont instanciées et la méthode « bonjour » est appelé.
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
Ainsi, après l'exécution de la sortie est:
Bonjour tout le monde, je suis juste une classe bruyante
Bonjour tout le monde, la classe A était ici
Je pense que l'utilisation inutile de eval est le mal. Et je ne suis pas sûr si l'utilisation de eval est obligatoire ici. Y at-il une façon plus intelligente en invoquant toutes les classes à partir du type « BaseClass » dynamiquement?
La solution
c = MySpace.const_get(e)
Autres conseils
eval est la seule façon que je connaisse pour transformer une chaîne en une constante. Ses même les rails de façon-t-il: http://api.rubyonrails.com/classes/Inflector.html#M001638
La chose étrange est que les constantes renvoie des chaînes.
Avez-vous regardé à la place class_eval
?
------------------------------------------------------ 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