Path 通过Julia中的外部函数或宏获取执行文件的路径

Path 通过Julia中的外部函数或宏获取执行文件的路径,path,julia,metaprogramming,Path,Julia,Metaprogramming,我正在尝试编写一个没有参数的助手函数或宏,这些参数可以记录文件名和调用它的行 帮助程序位于不同的模块中,并导入到脚本中,因此@\uuuuu FILE\uuuuu和@\uuuu LINE\uuuu不会指向正确的位置 这是我的助手模块,位于trace.jl: module Trace export @trace, Location struct Location file:: String line:: Integer end macro trace() return L

我正在尝试编写一个没有参数的助手函数或宏,这些参数可以记录文件名和调用它的行

帮助程序位于不同的模块中,并导入到脚本中,因此
@\uuuuu FILE\uuuuu
@\uuuu LINE\uuuu
不会指向正确的位置

这是我的助手模块,位于
trace.jl

module Trace
export @trace, Location

struct Location
    file:: String
    line:: Integer
end

macro trace()
    return Location(abspath(PROGRAM_FILE), __source__.line)
end    

end
下面是一个脚本
caller.jl

include("trace.jl")
using .Trace

# putting two statements in one line so that line number is the same
println("I want: ", Location(@__FILE__, @__LINE__)); println(" I get: ", @trace)
运行
juliacaller.jl
的输出如下:

D:\github\Handout.jl\src>julia caller.jl
I want: Location("D:\\github\\Handout.jl\\src\\caller.jl", 5)
 I get: Location("D:\\github\\Handout.jl\\src\\caller.jl", 5)
我不确定PROGRAM_文件是否意外地为我提供了
caller.jl
,或者可以提供更多的保证

我会更乐意从
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

文档中有两个部分。委员会:

除了给定的参数列表外,每个宏都会被传递名为
\uuuuu source\uuuuuu
\uuuu module\uuuuu
的额外参数

参数
\uuuuuuuuuuuuuuuuuuuuuu
提供有关宏调用中
@符号的解析器位置的信息(以
LineNumberNode
对象的形式)

委员会:

源位置信息表示为
(line-line-line-num-file-name)
,其中第三个组件是可选的(当当前行号(而不是文件名)更改时,将省略)

这些表达式在Julia中表示为
LineNumberNode
s

有没有办法爬上
LineNumberNode
链来获取文件名而不是
nothing

另外,也许有一种方法可以将
%\uuuuuu文件的计算延迟到运行时,这样我就可以在
跟踪
中使用该构造

类似的讨论:
Julia手册中推荐引用
\uuuuu源代码。这里有一个例子

文件
f1.jl
文件
f2.jl
文件
f3.jl
运行上述 现在看一下输出:

$ julia f3.jl
I want: ("D:\\f2.jl", 5)
I get: #= D:\f2.jl:5 =#
LineNumberNode
  line: Int64 7
  file: Symbol D:\f2.jl
This is not what you want: f3.jl
特别是:

  • @trace
    返回有两个字段的
    LineNumberNode
    对象(但我知道这是您想要的)
  • 您可以看到,
    PROGRAM_FILE
    为您提供了一个不同的信息:它是从命令行传递给Julia的文件名(在我们的例子中,它是
    f3.jl
    ,尽管它是在
    f2.jl
    文件中调用的,而
    include
    d被
    f3.jl

这一点现在更清楚了吗?

以下是我根据@BogumiłKamiński的答案得出的代码:

文档给我的印象是,访问
源代码内容需要
QuoteNode
,事实上,您只需将
符号
源文件
转换为
字符串


仍然不清楚,为什么
\uuuu源文件
必须是
符号
的第一手资料,这一定有原因。

如此清晰的阐述,谢谢!还有一个问题:我应该尝试将文件路径从符号转换为字符串吗?例如,如果我想读取f2.jl的源代码,并且需要它的路径。是的,您可以将
Symbol
转换为
String
,然后使用此值读取该文件。
include("f1.jl")

using .Trace

println("I want: ", (@__FILE__, @__LINE__)); println("I get: ", @trace)

x = @trace
dump(x)

println("This is not what you want: ", PROGRAM_FILE)
include("f2.jl")
$ julia f3.jl
I want: ("D:\\f2.jl", 5)
I get: #= D:\f2.jl:5 =#
LineNumberNode
  line: Int64 7
  file: Symbol D:\f2.jl
This is not what you want: f3.jl
struct Location
    file:: String
    line:: Integer
end

macro trace()
    return Location(String(__source__.file), __source__.line)
end