Rubyにおけるフックメソッドとメソッド呼び出しへのフックの追加例
2022-01-04 16:49:20
フックメソッドは、特定のイベントが発生した後に特定のコールバック関数を実行できるという点で、イベントドライバと多少似ています。Railsでは、beforeafter関数が最も一般的なフックメソッドです。
class#inheritedメソッドもそのようなフックメソッドの一つで、クラスを継承する際にRubyが呼び出すメソッドです。デフォルトではClass#inheritedは何もしませんが、継承を行うことでそのイベントをインターセプトし、興味のある継承されたイベントに対応することができるのです。
class String
def self.inherited(subclass)
puts "#{self} was inherited by #{subclass}"
end
end
class MyString < String; end
出力します。
String was inherited by MyString
Rubyのクラスやモジュールのライフサイクルに介入できるフックメソッドを利用することで、プログラミングの自由度を大きく向上させることができます。
メソッド呼び出しにフックを追加した例
rubyにはinclude, included, method_missingなどの便利なフックがたくさんあります。メソッド呼び出しにフックを追加するには、aliasを巻き付けることで実現できますが、少し面倒ですし、alias_method_chainはwith_featureメソッドを定義する必要があるので、これも面倒ですので、次のように実装します モジュール、call method_callback :before_method,:after_method after includeでfirst_methodへのフックを追加してください。
module AfterCall
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def after_call when_call,then_call,*args_then,&block_then
alias_method "old_#{when_call}",when_call
define_method when_call do |*args_when,&block_when|
send "old_#{when_call}",*args_when,&block_when
send then_call,*args_then,&block_then
end
end
end
end
class Student
include AfterCall
def enter_class sb
puts "enter class #{sb}"
yield('before') if block_given?
end
private
def after_enter_class pop
puts "after enter class #{pop}"
yield('after') if block_given?
end
protected
def third_after
puts "from third enter"
end
after_call :after_enter_class ,:third_after
after_call :enter_class ,:after_enter_class,"doubi", &lambda {|x|puts "from lambda #{x}"}
end
Student.new.enter_class "1" do |x|
puts "from lambda #{x}"
end
実行結果は以下の通りです。
#enter class 1
#from lambda before
#after enter class doubi
#from lambda after
#from third enter
関連
-
bundlerを使ったRuby環境のインストールと複数バージョンのgemの管理
-
Ruby on Railsフレームワークの設計構造をMVCマインドで理解する
-
Rubyの並列処理とグローバルロック
-
Rubyのオブジェクト指向プログラミングにおけるスコープの簡単な説明
-
デザインパターンのうち、ProxyパターンとDecorativeパターンを使ったRubyのコード例
-
Rubyの4つの比較関数(equal?, eql?, ==, ===)について解説します。
-
Ruby on Railsのパフォーマンスを最適化するためのいくつかの方法についての考察
-
Ruby on Railsのjquery_ujsコンポーネントが遅くなる問題が解決された
-
Rubyの基本文法チュートリアル
-
Rubyの基本構文
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン