You are on a machine via Remote Desktop, there is no Visual Studio in sight, nor you can install, nor you want to install anything, and script does not work. What's next?
Enable script debug output (you'll need DebugView for Windows to see the output)
xsharper hello.xsh //debug
If //debug is specified, if script fails with exception, a complete error message is produced. For example, there is a script:
You are on a machine via Remote Desktop, there is no Visual Studio in sight, nor you can install, nor you want to install anything, and script does not work. What's next?
Enable script debug output (you'll need DebugView for Windows to see the output)
xsharper hello.xsh //debug
If //debug is specified, if script fails with exception, a complete error message is produced. For example, there is a script:
<print newline="false">Enter an expression:</print> <set expr="${=c.ReadLine()}" /> <print outTo="^debug">Expression: ${expr}</print> <print>Result: ${=c.Eval($expr)}</print>
which when executed attempts to divide by 0:
C:\xsharper eval.xsh Enter an expression: (50+20)/0 Error: Attempted to divide by zero. C:\xsharper eval.xsh //debug Enter an expression: (50+20)/0 Error: System.DivideByZeroException: Attempted to divide by zero. at XSharper.Core.EvalHelper.runAgainstObject(Object obj, Type objType, String func, Array a, RunFlags flags, Object& retVal) at XSharper.Core.Operations.OperationCall.Eval(IEvaluationContext context, Stack`1 stack) at XSharper.Core.Operations.OperationExpression.Eval(IEvaluationContext context, Stack`1 stack) at XSharper.Core.Operations.OperationVariableAccess.Eval(IEvaluationContext context, Stack`1 stack) at XSharper.Core.ScriptContext.EvaluateMulti(ParsingReader r) at XSharper.Core.ScriptContext.expandVars(TransformRules rules, String s) at XSharper.Core.ScriptContext.Transform(Object source, TransformRules rules) at XSharper.Core.ValueBase.GetTransformedValueStr() at XSharper.Core.Print.execute() at XSharper.Core.ScriptContext.<>c__DisplayClass13.<Execute>b__12() at XSharper.Core.ScriptContext.RunOnStack(ScriptOperation operation, IScriptAction action, ScriptExecuteMethod method) At script location: [Executing] print(value="Result: ${=c.Eval($expr)}") [Executing] xsharper(location="C:\eval.xsh")
To enable debug output and print it to console there is //debugc switch (debugc= debug to console)
C:\>xsharper eval.xsh //debugc Enter an expression: 4+5 Expression: 4+5 Result: 9
Same, but enable debug output and print it to console, including script engine details, is done via //verbose:
C:\>xsharper eval.xsh //debugc //verbose # OpenStream> Reading from file C:\eval.xsh # Context> Executing script C:\eval.xsh with isolation High Enter an expression: 4+5 Expression: 4+5 Result: 9
Same, as above, but also trace lines of code as they execute
xsharper hello.xsh //debugc //verbose //trace C:\>xsharper eval.xsh //debugc //verbose //trace # OpenStream> Reading from file C:\eval.xsh # @ [Loading] xsharper(location="C:\eval.xsh") # @ [Initializing] xsharper(location="C:\eval.xsh") # @ [Initializing] xsharper(location="C:\eval.xsh") >> print(newLine="False", value="Enter an expression:") # @ [Initializing] xsharper(location="C:\eval.xsh") >> set(name="expr", ="${=c.ReadLine()}") # @ [Initializing] xsharper(location="C:\eval.xsh") >> print(outTo="^debug", value="Expression: ${expr}") # @ [Initializing] xsharper(location="C:\eval.xsh") >> print(value="Result: ${=c.Eval($expr)}") # @ [Compiling] xsharper(location="C:\eval.xsh") # Context> Executing script C:\eval.xsh with isolation High # @ [ParsingArguments] xsharper(location="C:\eval.xsh") # @ [Executing] xsharper(location="C:\eval.xsh") # @ [Executing] xsharper(location="C:\eval.xsh") >> print(newLine="False", value="Enter an expression:") Enter an expression: @ [Executing] xsharper(location="C:\eval.xsh") >> set(name="expr", ="${=c.ReadLine()}") 4+5 # @ [Executing] xsharper(location="C:\eval.xsh") >> print(outTo="^debug", value="Expression: ${expr}") # Expression: 4+5 # @ [Executing] xsharper(location="C:\eval.xsh") >> print(value="Result: ${=c.Eval($expr)}") Result: 9
Measure script execution time, display exit code and ask for a key press before exit
xsharper #/hash //wait
Using the previous steps you may determine where the program throws an exception, how execution goes, how to print debug messages etc.
It is as important to see variables defined at critical script points. Of couse, can use the usual ToString method, but it often produces rather useless results for complex objects.
XSharper has a few special methods for converting objects variables:
Shortcut name | Full method name | Description |
---|---|---|
.ToDump | Dump.ToDump | Convert a .NET object graph to string |
.ToDumpAll | ScriptContext.ToDumpAll | Convert all defined XSharper variables to string (a filter may be specified to dump only some variables |
.Dump | ContextWriter.Dump | Shortcut for ContextWriter.WriteDump.ToDump(object)) |
.Dump | ScriptContext.Dump | Shortcut for Out.Write(Dump.ToDump(object)) |
What it all means is easier to demonstrate:
<set a="Hello" /> <set b="${=new DirectoryInfo('c:\windows')}" /> <set c="${=new string[] { 'This', 'is','a','string','array'} }" /> <print outTo="^bold">Dumping a to standard output</print> <eval>c.Dump($a);</eval> <print outTo="^bold">Dumping b to error output</print> <eval>c.Error.Dump($b);</eval> <print outTo="^bold">Dumping b and c to info</print> <eval>c.Out.WriteLine(c.ToDumpAll('b;c*'))</eval>
prints
Dumping a to standard output (string) "Hello" Dumping b to error output (DirectoryInfo) { /* #1, 03553390 */ Name = (string) "windows" Parent = (DirectoryInfo) "" /* ToString */ Exists = (bool) true Root = (DirectoryInfo) "c:\" /* ToString */ FullName = (string) "c:\windows" Extension = (string) "" CreationTime = (DateTime) 2009-03-03T08:30:25.3750000-05:00 CreationTimeUtc = (DateTime) 2009-03-03T13:30:25.3750000Z LastAccessTime = (DateTime) 2009-12-10T13:12:37.1088672-05:00 LastAccessTimeUtc = (DateTime) 2009-12-10T18:12:37.1088672Z LastWriteTime = (DateTime) 2009-12-07T19:51:20.7933162-05:00 LastWriteTimeUtc = (DateTime) 2009-12-08T00:51:20.7933162Z Attributes = (FileAttributes) [Directory] /* 0x00000010 */ } Dumping b and c to info b = (DirectoryInfo) "c:\windows" /* ToString */ c = (string[]) "System.String[]" /* ToString */