Friday, September 10, 2010

Trick Debugging with Object#tap

Since ActiveSupport 3.0 deprecated Object#returning in favor of Object#tap, we can make use of inline debugging like this:

(1..100).to_a.map { |x|
x * 2
}.inject( 0 ) { |a, b|
a + b
}.tap { |sum| p sum }


Being used to Symbol#to_proc, this looks so awkward. I'd rather do this:

WATCH = lambda { |*args| p *args }

(1..100).to_a.map { |x|
x * 2
}.inject( 0 ) { |a, b|
a + b
}.tap(&WATCH)


Extending that idea, you can make something that'd log things to file, vial Rails logger. Or you can make use of metaprogramming:

require 'ap' # awesome_print gem
def watch(sym)
lambda { |*args| ap ( { sym => args[0] } ) }
end

(1..100).to_a.map { |x|
x * 2
}.inject( 0 ) { |a, b|
a + b
}.tap(&watch(:sum))