如何从gem要求模块使用没有命名空间的类?

时间:2017-02-21 10:52:43

标签: ruby-on-rails ruby rubygems

你能帮帮我吗? 我正在开发gem,它有一个模块:

#cherry/sdk/high_level.rb
 module Cherry
  module SDK
   module HighLevel
    autoload :CherryUser, 'cherry/sdk/high_level/user'
    autoload :CherryCard, 'cherry/sdk/high_level/card'
   end
  end
 end

现在我这样使用它:

 require "cherry/sdk/high_level"
 user = Cherry::SDK::CherryUser.new
 card = Cherry::SDK::CherryCard.new

但我需要用户使用我没有命名空间的宝石类,即

 require "cherry/sdk/high_level"
 user = CherryUser.new
 card = CherryCard.new

我怎样才能实现它? 您还如何看待自动加载? 它被承诺贬低这种能力,但新的ruby版本仍然有自动加载方法。

谢谢!

2 个答案:

答案 0 :(得分:3)

您始终可以包含模块以访问当前类范围内的类:

module Cherry
  module SDK
    module HighLevel
      class CherryUser
      end
    end
  end
end

# require "cherry/sdk/high_level"
include Cherry::SDK::HighLevel
user = CherryUser.new # => #<Cherry::SDK::HighLevel::CherryUser:0x007f9c09185ab8>

关于自动加载 - 它被认为是不好的做法,你应该避免它。这篇文章非常好:http://urbanautomaton.com/blog/2013/08/27/rails-autoloading-hell/

答案 1 :(得分:1)

我认为如果你在顶级创建类并从命名空间类继承它们,它应该可以工作,即

#cherry_user.rb
class CherryUser < Cherry::SDK::HighLevel::CherryUser
end

require 'cherry_user'
CherryUser.new

否则,您可能需要在顶级CherryUser类中为您的方法定义公共接口,这将调用您在SDK中需要的方法(可能更好地组织起来设置您的公共API)< / p>

更好的做法是

#lib/cherry/user.rb
module Cherry
  class User < Cherry::SDK::HighLevel::CherryUser
  end
end

#lib/cherry.rb
require 'cherry/user'

# in user code
Cherry::User.new

这样捆绑器会自动需要lib / cherry.rb,这反过来会加载用户代码,也会有更少的类添加到全局命名空间,这通常是好的