【问题标题】:How to get object instance by filename in ruby如何在ruby中通过文件名获取对象实例
【发布时间】:2013-05-27 15:38:21
【问题描述】:

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​​ 中实现相同的功能。 谢谢

【问题讨论】:

标签: ruby


【解决方案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,您可以如何最好地运行测试。

【讨论】:

    猜你喜欢
    • 2011-07-02
    • 2011-12-14
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多