1

クラスにいくつかの関数があります。関数ごとに、実行前に何を呼び出すか、実行後に何を呼び出すかを指定できるようにしたいと考えています。

たとえば、関数が a、b、c、d、および e であるとします。次のようなことをしたい:

before: [:a, :b, :c], execute: :before_func
after: [d, e], execute: :after_func

上記を達成するために使用できる宝石やテクニックはありますか?

バックグラウンド:

私のクラスは、基本的には ftp からファイルを読み取るクラスです。クラス インスタンスの作成時に初期化される @ftp 変数を宣言し、必要に応じて ftp からの読み取りを試みたり、ftp で他の操作を実行したりします。操作が近くで発生した場合は機能しますが、そうでない場合はタイムアウトになります。したがって、各関数の前に、現在の @ftp を閉じ、新しい接続を再度開いて使用したいと考えています。関数が終了したら、ftp 接続を閉じたいと思います。私はすでにほとんどの関数を書いているので、接続を開く関数と接続を閉じる関数の 2 つの関数を宣言するだけです。

4

2 に答える 2

2

define_methodとを介して ruby​​ メタ プログラミングを使用できますalias_method_chain。おそらく次のようになります。

module MethodHooks

  def before(*symbols)
    hook=symbols.pop
    symbols.each { |meth|
      define_method :"#{meth}_with_before_#{hook}" do |*args, &block|
        self.send hook, *args, &block
        self.send :"#{meth}_without_before_#{hook}", *args, &block
      end
      alias_method_chain meth, :"before_#{hook}"
    }
  end

  def after(*symbols)
    hook=symbols.pop
    symbols.each { |meth|
      define_method :"#{meth}_with_after_#{hook}" do |*args, &block|
        self.send :"#{meth}_without_after_#{hook}", *args, &block
        self.send hook, *args, &block
      end
      alias_method_chain meth, :"after_#{hook}"
    }
  end
end

Object.extend(MethodHooks)

次に、任意のクラスで使用します。

before :a, :b, :c, :before_func
after :a, :b, :c, :after_func

上記の (テストされていない) コードは、インスタンス メソッドをフックするためのアイデアを示していますが、必要に応じてクラス メソッドに適応させることもできます。

于 2013-09-16T15:32:22.337 に答える
0

基本的に、Rails でアスペクト指向プログラミングを行うことを検討しています。

おそらく、この宝石が役立つかもしれませんhttps://github.com/davesims/simple-aop

于 2013-09-16T15:33:59.643 に答える