17 August 2013

Debugging Tips (using local objects to your advantage)


(This is a repost of an article of mine on Real Software's, now Xojo Inc's, former blog)

In this article I am going to share a nifty way to help with debugging your code. There are times when you need to figure out which methods of your code are called when. A common solution for this is to add lines like this to your code:

Sub myMethod()
System.DebugLog CurrentMethodName + " Entered"

... your code ...

System.DebugLog CurrentMethodName + " Exited"
End Sub

This can quickly get overwhelming if the methods you want to test have lots of exit points, i.e. return statements, as you'll have to spot all of those and add a line before each of the return statements. It gets even worse if the return statement calls a function, like this:

return mySubroutine()

To get this right, you'd have to modify your code like this:

dim tmpResult as String = mySubroutine()
System.DebugLog CurrentMethodName + " Exited"
return tmpResult

But there's a much simpler solution which brings along a few other enhancements as well: 

Use an object that exists for the time the method is running, like this:

Sub myMethod()
dim myTmpObject as new MethodProfiler(CurrentMethodName)

With this construct, you create an object of class MethodProfiler at the start of the method, and it'll be destructed automatically when the method is exited. That's all thanks to RB's method of reference-counted object management (it wouldn't work with the garbage disposal management as it's used by Java and Objective C).

The MethodProfiler class just needs its constructor and destructor methods implemented, like this:

Sub Constructor(name as String)
System.DebugLog "<"+name+"> Entered"
mName = name
End Sub

Sub Destructor()
LogMsg "<"+mName+"> Exited"
End Sub

No more need to add numerous DebugLog calls before return statements.

But wait, there's more!

With that single class taking care of all the tracking, you can easily add code to have it measure the time that the method takes to execute. And it could count the depth, allowing you to indent the output, making it more readable if you have nested calls you want to trace.

For your convenience, here is a demo project with a ready-to-use MethodProfiler class: http://files.tempel.org/RB/MethodProfiler.rbp.zip

Also, if you have at least a Basic license for my tool Arbed, you can use Arbed to add these MethodProfiler invocations to all methods of your project in one easy step. See this Xojo forum article for instructions.

Enjoy.

No comments:

Post a Comment