lua - In trepl or luajit, how can I find the source code of a library I'm using? -
let's i'm working lua library installed using luarocks, , want see definition of function library. in ipython in use
??function_name
to see definition in terminal, in matlab use
which function_name
then use editor @ path returned which. how similar find function definition lua library?
in 'plain' lua/jit, can debug.getinfo
( func )
, table containing (among others) fields short_src
, source
, linedefined
.
for lua functions, short_src
filename or stdin
if defined in repl. (source
has different format, filenames prefixed @
, =
prefix used c functions or stuff defined interactively, , load
ed functions, actual string loaded.)
you can pack in function like
function sourceof( f ) local info = debug.getinfo( f, "s" ) return info.short_src, info.linedefined end
or maybe start editor , point there, e.g. (for vim)
function viewsource( f ) -- info & check it's file local info = debug.getinfo( f, "s" ) local src, line = info.source, info.linedefined if src == "=[c]" return nil, "is c function." end local path = src:match "^@(.*)$" if path -- start vim (or other editor if adapt format string) return os.execute( ("vim -fr %q +%d"):format( path, line ) ) end return nil, "was defined @ run time." end
and fun, here's yet version returns code if can find somewhere. (this work functions have been generated @ run time, e.g. calling load
, , no source file exists. work in other direction dumping load
ed snippet temp file , opening that…)
-- helper extract source block defining function local function funclines( str, line1, linen, filename ) -- if linedefined / lastlinedefined 0, main chunk's function if line1 == 0 , linen == 0 filename = filename , filename.." (main chunk)" or "(chunk defined @ run time)" return "-- "..filename.."\n"..str end -- add line info file name or use placeholder filename = filename , filename..":"..line1 or "(defined @ run time)" -- source block local phase, i, j, k1, kn = 1, line1-1, linen-line1+1 if == 0 phase, k1 = 2, 0 end pos in str:gmatch "\n()" if phase == 1 = - 1 ; if == 0 k1, phase = pos, 2 end else -- phase == 2 j = j - 1 ; if j == 0 kn = pos-2 ; break end end end return "-- "..filename.."\n"..str:sub( k1, kn ) end function dumpsource( f ) -- info & line numbers local info = debug.getinfo( f, "s" ) local src, line, lastline = info.source, info.linedefined, info.lastlinedefined -- can't c function if src == "=[c]" return nil, "is c function." end if src == "=stdin" return nil, "was defined interactively." end -- files, fetch definition local path = src:match "^@(.*)$" if path local f = io.open( path ) local code = f:read '*a' f:close( ) return funclines( code, line, lastline, path ) end -- otherwise `load`ed, `source`/`src` _is_ source return funclines( src, line, lastline ) end
a closing remark: if paste code lua/jit repl, local
s disappear between definitions, because every line (or minimal complete group of lines) own chunk. common fix (that know) wrap block do
*paste*end
, alternative load[[
*paste*]]()
(possibly more =
s [===[
, ]===]
.) if paste way, above dumpsource
(or other function using debug.getinfo
) able source of function(s). means if defined nice function it's gone history , scroll buffer, can recover in way (if defined load
ing , not directly feeding interpreter). saving source in file possible without copy-pasting , not require editing out >>
prompts.
Comments
Post a Comment