在trepl或luajit中,如何找到我正在使用的库的源代码?

时间:2015-04-25 21:47:01

标签: lua torch

假设我正在使用luarocks安装的lua库,我希望从该库中看到函数的定义。在ipython中可以使用

  
    

??函数名

  

在终端中查看定义,在matlab中我可以使用

  
    

哪个function_name

  

然后使用我的编辑器查看返回的路径。我怎么能做类似的事情来找到lua库的函数定义?

1 个答案:

答案 0 :(得分:3)

在'普通' Lua / JIT,您可以说debug.getinfo ( func ),并会得到一个包含({1}},short_srcsource字段的表格。

对于Lua函数,linedefined将是文件名,如果它在REPL中定义,则为short_src。 (stdin格式略有不同,文件名前缀为source@前缀用于C函数或交互式定义的内容,以及= ed函数,它将是加载的实际字符串。)

您可以将其打包在像

这样的功能中
load

或者甚至可以启动编辑器并将其指向那里,例如(对于vim)

function sourceof( f )
    local info = debug.getinfo( f, "S" )
    return info.short_src, info.linedefined
end

只是为了好玩,这里还有另一个版本,如果可以在某个地方找到它,就会返回代码。 (这也适用于在运行时生成的函数,例如通过调用function viewsource( f ) -- get info & check it's actually from a file local info = debug.getinfo( f, "S" ) local src, line = info.source, info.linedefined if src == "=[C]" then return nil, "Is a C function." end local path = src:match "^@(.*)$" if path then -- start vim (or an other editor if you adapt the format string) return os.execute( ("vim -fR %q +%d"):format( path, line ) ) end return nil, "Was defined at run time." end ,并且不存在源文件。您也可以通过将load ed片段转储到另一个方向来工作临时文件并打开...)

load

结束语:如果将代码粘贴到Lua / JIT REPL中,-- helper to extract the source block defining the function local function funclines( str, line1, lineN, filename ) -- if linedefined / lastlinedefined are 0, this is the main chunk's function if line1 == 0 and lineN == 0 then filename = filename and filename.." (main chunk)" or "(chunk defined at runtime)" return "-- "..filename.."\n"..str end -- add line info to file name or use placeholder filename = filename and filename..":"..line1 or "(defined at runtime)" -- get the source block local phase, skip, grab = 1, line1-1, lineN-(line1-1) local ostart, oend -- these will be the start/end offsets if skip == 0 then phase, ostart = 2, 0 end -- starts at first line for pos in str:gmatch "\n()" do if phase == 1 then -- find offset of linedefined skip = skip - 1 ; if skip == 0 then ostart, phase = pos, 2 end else -- phase == 2, find offset of lastlinedefined+1 grab = grab - 1 ; if grab == 0 then oend = pos-2 ; break end end end return "-- "..filename.."\n"..str:sub( ostart, oend ) end function dumpsource( f ) -- get info & line numbers local info = debug.getinfo( f, "S" ) local src, line, lastline = info.source, info.linedefined, info.lastlinedefined -- can't do anything for a C function if src == "=[C]" then return nil, "Is a C function." end if src == "=stdin" then return nil, "Was defined interactively." end -- for files, fetch the definition local path = src:match "^@(.*)$" if path then local f = io.open( path ) local code = f:read '*a' f:close( ) return funclines( code, line, lastline, path ) end -- otherwise `load`ed, so `source`/`src` _is_ the source return funclines( src, line, lastline ) end 在定义之间消失,因为每一行(或最小的完整行组)都是它自己的块。常见的修复(您可能知道)是将所有内容包装为local * paste * do,但另一种方法是end * paste * load[[(可能有更多]](),例如=[===[。)如果您这样粘贴,则上面的]===](或使用dumpsource的任何其他函数)将会能够获得功能的来源。这也意味着如果您定义了一个很好的函数,但它已从历史记录和滚动缓冲区中删除,您可以通过这种方式恢复它(如果您通过debug.getinfo定义它而不是直接喂养口译员)。在没有复制粘贴的情况下,也可以将源保存在文件中,而不需要编辑load提示。