【问题标题】:How to autoload a class in ruby如何在 ruby​​ 中自动加载一个类
【发布时间】:2017-07-27 20:52:48
【问题描述】:

我有一个模块如下

-MyClass 类 lib/a/b/myclass.rb 的路径

module A
  module B
    class MyClass
      puts 'inside myclass'
    end
  end
end

现在我想从根目录中的文件自动加载上述类。 文件名:dostuff

def main
  autoload A::B:MyClass,'a/b/myclass.rb' #path is correct , getting error here
  c = A::B:MyClass.new
end

main

出现错误:uninitialized constant A::B::MyClass (NameError)

如果我按如下方式使用 require 并删除自动加载代码,一切正常。

require 'a/b/myclass' 

【问题讨论】:

  • 我的班级还是我的班级?
  • 在您的 LOAD_PATH 中是否为 lib
  • 请忽略错别字。如果我使用 require 'a/b/myclass' 加载模块,一切正常。但我想出于其他原因使用自动加载。 lib 在我的加载路径中。
  • @SergioTulentsev 你能帮我解决这个问题吗?

标签: ruby autoload


【解决方案1】:

您对自动加载器的要求太高了。它实际上一次只能处理一个级别。这意味着您需要通过在单独的文件中表达每个模块或类来实现这一点:

# a.rb
module A
  autoload(:B, 'a/b')
end

# a/b.rb
module A::B
  autoload(:MyClass, 'a/b/my_class')
end

# a/b/my_class.rb
class A::B::MyClass
end

然后就可以自动加载A了:

autoload(:A, 'a')

A::B::MyClass.new

在 Ruby 中拥有 main 函数也是非常规的。通常,您只需将代码放在已称为 main 的上下文中的顶层。

【讨论】:

  • :感谢您的回答。但是为什么我不能从主目录自动加载 A::B::MyClass?仅通过样板自动加载到下一个嵌套模块来创建模块是一种浪费。还有其他解决方法吗?
  • 这是因为在您的代码中您引用了尚不存在的A::B,所以它爆炸了。尽管这可能看起来很混乱,但它更传统并且使组织代码更容易。这就是人们期望你的库在文件系统上的布局方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-27
  • 2015-11-02
  • 2011-07-31
相关资源
最近更新 更多