如何在ruby中通过文件名获取对象实例

时间:2013-05-27 15:38:21

标签: ruby

ruby​​文件test.rb中有一个类

#test.rb
class AAA<TestCase
  def setUp()
     puts "setup"
  end
  def run()
     puts "run"
  end
  def tearDown()

  end
end

在另一个文件test2.rb中,我想通过文件名“test.rb”获取AAA的实例。 在python中,我可以通过以下方式执行此操作:

casename = __import__ ("test")
for testcase in [getattr(casename, x) for x in dir(casename)]:
    if type(testcase) is type and issubclass(testcase, TestCase):
             #do something with testcase()

我现在如何在ruby中实现相同的功能。 感谢

1 个答案:

答案 0 :(得分:1)

只需要没有.rb扩展名的文件名,如下所示:

require './test'

假设您有此目录结构:

+-- project/
|   |
|   +-- folder1/
|   |   |
|   |   +-- file1.rb
|   |
|   +-- folder2/
|       |
|       +-- file2.rb
|
+-- file3.rb

在这种情况下,您可能希望将特定目录添加到加载路径,如下所示:

# in file3.rb
$LOAD_PATH.unshift './folder1'

这样您可以按名称要求文件,而不必每次都指定文件夹:

require 'file1'

现在为第二部分,获取一个实例。你可以做AAA.new,但我想你想动态创建作为TestCase子类的类的实例。首先,您必须找到TestCase的所有子类:

class Class
  def subclasses
    constants.map do |c|
      const_get(c) 
    end.select do |c|
      c.is_a? Class
    end
  end
end

这将使您能够获得如下的子类列表:

TestCase.subclasses
#=> [TestCase::AAA]

您可以从中构建对象

TestCase.subclasses.map{|klass| klass.new }
#=> [#<TestCase::AAA:0x007fc8296b07f8>]

如果您不需要将参数传递给new

,则更短
TestCase.subclasses.map(&:new)
#=> [#<TestCase::AAA:0x007fc8296b07d0>]

到目前为止,这么好。但是如果我做对了你就试图建立一个测试跑者。别。有很多测试库和优秀的测试运行器。 Ruby有内置的Minitest和this blog post explains very well如何最好地运行测试。