This is a read-only archive!

Debugging (awesomely)

The simple act of jamming lots of print statements into your code to output values to help with debugging turns out to be tedious once you do it a billion times. One problem is in Ruby code that looks like this contrived example:

arr.sort.map{|el| "'#{el}'"}.join("\n")

If you wanted to inspect your object right in the middle, say after the sort but before the map, how could you? Like this maybe:

tmp = arr.sort
p tmp
tmp.map{|el| "'#{el}'"}.join("\n")

Ugly. Ruby 1.9 apparently has Object#tap, which has been widely used in the community for a while anyways I believe but will now be a standard method. It has the simple definition:

def tap
  yield self
  self
end

So you can do

arr.sort.tap{|o| p o}.map{|el| "'#{el}'"}.join("\n")

Just makes your life a bit easier. (Though tap can be used for more than printing things obviously.) Ruby's ability to mess with the innards of standard classes makes this possible. In languages which lack this power, you couldn't do this so easily.

Then you have Common Lisp, which arguably takes that kind of power to another level. So you can do something awesome like this and print intermediate results the whole way down the call chain without even having to edit your original code at all. The author mentions that it won't work with certain macros and special forms, but it's still awesome and useful even given its limitations. How could you do this in Ruby?

April 12, 2008 @ 5:56 AM PDT
Cateogory: Programming
Tags: Lisp, Ruby

1 Comment

ferringb
Quoth ferringb on April 14, 2008 @ 7:36 AM PDT

At least for python, we can rely on sys.settrace hookpoint as a way to track every step of the vm, and specifically identify when entering/leaving frames throughout the call chain.

Doesn't fully shoot through any cpython extensions (since to the vm, that's typically a single step), but for most usages, it's more then enough.