全てのメソッド呼出に対して何らかの処理を行うようなオブジェクトを生成したいとき、Rubyだと直接そういうオブジェクトを生成するようなクラスは用意されていないが、BasicObjectとmethod_missingを利用すれば簡単に作成できる。例えば、渡したloggerの全ての出力にタグを付けて欲しい場合にこの方法で解決しようとすると、こういう感じになる(この問題に対してのGoodな解決方法では無いです)。
class TaggingProxy < BasicObject
def initialize(target)
@target = target
end
def method_missing(name, message, *args, &block)
@target.send(name, "[tag] #{message}", *args, &block)
end
end
require "logger"
logger = Logger.new(STDOUT)
proxied = TaggingProxy.new(logger)
proxied.info("1")
proxied.debug("2")
__END__
I, [2012-12-26T04:24:23.634927 #95746] INFO -- : [tag] 1
D, [2012-12-26T04:24:23.635012 #95746] DEBUG -- : [tag] 2
こういう感じ。Ruby1.8系の場合はActiveSupport::BasicObjectを使うという選択肢もある。
[1] pry(main)> BasicObject.instance_methods
=> [:==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__, :__id__]
[2] pry(main)> BasicObject.ancestors
=> [BasicObject]