4

私は foo.gem を持っていて、そこlib/foo.rbにあります。

Gemfile に gem を追加すると、パスに 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]

PS

初期化子で問題を解決できますが、プロジェクトのコードを変更したくありません。宝石を追加したいだけで、それが機能することを確認します。

4

2 に答える 2

1

Kernelに含まれているモジュールを使用する必要があります。、、などのプライベートメソッドが定義されている場所であるため、命令型APIを定義するための優れた選択肢です。 Objectexitputsrequire

を拡張するObjectと、人々は任意のオブジェクトに対して明示的にメソッドを呼び出すことができることを期待し、メソッドがそのオブジェクトの状態に依存することも理解します。

Kernel方法は異なって理解されました。それらはすべてのオブジェクトで技術的に利用可能ですが、人々が次のようなことを書くことを期待することはできません。

'some string'.sleep 1000

これは意味がありません。sleep文字列とは何の関係もありません。それは決してそれに依存していません。の概念そのものがself存在しないかのように、暗黙のレシーバーでのみ呼び出す必要があります。

メソッドをプライベートにして拡張Kernelすることで、そのメッセージを伝えることができます。


あなたはでそれを行うことができますfoo.rb

module Foo
  # …
end

Some::Class.send :include, Foo

あなたloadまたはrequireいくつかのファイルの場合、それは行ごとに実行されます。モジュールやクラスの定義内であっても、ファイル内のどこにでも任意のコードを置くことができます。他の人がする必要がないようにライブラリを適切に設定するために、それを利用することができます。

于 2012-06-13T11:44:49.343 に答える
1

試しましたか

Object.send(:include,Foo)

また

self.send(:include,Foo)

コンソール内

于 2012-06-13T11:38:32.467 に答える