Nasal library/debug: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
(Start print_rank())
(→‎print_rank(): Finish doc)
Line 199: Line 199:
{{Nasal doc
{{Nasal doc
|syntax = debug.print_rank(label, list, names);
|syntax = debug.print_rank(label, list, names);
|text = Formats and prints results from {{func link|rank()|page=this}}.
|text = Formats and prints results from {{func link|rank()|page=this}}. It will show them in order of fastest to slowest, the time taken in milliseconds, and what percentage of time each took relative to the slowest.
|param1 = label
|param1 = label
|param1text = Label to add to the results header.
|param1text = Label to add to the results header.
Line 205: Line 205:
|param2text = Results vector from {{func link|rank()|page=this}}.
|param2text = Results vector from {{func link|rank()|page=this}}.
|param3 = names
|param3 = names
|param3text = Either a vector or hash that will supply the names of the functions. If a hash, it must have the structure of <code>{ name: func, ... }</code>. If a vector, its structure can be etiher <code>[[name, func], ...]</code> or <code>[[func, name], ...]</code>
|param3text = Either a vector or hash that will supply the names of the functions. If a hash, it must have the structure of <code>{ name: func, ... }</code>. If a vector, its structure can be either <code><nowiki>[[name, func], ...]</nowiki></code> or <code><nowiki>[[func, name], ...]</nowiki></code>
|example1 =  
|example1 = var getElev = func(){
    var pos = geo.aircraft_position();
    return geo.elevation(pos.lat(), pos.lon());
}
var getTime = func(){
    return getprop("/sim/time/gmt");
}
var list = [getElev, getTime];
var result = debug.rank(list, 1000);
var names = [["getElev", getElev], ["getTime", getTime]];
#var names = [[getElev, "getElev"], [getTime, "getTime"]]; # other option
#var names = { # third option
#    "getElev": getElev,
#    "getTime": getTime
#};
debug.print_rank("getElev() and getTime()", result, names);
}}
}}



Revision as of 11:25, 25 November 2016

WIP.png Work in progress
This article or section will be worked on in the upcoming hours or days.
See history for the latest developments.

This page contains documentation for the debug namespace in Nasal. This namespace provides various useful APIs for debugging Nasal code. The debug namespace is sourced from fgdata/Nasal/debug.nas.

Functions

attributes()

debug.attributes(p[, verbose[, color]]);

Returns a string showing the attributes of the node, in the form (type[, attr[, Lnum[, #refs]]). See the table below for explanation.

Data Meaning
type Type of node as returned by props.Node.getType() .
attr Various attribute flags, see props.Node.getAttribute() . "r" = read protected, "w" = write protected, "R" = trace read, "W" = trace write, "A" = archive, "U" = userarchive, "P" = preserve, and "T" = tied.
num Number of listeners, if any.
refs This argument will be shown if verbose is true. Tells the number of references to the node. Note that all nodes have two references by default, but this tells the number of extra references.
p
Mandatory props.Node object.
verbose
Optional bool specifying whether to show the number of times the node is referenced. Defaults to 1 (true).
color
Optional bool specifying whether to output the string with an ANSI color code This is a link to a Wikipedia article. Defaults to nil.

Examples

var node = props.globals.getNode("/sim/time/gmt");
print(debug.attributes(node)); # prints "(STRING, AT, #1)" - string, archive, tied, 1 extra ref
var node = props.Node.new();
node.setIntValue(12);
node.setAttribute(17);
print(debug.attributes(node)); # prints "(INT, wR)" - integer, write protected, trace read
var node = props.globals.getNode("/sim/signals/fdm-initialized");
print(debug.attributes(node)); # prints "(BOOL, L6, #16)" - bool, 6 listeners, 16 extra refs

backtrace()

debug.backtrace([desc]);

When called, this function prints the backtrace This is a link to a Wikipedia article, also printing the local variables at each level.

desc
Optional extra description to add.

Examples

var myFunc = func(a){
    multiply(a, 2);
}
var multiply = func(x, y){
    debug.backtrace();
}
myFunc(2);
var myFunc = func(a){
    multiply(a, 2);
}
var multiply = func(x, y){
    debug.backtrace("multiply() function");
}
myFunc(2);

bt()

debug.bt([desc]);

Shortcut for backtrace() . See doc there

benchmark()

debug.benchmark(label, fn[, repeat[, output]]);

Analyses the amount of time a function takes to run. If repeat is given and output is not, the time taken to repeat the function the given amount off times will be printed. If both are given, the return value of each repeat of the function will be returned in a vector output.

label
Label to add to the output.
fn
Function to call.
repeat
Optional integer specifying how many times the function is to be run. If not given, the function will be run once.
output
Optional vector that will be returned with the return value of each function.

Examples

var test = func(){
    var children = props.globals.getNode("sim").getChildren();
    var vec = [];
    foreach(var child; children){
        append(vec, child.getChildren());
    }
    return vec;
}
var result = debug.benchmark("test()", test);
debug.dump(result);
var test = func(){
    var children = props.globals.getNode("sim").getChildren();
    var vec = [];
    foreach(var child; children){
        append(vec, child.getChildren());
    }
    return vec;
}
debug.benchmark("test()", test, 10);
var test = func(){
    var children = props.globals.getNode("sim").getChildren();
    var vec = [];
    foreach(var child; children){
        append(vec, child.getChildren());
    }
    return vec;
}
var result = debug.benchmark("test()", test, 10, []); # this example may cause a small pause
debug.dump(result);

benchmark_time()

debug.benchmark_time(fn[, repeat[, output]]);

Behaves in exactly the same way as benchmark() , but returns the amount of time taken, rather than printing it out.

fn
Function to call.
repeat
Optional integer specifying how many times the function is to be run. If not given, the function will be run once.
output
Optional vector that will be returned with the return value of each function.

Examples

var test = func(){
    var children = props.globals.getNode("sim").getChildren();
    var vec = [];
    foreach(var child; children){
        append(vec, child.getChildren());
    }
    return vec;
}
print(debug.benchmark_time(test));
var test = func(){
    var children = props.globals.getNode("sim").getChildren();
    var vec = [];
    foreach(var child; children){
        append(vec, child.getChildren());
    }
    return vec;
}
print(debug.benchmark_time(test, 10));
var test = func(){
    return getprop("/sim/time/gmt");
}
print(debug.benchmark_time(test, 1000, var res = []));
debug.dump(res);

dump()

debug.dump([arg[, arg[, ...]]]);

Dumps the given arguments in the console. If no arguments of given, the local namespace will be dumped.

arg
Anything. Literally, anything. There may be as may arguments as you like. If more than one argument is given, each will be dumped separately with an index.

Examples

var x = nil;
debug.dump(); # prints "{ x: nil, arg: [] }"
debug.dump("Hello, World!"); # 'Hello, World!'
debug.dump(1234); # 1234
debug.dump(nil); # nil
debug.dump(["a", "b", "c"]); # ['a', 'b', 'c']
debug.dump({ a: 1, b: 2, c: 3 }); # { a: 1, b: 2, c: 3 }
debug.dump(props.Node.new()); # < = nil (NONE)>
debug.dump(airportinfo()); # <airport> 
debug.dump(func(a){ print(a); }); # <func>
debug.dump( # dump, showing the index of each argument
    "Hello, World!",
    1234,
    nil,
    ["a", "b", "c"],
    { a: 1, b: 2, c: 3 },
    props.Node.new(),
    airportinfo(),
    func(a){ print(a); },
);

isnan()

debug.isnan(num);

Checks whether a number actually is a valid number and returns 0 (false) if it is and 1 (true) if it is not.

num
Number to check.

Examples

print(debug.isnan(1.234)); # prints "0" (1.234 is valid)
print(debug.isnan(1/0)); # prints "1" (division by 0 is undefined)

local()

debug.local([frame]);

Prints and also returns a hash containing all the local variables.

frame
Optional integer specifying the frame. Corresponds to the argument given to caller() .

Examples

var n = 12;
debug.local(); # prints "{ n: 12, arg: [] }"
var sqr = func(a){
    debug.local(); # prints "{ a: 16 }"
    debug.local(1); # prints "{ sqr: <func>, arg: [] }"
    return a * a;
}
print(sqr(16));

print_rank()

debug.print_rank(label, list, names);

Formats and prints results from rank() . It will show them in order of fastest to slowest, the time taken in milliseconds, and what percentage of time each took relative to the slowest.

label
Label to add to the results header.
list
Results vector from rank() .
names
Either a vector or hash that will supply the names of the functions. If a hash, it must have the structure of { name: func, ... }. If a vector, its structure can be either [[name, func], ...] or [[func, name], ...]

Example

var getElev = func(){
    var pos = geo.aircraft_position();
    return geo.elevation(pos.lat(), pos.lon());
}
var getTime = func(){
    return getprop("/sim/time/gmt");
}
var list = [getElev, getTime];
var result = debug.rank(list, 1000);
var names = [["getElev", getElev], ["getTime", getTime]];
#var names = [[getElev, "getElev"], [getTime, "getTime"]]; # other option
#var names = { # third option
#    "getElev": getElev,
#    "getTime": getTime
#};
debug.print_rank("getElev() and getTime()", result, names);

printerror()

propify()

proptrace()

rank()

string()

tree()

warn()