Wie Klassen dynamisch aufzurufen, ohne mit eval?
Frage
Ist es möglich, unter der eval Erklärung loswerden? Der folgende Code filtert alle Klassen aus, die vom Typ Baseclass abgeleitet werden. Danach werden diese Klassen instanziiert und Methode ‚Hallo‘ genannt wird.
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
So nach der Ausführung der Ausgabe lautet:
Hallo Welt, ich bin nur eine laute Klasse
Hallo Welt, Klasse A war hier
Ich denke, unnötige Verwendung von eval ist böse. Und ich bin nicht sicher, ob die Verwendung von eval ist hier obligatorisch. Gibt es ein intelligenter Weg, um alle Klassen von Typ „Baseclass“ dynamisch aufrufen?
Lösung
c = MySpace.const_get(e)
Andere Tipps
eval ist der einzige Weg, den ich kenne, eine Zeichenfolge in eine Konstante zu drehen. Seine auch die Art und Weise Schienen tut es: http://api.rubyonrails.com/classes/Inflector.html#M001638
Das Seltsame ist, dass Konstanten gibt Strings.
Haben Sie bei class_eval
sah statt?
------------------------------------------------------ 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