Cutting down on logging statements

I

Iain Barnett

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 =3D 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

Iain Barnett

and use method missing to wrap all the calls with logging and then =
remove the underscore and recall the method.

I meant *add* the underscore...


Iain
 
J

Josh Cheek

[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 :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
"<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
 
I

Iain Barnett

Thanks Josh and Ben, I'll peruse the code and the article and see what =
fits best. Interesting stuff.

Regards,
Iain
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,138
Latest member
NevilleLam
Top