0

ActiveRecord のクラス ActionController の拡張機能があります。

module MyExtension
  def my_method
    "default implementation"
  end
end
ActionController::Base.class_eval { include MyExtension }

すべてのコントローラーは から継承しApplicationController、これは から継承しActionController::Baseます。MyExtension継承したクラスにメソッドを追加してオーバーライドしたい

class MyController < ApplicationController
   module MyExtension
     def my_method
       "overridden implementation"
     end
     def my_new_method
       "added method implementation"
     end
   end
 end

次に、特定の Controller クラスの MyExtension で定義されたメソッドを動的に検索したい

controller = Kernel.const_get("MyController")
methods_in_my_extension = Kernel.const_get("MyController::MyExtension").public_instance_methods

MyController::MyExtension定数が定義されていないため、明らかにこれは機能しません。

より一般的な意味で、私が達成したいことは次のとおりです。

  1. から継承するクラスのデフォルトの動作を実装するメソッドをグループ化するActionController::Base

  2. クラス定義でこれらのメソッドをオーバーライドして追加できる

  3. 特定のクラスのグループ化されたメソッドのリストを動的に取得します

編集:なぜ私がこれをやりたいのかについてDeefourに答えて:

コントローラーをラップする CLI メニューを作成しています。コントローラ メソッドを呼び出すには、ユーザーからの入力が必要です。メニューはコントローラーからメソッドを直接収集し、それによって有効なコマンド/入力を定義します。

私が望むのは、新しいレベルのカプセル化、新しいアクセス指定子、CLI メニューからアクセスできるパブリック メソッドのサブセットを定義することです。

メニューで使用可能なすべてのメソッドのプレフィックスを作成するだけでこれを実現できますが、ルビーの内部動作も把握しようとしています。

4

1 に答える 1

0

私はそれを考え出した:

ActionControllerExtension:

module MyExtension
  module MyDefaultImplementations
    def my_method
      "default implementation"
    end
  end
  def get_selected_methods
    default = MyDefaultImplementations.public_instance_methods
    added = Kernel.const_get(self.class.name).const_get("MyImplementation").public_instance_methods
    return (default + added).uniq
  end
end
ActionController::Base.class_eval { include MyExtension }

コントローラー:

class MyController < ApplicationController
  module MyImplementation
    def my_method
      "overridden implementation"
    end
    def my_new_method
      "added method implementation"
    end
  end
  include MyImplementation
end

それは今のところうまくいっているようです。誰かが別の/より良いアプローチを持っているなら、私はそれらを見てみたい. また、大きな注意事項や規約との矛盾がある場合はお知らせください。

于 2012-08-19T15:52:55.557 に答える