概要
Python のデコレータは関数の前後処理を実装することができる便利な機能です
Ruby でも同じことがしたいと思い試してみました
環境
- macOS 10.15.5
- Ruby 2.7.1p83
サンプルコード
vim hooks.rb
module Hooks
def before(*method_names)
to_prepend = Module.new do
method_names.each do |name|
define_method(name) do |*args, &block|
puts "before #{name}"
super(*args,&block)
end
end
end
prepend to_prepend
end
end
説明
最大のポイントは prepend を使っているところです
クラス (Example) が持っているメソッドをモジュール (Module.new したモジュール) で再度 define_method
します
そしてそのモジュールを prepend することでクラスで呼ばれる同名のメソッドが呼ばれた際に prepend したモジュールで定義されたメソッドがコールされるという仕組みです
確認用スクリプト
vim test.rb
require './hooks'
class Example
extend Hooks
before :foo, :bar
def foo
puts "in foo"
end
def bar
puts "in bar"
end
end
a = Example.new
a.foo
ruby test.rb
=> before foo in foo
after の場合は
おそらく以下のような感じでいいと思います
module Hooks
def after(*method_names)
to_prepend = Module.new do
method_names.each do |name|
define_method(name) do |*args, &block|
super(*args,&block)
puts "after #{name}"
end
end
end
prepend to_prepend
end
end
最後に
Ruby で Python のデコレータっぽい処理を試してみました
Ruby にはデコレータパターンと呼ばれるデザインパターンが存在しますがこれは既存クラスの拡張っぽい機能なので少し異なります
0 件のコメント:
コメントを投稿