使用Module对象查找Module的路径

时间:2017-11-08 06:15:05

标签: julia

Module对象到声明它的文件的路径有什么明智的方法? 确切地说,我正在寻找关键字module出现的文件。

间接方法是在每个模块中查找自动定义的eval方法的位置。 moduleloc(mm::Module) = first(functionloc(mm.eval, (Symbol,)))

例如

moduleloc(mm::Module) = first(functionloc(mm.eval, (Symbol,)))
using DataStructures
moduleloc(DataStructures)

输出:

/home/oxinabox/.julia/v0.6/DataStructures/src/DataStructures.jl

这种间接方法有效,但感觉有点像kludge。 我错过了一些内置函数吗?

我会提醒回答,模块与包不是一回事。 考虑是否存在子模块,甚至是通过include在包目录或加载路径之外的某个绝对路径加载的模块。

4 个答案:

答案 0 :(得分:1)

模块根本不存储定义它们的文件位置。你可以在their definition in C中看到自己。你唯一的希望是浏览他们所持有的绑定。

另一方面,方法确实存储了他们的文件位置。 eval是每个module中定义的一个函数(尽管不是baremodule)。稍微更正确的可能是:

moduleloc(mm::Module) = first(functionloc(mm.eval, (Any,)))

因为它更准确地反映了自动定义的eval方法。

答案 1 :(得分:0)

如果您没有寻找编程方式,可以使用methods功能。

using DataFrames
locations = methods(DataFrames.readtable).ms

它适用于所有方法,但除非你有大量的方法只是在很小的方面有所不同,否则找到合适的方法并不困难。

答案 2 :(得分:-1)

require显然需要执行该操作。回顾loading.jl,我发现找到模块路径最近发生了一些变化:在v0.6.0中,有一个函数

load_hook(prefix::String, name::String, ::Void)

你可以打电话"手动":

julia> Base.load_hook(Pkg.dir(), "DataFrames", nothing)
"/home/philipp/.julia/v0.6/DataFrames/src/DataFrames.jl"

然而,current master已经变得更好了;现在有一个函数find_package,我们可以复制它:

macro return_if_file(path)
    quote
        path = $(esc(path))
        isfile(path) && return path
    end
end

function find_package(name::String)
    endswith(name, ".jl") && (name = chop(name, 0, 3))
    for dir in [Pkg.dir(); LOAD_PATH]
        dir = abspath(dir)
        @return_if_file joinpath(dir, "$name.jl")
        @return_if_file joinpath(dir, "$name.jl", "src", "$name.jl")
        @return_if_file joinpath(dir,   name,     "src", "$name.jl")
    end
    return nothing
end

并添加一个小帮手:

find_package(m::Module) = find_package(string(module_name(m)))

基本上,这需要Pkg.dir()并查看"常用位置"。

此外,v0.6.0中的chop并没有采用这些额外的参数,我们可以通过添加

来解决这些问题
chop(s::AbstractString, m, n) = SubString(s, m, endof(s)-n)

此外,如果您不在Unix上,则可能需要关注链接代码上方isfile_casesensitive的定义。

如果你不是那么关心角落案件,也许这就足够了,或者可以作为基础:

function modulepath(m::Module)
    name = string(module_name(m))
    Pkg.dir(name, "src", "$name.jl")
end

答案 3 :(得分:-1)

julia> Pkg.dir("DataStructures")
"/home/liso/.julia/v0.7/DataStructures"

编辑:我现在意识到你想使用Module对象!

julia> m = DataStructures
julia> Pkg.dir(repr(m))
"/home/liso/.julia/v0.7/DataStructures"

Edit2:我不确定你是否正在尝试找到模块中的路径或模块中定义的对象(我希望从下一个结果中解析路径很容易):

julia> repr(which(DataStructures.eval, (String,)))
"eval(x) in DataStructures at /home/liso/.julia/v0.7/DataStructures/src/DataStructures.jl:3"