2017-02-21 43 views
0

Не могли бы вы помочь мне? Я разрабатываю камень, он имеет модуль:Как требовать модуль от 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 

Как я могу это достичь? И что вы думаете о autoload? было обещано обесценить эту способность, но новые версии рубинов по-прежнему имеют автозагрузка метод.

Спасибо!

ответ

1

Я думаю, что если вы создаете классы на верхнем уровне и наследуют их из пространствами имен классов, он должен работать, т.е.

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

require 'cherry_user' 
CherryUser.new 

В противном случае вам, возможно, потребуется определить открытый интерфейс для ваших методов в классе CherryUser верхнего уровня, который вызовет методы, которые вам нужны в вашем SDK (может быть, лучше организовать для вашего публичного API)

Также лучшей практикой было бы имеют

#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, который, в свою очередь, загрузить код пользователя, также будет меньше классов добавлены в глобальное пространство имен, которое, как правило, хорошо

2

Вы всегда можете включать в себя модули, чтобы получить доступ к своим классам в текущей области видимости класса:

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/

+0

Спасибо за ваш ответ. Но могу ли я настроить свой камень, чтобы пользователь не мог использовать ** include **? Может ** включать ** автоматически выполняться в драгоценном камне? – Vasilina

+1

вы можете использовать движок rails для этого: http://stackoverflow.com/questions/7066040/automatic-include-a-gem-in-a-controller, иначе я бы рекомендовал придерживаться хорошего старого поведения. – Esse

+0

Большое спасибо! :) – Vasilina

 Смежные вопросы

  • Нет связанных вопросов^_^