2012-06-13 30 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,对于这个看起来太普通了。但它的作品:)谢谢。 –