如何在不使用eval的情况下动态调用类?

时间:2009-02-03 18:33:13

标签: ruby eval

是否有可能摆脱下面的 eval 声明?下面的代码过滤掉从BaseClass类型派生的所有类。之后,这些类被实例化,并调用方法'hello'。

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

执行后输出为:

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

我认为不必要地使用 eval 是邪恶的。而且我不确定在这里是否必须使用 eval 。是否有一种更智能的方法可以动态调用“BaseClass”类型的所有类?

3 个答案:

答案 0 :(得分:4)

c = MySpace.const_get(e)

答案 1 :(得分: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

答案 2 :(得分:0)

eval是我知道将字符串转换为常量的唯一方法。它甚至是rails的方式: http://api.rubyonrails.com/classes/Inflector.html#M001638

奇怪的是常量返回字符串。