On Wed, Dec 1, 2010 at 8:48 AM, Iain B. [email protected]
wrote:
and use method missing to wrap all the calls with logging and then remove
I’m not especially keen on method_missing, it seems difficult to
diagnose
when it has issues, and I always worry about it colliding with other
method_missings. It would also mean you’d have to hack respond_to as
well
(if you want to play nice, anyway). And it means you can’t override
methods,
for example:
class MyClass
def _foo(arg)
end
def to_s
“you will never see me”
end
def method_missing(meth,*args,&block)
if respond_to?("#{meth}")
puts “LOGGING: ‘#{meth}’ RECEIVED #{args.inspect} WITH#{‘OUT’
unless
block} A BLOCK”
else
super
end
end
end
m = MyClass.new
m.foo(:bar) { }
puts m.to_s
>> LOGGING: ‘foo’ RECEIVED [:bar] WITH A BLOCK
Here is a different way, which allows you to exert a bit more control.
Note
that this won’t work on 1.8.6. Some other things you could do would be
to
have it hook into a callback so you can customize the logging for each
class, or even each method that uses it; or to allow additional args to
loggable method, which would then be the custom message (ie priority and
message).
alias :log :puts
module Loggable
def loggable( meth , &block )
define_actual meth , &block
define_loggable meth
end
def define_actual( meth , &block )
define_method “_#{meth}” , &block
end
def define_loggable(meth)
define_method meth do |*args,&block|
log “LOGGING: ‘#{meth}’ RECEIVED #{args.inspect} WITH#{‘OUT’
unless
block} A BLOCK”
send “_#{meth}” , *args , &block
end
end
end
class BreadBox
extend Loggable
def initialize
@slices = 0
end
a logging method
loggable :insert do |n|
@slices += n
end
a non-logging method
def remove(n)
@slices -= n
end
can log overridden methods
loggable :to_s do
“”
end
end
box = BreadBox.new
BreadBox.instance_methods(false) # => [:_insert, :insert, :remove,
:_to_s,
:to_s]
box.respond_to? :insert # => true
box.insert 5 # => 5
box.remove 3 # => 2
box.insert 7 # => 9
box.to_s # => “”
>> LOGGING: ‘insert’ RECEIVED [5] WITHOUT A BLOCK
>> LOGGING: ‘insert’ RECEIVED [7] WITHOUT A BLOCK
>> LOGGING: ‘to_s’ RECEIVED [] WITHOUT A BLOCK