在trepl或luajit,我怎么能找到我使用的是库的源代码?(In trepl or luajit

2019-10-22 19:43发布

比方说,我与我使用luarocks安装一个Lua库的工作,我想看看从库中的函数的定义。 在IPython中的可使用

?? FUNCTION_NAME

看到在终端的定义,在MATLAB我可以使用

该函数名

然后用我的编辑来看看由返回的路径。 我怎么会做同样找到一个Lua库中的函数定义的东西吗?

Answer 1:

在“纯”的Lua / JIT,你可以说debug.getinfo ( func )并会得到一个表包含(其中包括)领域short_srcsourcelinedefined

对于Lua函数, short_src将是文件名或stdin ,如果它是在REPL定义。 ( source有一个稍微不同的格式,文件名的前缀与@ ,一个=前缀用于交互式地定义的C函数或东西,以及用于load ED的功能,这将是被装载的实际字符串)。

你可以打包,最多的功能类似

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

或者甚至启动一个编辑器,并指出其存在,例如,(对于VIM)

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 ,并在没有源文件存在。你也可以在其他方向倾倒的工作load编辑片段到一个临时文件,并打开该...)

-- 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

一个关闭的话:如果你将代码粘贴到一个Lua / JIT REPL, local界说之间消失了,因为每一行(或线的最小完整的组)是它自己的块。 常见的修复(你可能知道)是一切包装成块的do *贴* end ,而是另一种是load[[ *贴* ]]()可能更多=就像[===[]===]如果粘贴这样,上述dumpsource (或任何其他功能使用debug.getinfo )随后将能够获得功能(S)的来源。 这也意味着,如果你定义一个不错的功能,但它是从历史和滚动缓冲区走了,你可以用这种方式恢复它( 如果您将它定义load ING,而不是直接将解释)。 然后在文件中保存源也有可能没有复制粘贴,并且不需要编辑出>>提示。



文章来源: In trepl or luajit, how can I find the source code of a library I'm using?
标签: lua torch