メソッドのフック
Posted feedbacks - Ruby
#6029を参考にしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | def add_hook( klass, method, before, after )
klass.instance_eval do
original = instance_method( method )
define_method( method ) do |args|
before.call( self, args )
begin
result = original.bind( self ).call( *args )
rescue Exception => e
after.call( self, args, result, e )
else
after.call( self, args, result, nil )
end
result
end
end
end
add_hook( String, :split, proc{|s,*|puts "split:#{s}"},
proc{|s,a,r,e|puts"return:#{r.inspect}"} )
p 'hoge'.split(//)
|
ログの開始などだろうから、その物には影響を与えない形でしてみます。もちろん返り値には影響を与えません。利用したものはyieldを使ったブロック構文です。こうすると、メソッドチェーンの間に含めることで逐次変数の変化を見ることが出来ますね。お題のように、ログの開始終了もブロックの中に記述すればいいですね。
例)
irb(main):014:0> "1".hook{|x| p x}.to_f.hook{|x| p x}.to_i.hook{|x| p x}
"1"
1.0
1
1
例)
irb(main):014:0> "1".hook{|x| p x}.to_f.hook{|x| p x}.to_i.hook{|x| p x}
"1"
1.0
1
1
1 2 3 4 | def hook
yield self
self
end
|



todogzm
#6017()
Rating1/7=0.14
例えば、あるクラスのあるメソッドを実行する前に他の処理を呼びたい(例えばログやトランザクション開始など)。 また、そのメソッドの終了後にも何らかの後処理を呼びたい(トランザクション終了など)。
そのような、メソッドに対するフック処理を書いてください。 ライブラリを使用してメソッドのフックを実現した場合は ライブラリの名前を紹介してくれると助かります。
[ reply ]