English 中文(简体)
如何动态调用类而不使用eval?
原标题:
  • 时间:2009-02-03 18:33:13
  •  标签:

下面的eval语句是否可以被摆脱?下面的代码会过滤所有派生自BaseClass类型的类。然后这些类会被实例化,并调用方法hello。

module MySpace

  class BaseClass
    def hello; print "
hello 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, I m just a noisy class
hello world, class A was here

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

最佳回答
c = MySpace.const_get(e)
问题回答

eval is the only way I know of to turn a string into a constant. Its even the way rails does it: http://api.rubyonrails.com/classes/Inflector.html#M001638

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

你看过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




相关问题
热门标签