- prepends the name of the script to any debug message
- can output the calling function's parameter list with the current values
- can output a variable, printing its name and value
- can recursively print out an object
- has very nice formatting!* each parameter in a parameter list gets its own line
* each indent level is spaced so as not to overlap with other levels
* everything in an indent level is aligned at "="
* certain parameter values can be ignored (like "__deFault__")
* parameter values can also be formatted (split lists like "first|second|third" such that each item (first, second, and third) is on its own line)[/list]REQUIREMENTS:- LowLevel library by Lexikos
- HTML DialogBox by SKAN
- There should be no problems using this library with any build.
DOWNLOADS (last updated 2010-08-13, 13:24):dout.ahk (my debugging library)
DebugViewer (A program for viewing the debug output from OutputDebug. There are alternatives available, but this viewer is the best I've seen.)
Time for an example. So for the following (in a script named t1.ahk):
dout("hello!") dout("multiple`nlines`nwork`nfine`ntoo") var123 := "one-two-three" dout_v(var123) test(1,"two","3","abc|def|ghi|jkl|") dout_x() dout_m("this is a more important alert") test(first,p2,three,list,optional="cake",another="__deFault__") { dout_f(A_ThisFunc) }the debug output (in DebugView, for my setup) will be:
[5472] t1 - hello! [5472] t1 - multiple [5472] lines [5472] work [5472] fine [5472] too [5472] t1 - var123=one-two-three [5472] t1 - test(first = 1, [5472] p2 = "two", [5472] three = "3", [5472] list = "abc| [5472] def| [5472] ghi| [5472] jkl|", [5472] optional = "cake") [5472] t1 - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx [5472] t1 - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx [5472] t1 - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx [5472] t1 - this is a more important alert(5472 is the process id, which DebugView adds itself. Timestamps are also present, but not shown here.)
Here's an example script to demo dout_o():
; make an object for demonstrating dout_o() obj := Object() Loop 3 { c := Object() c.asdfqwerty := "slnh value" c.alpha := "a" c.one := 1 obj[A_Index] := c } /* ; you can uncomment this if you have the Array library by temp01 obj.a := Array() Loop 4 obj.a.append(A_Index) */ obj["extra"] := Object() obj["extra"].something := "this`nis`nMULTILINE!!!" obj.x := Object("base", Object("__Get","func_get")) obj.y := Object("base", Object("__Set","func_set")) obj.z := Object("base",Object("__Call","func_call")) ; test overriden methods (they don't interfere with dout_o()) obj.x.test := "hix!" obj.y.test := obj.x.test . "!" obj.z.test := obj.z() ; print out the object: dout_o(obj) ; you can also specify the name to be displayed: dout_o(obj,"my object") MsgBox return ;====================================================================== ; these won't get called by accident when using the debug functions ; dout_o() only uses IsObject(), &, and ObjNewEnum() to interact with ; the given objects. So feel free to customize your objects however ; you like! ;====================================================================== func_get(o,f) { static already=false if already MsgBox "don't worry, this won't get called" else already := true } func_set(o,f) { static already=false if already MsgBox "don't worry, this won't get called" else already := true } func_call(o,f) { static already=false if already MsgBox "don't worry, this won't get called" else { already := true return "call works fine" } }After running that, the output in DebugView will be:
[5200] t2 - [5200] ? = [0x1E0F178] [5200] 1 = [0x1E0F1C0] [5200] alpha = a [5200] asdfqwerty = slnh value [5200] one = 1 [5200] 2 = [0x1E0F458] [5200] alpha = a [5200] asdfqwerty = slnh value [5200] one = 1 [5200] 3 = [0x1E0F688] [5200] alpha = a [5200] asdfqwerty = slnh value [5200] one = 1 [5200] extra = [0x1A9EE80] [5200] something = this [5200] is [5200] MULTILINE!!! [5200] x = [0x1A9EF58] [5200] test = hix! [5200] y = [0x1A9F030] [5200] test = hix!! [5200] z = [0x1A9F108] [5200] test = call works fine [5200] t2 - [5200] my object = [0x1E0F178] [5200] 1 = [0x1E0F1C0] [5200] alpha = a [5200] asdfqwerty = slnh value [5200] one = 1 [5200] 2 = [0x1E0F458] [5200] alpha = a [5200] asdfqwerty = slnh value [5200] one = 1 [5200] 3 = [0x1E0F688] [5200] alpha = a [5200] asdfqwerty = slnh value [5200] one = 1 [5200] extra = [0x1A9EE80] [5200] something = this [5200] is [5200] MULTILINE!!! [5200] x = [0x1A9EF58] [5200] test = hix! [5200] y = [0x1A9F030] [5200] test = hix!! [5200] z = [0x1A9F108] [5200] test = call works fineThe first printout was for the dout_o() call that didn't specify a name for the base object. I don't yet know how to obtain the name automatically for an object like this, but it isn't much of a problem. The hex values in brackets are the object addresses.