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]

附言

我可以用初始化程序解决问题,但我不想更改项目的代码,我只想添加 gem 并且它可以工作。

4

2 回答 2

1

你试过了吗

Object.send(:include,Foo)

或者

self.send(:include,Foo)

在您的控制台内

于 2012-06-13T11:38:32.467 回答
1

您应该使用该Kernel模块,它包含在. 它是定义私有方法的地方,例如,和,因此它是定义命令式 API 的绝佳选择。 Objectexitputsrequire

当您扩展时Object,人们希望能够在任何对象上显式调用您的方法,并且他们也明白您的方法取决于该对象的状态。

Kernel方法理解不同。尽管它们在技术上对所有对象都可用,但您不希望人们编写如下内容:

'some string'.sleep 1000

这是没有意义的。sleep与字符串无关;它不以任何方式依赖它。它应该只使用隐式接收器调用,就好像self根本不存在的概念一样。

将您的方法设为私有并Kernel改为扩展可以帮助您传达该信息。


你可以这样做foo.rb

module Foo
  # …
end

Some::Class.send :include, Foo

当您loadrequire某些文件时,它会逐行执行。您可以将任意代码放在文件中的任何位置,甚至在模块和类定义中。您可以利用它来正确设置您的库,以便其他人不必这样做。

于 2012-06-13T11:44:49.343 回答