如何在模块中加载未知类?

Posted

技术标签:

【中文标题】如何在模块中加载未知类?【英文标题】:How to load a unknown class in a module? 【发布时间】:2011-07-23 10:15:09 【问题描述】:

我有一些 rb 文件,都具有相同的结构:

class RandomName < FooBar
end

randomname 是一个随机类名,在每个 rb 文件中都会发生变化,但都继承自 Foobar。

如何从 rb 文件中加载所有 randomclass?

【问题讨论】:

Best way to require all files from a directory in ruby ? 的可能重复项 不!因为我知道如何要求所有文件,但我不知道如何在里面获取类的实例!如果我不知道班级名称 【参考方案1】:

您可以在 FooBar 类中定义一个名为 inherited 的方法。看here

class FooBar
  def self.inherited(subclass)
    puts "New subclass: #subclass"
  end
end

每次创建子类时,都会在回调中得到它。然后你可以对所有这些子类做任何你想做的事情。

【讨论】:

【参考方案2】:

我认为解决方案有两个部分:

    如何动态实例化一个类

    一个。使用String#constantize from ActiveSupport

    klass = "SomeNamespace::SomeClassName".constantize
    klass.new
    

    b.使用Module#const_get(不处理命名空间)

    klass = const_get(:SomeClassName)
    klass.new
    

    如何检测类名

    在 ruby​​ 中广泛遵循的约定是以文件包含的类命名文件,因此 random_name.rb 将包含 RandomName 类。如果您遵循此约定,那么您可以执行以下操作:

    Dir["/path/to/directory/*.rb"].each do |file| 
      require file 
      file_name = File.basename(file.path, '.rb')
       # using ActiveSupport for camelcase and constantize
      file_name.camelcase.constantize.new 
    end
    

我认为您应该解释您要完成的工作。您采用的方法似乎非常规,并且可能有一种更有效的方法来实现您的目标,而无需执行所有这些文件加载​​和具有随机名称的类的动态实例化。

请记住,仅仅因为 ruby​​ 让您做某事,并不意味着实际去做就是一个好主意!

【讨论】:

【参考方案3】:

我有类似的要求,将类名作为字符串传入。 require 的一个技巧是它不必在开头,所以我更喜欢只加载我需要的类。

我使用 eval 是因为它没有任何 Rails 依赖项(我在这里编写纯 Ruby 代码)。

以下依赖于约定(类在同名文件中),但如果您确实知道类和文件,这种方法的优点是不需要目录中的每个文件,只需动态加载在您需要的时候使用它。

klass = "classname"

begin

    # Load the file containing the class from same directory I'm executing in
    require_relative klass # Or pass a local directory like "lib/#klass"

    # Use eval to convert that string to a Constant (also capitalize it first)
    k = eval(klass.capitalize).new

rescue
    # Do something if the convention fails and class cannot be instantiated.

end

k.foo # Go ahead and start doing things with your new class.

【讨论】:

以上是关于如何在模块中加载未知类?的主要内容,如果未能解决你的问题,请参考以下文章

Xampp:作曲家安装问题:模块 openssl 已在第 0 行的未知中加载

无法从/在 SRAM 中加载/存储数据:读取数据未知

如何在 joomla 2.5 的组件中加载模块

如何在 Angular Electron 中加载模块?

如何在 python 中加载带有参数的 python 模块?

在 MicroPython 中,如何从字符串中加载模块