[Note: parts of this message were removed to make it a legal post.]
Hi,
As hacky ideas go, how does this sound? My code is peppered with logging
statements which I'd rather not wade through, so maybe I could define all my
methods with a leading underscore but call them without e.g.
def _my_method...
@n = my_method @a, @b, @c ...
and use method missing to wrap all the calls with logging and then remove
the underscore and recall the method.
I tried using the Aquarius lib but it didn't work for me, so this is my
crazy idea for the day. Aside from putting all my money into buying
government debt.
Is it crazy?
Regards,
Iain
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
# >> #<MyClass:0x0000010086ca80>
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

uts
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
"<BreadBox slices=#{@slices}>"
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 # => "<BreadBox slices=9>"
# >> LOGGING: 'insert' RECEIVED [5] WITHOUT A BLOCK
# >> LOGGING: 'insert' RECEIVED [7] WITHOUT A BLOCK
# >> LOGGING: 'to_s' RECEIVED [] WITHOUT A BLOCK