2009-02-03 140 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 
相關問題