2009-02-03 110 views
0

是否有可能摆脱下面的评估声明?下面的代码过滤掉从BaseClass类型派生的所有类。之后,这些类将被实例化,并调用方法'hello'。如何在不使用eval的情况下动态调用类?

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 

所以执行后的输出结果是:

世界你好,我只是一个吵吵闹闹的班级
的Hello World,A类在这里

我认为没有必要使用的eval是邪恶的。而且我不确定是否使用eval这里是强制性的。动态调用“BaseClass”类型的所有类是否有更明智的方法?

回答

4
c = MySpace.const_get(e) 
0

你看过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 
相关问题