= TraceStatement = The '''trace''' statement is a debugging aid to log points of execution in the source code and/or values of expressions. === Grammar === {{{ trace trace , , ... trace all trace off trace on }}} A simple '''trace''' gives the filename, line number, declaring class name and declaring method name that the '''trace''' is located in. If the current object's class is a subclass of the declaring class then the subclass name is reported as well. When given one or more expressions, '''trace''' gives the same information plus the source code and value of each expression. The '''trace all''' statement is a convenience for logging '''this''', every method argument and every local variable. The '''trace off''' statement turns off the subsequent trace statements in the declaring method. The '''trace on''' statement turns them back on. Sprinkling '''trace''' statements in methods can help diagnose bugs by showing program flow and values during execution, as seen here: {{{ #!cobra class Foo var _z as int def computeStuff(x as int, y as int) if x > y trace return _z = x * y trace all trace _z }}} {{{ trace: this=Foo; x=2; y=4; at Foo.cobra:10; in Foo.computeStuff trace: this=Foo; _z=8; at Foo.cobra:11; in Foo.computeStuff }}} An alternative to a trace would be a print statement: {{{ #!cobra ... print 'trace: x=[x]; y=[y]' }}} But that won't report source information such as line number, and writing such a print statement is more work than: {{{ #!cobra trace x,y }}} Also, '''trace''' statements are easy to locate and remove—or turn off via '''trace off'''—while leaving application '''print''' statements in tact. And '''trace''' output is flushed with each trace, by default. Note that the '''trace''' statement is backed by a supporting class called '''Tracer''': {{{ #!cobra class Tracer inherits Object """ Used to implement the trace statement. """ cue init """ Initializes the tracer with Console.out as the destination. """ cue init(dest as System.IO.TextWriter) pro isActive as bool """ When false, the `trace` methods will produce no output. """ pro willAutoFlush as bool """ When true, `destination.flush` is invoked after every trace. Defaults to `true`. """ pro destination as String """ The TextWriter where all trace output is sent to. """ pro separator as String """ The separator string used between items of both name/value pairs and source information. Default is '; '. """ pro prefix as String """ The prefix string used at the beginning of every trace. Default is 'trace: '. """ def trace(source as SourceInfo) def trace(source as SourceInfo, nameValues as vari Object) require nameValues.length % 2 == 0 }}} You can get access to the current tracer with the shared property, '''CobraCore.tracer'''. In fact, you can use that same property to set the Tracer instance that the trace statements use, although modifying the default instance is normally sufficient. For example: {{{ #!cobra class Program def main is shared tracer = CobraCore.tracer tracer.prefix = '' tracer.separator = ', ' tracer.destination = File.createText('trace.text') }}} Don't confuse '''trace on/off''' with '''Tracer.isActive'''. The '''trace on/off''' statements are purely compile-time directives that affect only the method that contains them. The '''Trace.isActive''' property is purely a run-time property and will deactive the output of all trace statements when set to '''false'''.