1. ホーム
  2. ruby

[解決済み】Rubyモジュールをインクルードせずに、そのインスタンスメソッドを呼び出すことはできますか?

2022-04-13 03:28:03

質問

背景

いくつかのインスタンスメソッドを宣言しているモジュールがあります。

module UsefulThings
  def get_file; ...
  def delete_file; ...

  def format_text(x); ...
end

そして、これらのメソッドのいくつかをクラスの中から呼び出したいのです。通常、rubyでこれを行うには、次のようにします。

class UsefulWorker
  include UsefulThings

  def do_work
    format_text("abc")
    ...
  end
end

問題点

include UsefulThings を持ち込む すべて のメソッドのうち UsefulThings . この場合、私が欲しいのは format_text を必要とせず、明示的に get_filedelete_file .

これには、いくつかの解決策が考えられますね。

  1. メソッドをどこにもインクルードせず、モジュール上で直接呼び出す。
    • これがどのように/できるのかわかりません。(それゆえ、この質問)
  2. 何らかの形で含む Usefulthings で、そのメソッドの一部だけを取り込みます。
    • また、このようなことができるのか、どうすればできるのかわかりません。
  3. プロキシクラスを作成し、インクルード UsefulThings を作成し、その中で format_text をそのプロキシインスタンスに
    • これならうまくいくのですが、匿名プロキシクラスはハックされます。うっせーよ。
  4. モジュールを2つ以上の小さなモジュールに分割する
    • この方法も有効で、おそらく私が考えられる最善の解決策なのですが、何十ものモジュールが増殖してしまうので、できれば避けたいところです。

なぜ、一つのモジュールに関係のない機能がたくさんあるのですか?それは ApplicationHelper 私たちのチームは、他の場所に属するほど特殊でないものの捨て場所として事実上決定した、railsアプリのものです。ほとんどがスタンドアローンのユーティリティメソッドで、どこでも使われるものです。私はそれを別々のヘルパーに分割することができましたが、それらのすべてが1つのメソッドを持つ30があります...これは非生産的であると思われます。

解決方法は?

モジュール上のメソッドがモジュール関数になった場合、Modsからそのメソッドを呼び出すだけで、あたかもそれが

module Mods
  def self.foo
     puts "Mods.foo(self)"
  end
end

以下のmodule_functionのアプローチは、すべてのModsを含むクラスを壊さないようにするものです。

module Mods
  def foo
    puts "Mods.foo"
  end
end

class Includer
  include Mods
end

Includer.new.foo

Mods.module_eval do
  module_function(:foo)
  public :foo
end

Includer.new.foo # this would break without public :foo above

class Thing
  def bar
    Mods.foo
  end
end

Thing.new.bar  

しかし、そもそもなぜ無関係な関数のセットが同じモジュールに収まっているのかが不思議です。

編集 の場合にもインクルードが機能することを示すためです。 public :foo が呼び出された後に module_function :foo