Examine "quick-and-dirty" debugging information
The function Debug() returns the class object of the Debug class.
In informally debugging various problems, one often has to resort to all sorts of ad hoc insertions into the code. Typically this is a "msgbox()" function that echos something like "the program made it to the beginning of function foobar()". While there *is* an XBase++ debugger that allows more complete tracking of runtime states, informal debugging is still useful.
The Debug class provides something a little better than completely ad hoc messages. It avoids the need for continually rewriting the same few lines to check something about the current runtime state. As well, one sometimes would like to accumulate several bits of runtime status information in one place, and would like to have this information saved for later examination (even--or especially--if the application crashes)
It is anticipated that more methods to report on various other state information will be added to the Debug class over time. But the basic outline will remain consistent, and anything added should be straightforward (and this document should refelct such changes, ideally).
In the simplest case, you can use the Debug class to *immediately* and transiently report some runtime state info. This is done like:
Doing this will pop up something like:
--------------------------------------- WORKAREA SNAPSHOT Invoked at 09/18/1999 03:04:02 Called from SUMBYVENTYPE(1174) ---------------------------------------- SELECT() = 6 Workarea 1: ALIAS() = INVHSTHD Workarea 2: ALIAS() = SNAUDIT Workarea 3: ALIAS() = INVHED Workarea 4: ALIAS() = TENANT Workarea 5: ALIAS() = VENDOR
...right where the call is made in the program flow.
In a more complex case you can maintain one or more "debug logs" through a complex program flow, and look at them later in the program flow, or even from a diskfile after the whole program ends. See the Examples section of this document.
Whether you look at "debug logs" with the :View() method, or at the saved log files, you will get a list of zero or more entries describing the context and content of a reporting method call. Each log entry will appear in the sequence it was called within program flow, and show its time and caller.
A Debug instance comes into existence immediately upon its assignment with the Debug():new() method. No seperate :create() method is required to request system resources. A Debug instance is destroyed when its variable falls out of its declaration scope.
Although a Debug instance does not really have a "life cycle" in the way "XBase Parts" do, there are still three distinct processes a Debug instance goes through after initialization. (1) A Debug instance can generate textual content using one of its reporting methods; (2) A Debug instance will automatically log to diskfile a record of all instance textual content; (3) A Debug instance can be displayed within the application context.
The logging of textual content to a diskfile is performed wholly within the PROTECTED method :toDisk() (which is called internally within the reporting methods), so this aspect is not under application programmer control. However, the first and third "life stages" of a Debug instance follow the requirements of the application programmer. It serves no purpose to display a Debug instance to which nothing has been reported; but during course of running an application, it may make sense to alternate between reporting additional information and displaying it, some indefinite number of times
oDebug := Debug():new()
// Examine two dimensional array
oDebug:Message("Structure of active DBF", DBSTRUCT())
// Examine an object
oDebug:Message("Current configuration", Cfg())
// View the debug log
// Maintain and utilize multiple debug logs
PUBLIC oDebug1 := Debug():new("workareas.log")
PUBLIC oDebug2 := Debug():new("callstacks.log")
[... whatever ...]
[... open some more DBFs, for example ...]
[... more stuff ...]
[... cleanup some stuff ..]
MsgBox("You might want later to take a look at callstacks.log")
Source file is Debug.prg