![]() |
||
|
There would be advantages if lua_Debug included the starting character position of a function rather than (or in addition to) line numbers. The problem I have is a source code browser that given a function value `f` needs to obtain its signature string `sig`. `f` is typically obtained by something like `f = require 'foo'.bar`. I can obtain its line number and source code via the 'linedefined', 'source', and 'what' fields of `debug.getinfo(f)`. This allows a signature to be parsed, but it can do so uniquely only if a single function exists on the line, which is typical but not certain. An exact character position is more than sufficient actually: simply a token number or a number `n` indicating that the function is the n-th function on the line or file would be sufficient given an external lexer/parser. Now, I might perhaps infer n by bytecode analysis (looking up a function's Proto and finding all functions on that line and sorting them), but that is getting much more complicated than necessary and breaks under alternative bytecodes like LuaJIT2. So, it would be ideal to have the starting character position (positiondefined) in which a function is defined. linedefined, as well as a column number, may be derived from positiondefined. lastlinedefined and lastpositiondefined may also be derived by reparsing the source. The full text of a function, as some have requested [1], may then be derived from positiondefined and lastpositiondefined. Comments surrounding the function and other details may also be derived. This might not take up that much extra space [3], and it might only be needed for function definitions. I realize that in 5.2-work4, debug.getlocal and the 'nparams' and 'isvararg' fields of debug.getinfo results can be used to obtain parameter names [2], and this can be used to build much of a function's signature. However, it doesn't contain return values, which I would be able to obtain via a custom code analysis given an exact position (e.g. `function f(a, ...) local x = a .. a; return x end` has signature 'x = f(a, ...)', and a lot of times signatures are more complicated like 'info = debug.getinfo ([thread,] function [, what])'. It also doesn't allow some of the other possibilities mentioned above like obtaining function source and comments. In short, a character position seems the simplest to implement and most general in flexibility. I was also thinking that perhaps debug.getinfo should also be able to obtain source position info for tables rather than just functions, so that given a module table `t`, you can obtain the location where it is defined. OTOH, if you use some helper function like `function createmodule() return {} end` to create all your module tables, then this information won' t be distinctive. The same problem would also affect functions created with the decorator pattern [4], though decorator functions seem less common than utility function that create tables. If you want to determine where t is defined, you can just debug.getinfo a function inside t or trace t back to its require (which is easy when using the `local t = require "foo"` style import). On a tangential point, there's this curious "activelines" field in the debug info. There's only two threads in the archives on this related to partial success using it for code coverage analysis. As a test, function f() print(1) -- print(2, 3, 4 ) end local info = debug.getinfo(f, 'L') table.foreach(info.activelines, print) outputs 6 true 3 true 10 true 9 true 5 true which is a little odd looking but apparently corresponds with byte-codes. So, it would be byte-code dependent (which possibly should be noted in the manual). There was a suggestion it is useful for setting breakpoints via the hook mechanism. Finally, there probably are uses for allowing C functions to inject debugging information. Currently, debug.getinfo(math.sqrt).nparams --> returns 0 not 1 debug.getinfo(math.sqrt).linedefined --> returns -1 debug.getinfo(math.sqrt).source --> returns "=[C]" but could include the C __FILE__ macro though a module can always store more general metadata on function in weak table like in the decorator pattern [4], although there would be a lack of consistency in that between modules and through Lua. [1] http://lua-users.org/lists/lua-l/2008-09/msg00358.html [2] http://www.lua.org/work/doc/manual.html#pdf-debug.getlocal [3] http://lua-users.org/lists/lua-l/2009-11/msg00368.html [4] http://lua-users.org/wiki/DecoratorsAndDocstrings