2012-06-13 27 views
4

我有foo.gem,裏面有lib/foo.rb如何自動將Gem包含在路徑中?

當我添加寶石的Gemfile它的foo.rb在我的道路自動必需的。但我需要自動包含它。原因是我在做控制檯擴展,我希望他們在沒有我寫'include Foo'的情況下可用。

我與

SOME_CLASS.send(:include, Foo) 

但不知道是什麼類的實驗用把它添加到路徑例如當我開始自動包含的控制檯時。這裏有一些自動包含在控制檯中的mixin,我需要我的在那裏:)謝謝

irb(main):006:0> self.class.included_modules 
=> [PP::ObjectMixin, JSON::Ext::Generator::GeneratorMethods::Object, ActiveSupport::Dependencies::Loadable, Kernel] 

P.S.

我能解決初始化問題,但我不想改變項目的代碼,我只想補充的寶石,它的工作原理。

回答

1

內,您應該使用Kernel模塊,這是由Object包括在內。這也正是私有方法,如exitputsrequire定義,所以它是用於定義必要的API的最佳選擇。

當你擴展Object,人們希望能夠顯式調用任何對象的方法,他們也明白,你的方法取決於對象的狀態。

Kernel方法理解不同。儘管它們在技術上對所有物體都可用,但你不希望人們寫下類似的東西:

'some string'.sleep 1000 

這沒有任何意義。 sleep與字符串無關;它不以任何方式依賴於它。只應該用一個隱含的接收器來調用,就好像self這個概念不存在一樣。

使你的方法私人和延長Kernel,而不是幫助你更清楚該消息。


你可以做,在foo.rb

module Foo 
    # … 
end 

Some::Class.send :include, Foo 

當你loadrequire一些文件,它是由逐行執行。您可以將任意代碼放入文件中的任何位置,即使在模塊和類定義中也是如此。你可以利用這一點,以便正確設置你的圖書館,使其他人不必。

+1

我想讓它在控制檯中可用,「某些類」是一個關於使用什麼的問題。事實證明,它適用於'Object.send(:include,Foo)'。 –

+0

@Dolphin,對不起,我誤解了你的問題。我已經更新了我的答案,其中有幾個原因可以代替您使用'Kernel'。 –

+0

你說得對,在'Kernel'中使用它更有意義。似乎有錯誤或一些內部工作,我不明白哪些需要我做'Kernel.send(:include,self)',並且在將'Kernel'重新包含到'Object'之後,因爲它不工作它,'Object.send(:include,Kernel)'。 底線方法以'Object'結尾,即使它是更多行代碼,通過封裝到'Kernel'也是更好的方法。你能否提出我可以用這些核心Ruby工作更好地教育自己的材料? –

1

你有沒有試過

Object.send(:include,Foo) 

self.send(:include,Foo) 

控制檯

+0

使用'Object.send'工作。不知道是否有更好的類來使用它,而不是使用Object,對於這個看起來太普通了。但它的作品:)謝謝。 –