通过 Julia 中的外部函数或宏获取执行文件的路径
get path of the executed file through external function or macro in Julia
我正在尝试编写一个不带参数的辅助函数或宏来记录文件名和调用位置的行。
助手位于不同的模块中并导入到脚本中,因此 @__FILE__
和 @__LINE__
不会指向正确的位置。
这是我的辅助模块 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)
运行 julia caller.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_FILE 给我 caller.jl
是偶然还是有更多的保证?
我会更乐意从 __source__.file
中提取路径,因为 __source__.line
将我指向确切文件中的确切行,但是当我尝试时 __source__.file
是 nothing
.
文档中有两部分。 first one:
In addition to the given argument list, every macro is passed extra arguments named __source__
and __module__
.
The argument __source__
provides information (in the form of a LineNumberNode
object) about the parser location of the @ sign
from the macro invocation.
Source location information is represented as (line line_num file_name)
where the third component is optional (and omitted when the current line number, but not file name, changes).
These expressions are represented as LineNumberNode
s in Julia.
有没有办法爬上 LineNumberNode
链来获取文件名而不是 nothing
?
也许还有一种方法可以将 %__FILE__
的计算延迟到运行时,这样我就可以在 trace
?
中使用该构造
类似讨论:
引用 __source__
是 Julia 手册中推荐的。这是一个例子
文件f1.jl
module Trace
export @trace
macro trace()
return QuoteNode(__source__)
end
end # module
文件f2.jl
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)
文件f3.jl
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
特别是:
@trace
returns 你 LineNumberNode
对象有两个字段(但我知道这就是你想要的)
- 你可以看到
PROGRAM_FILE
给了你不同的信息:它是从命令行传递给 Julia 的文件的名称(所以在我们的例子中是 f3.jl
,虽然它是在 f2.jl
文件中调用,该文件由 f3.jl
编写 include
)。
现在清楚了吗?
这是我根据@Bogumił Kamiński 的回答和 answer on type conversion:
得出的代码
struct Location
file:: String
line:: Integer
end
macro trace()
return Location(String(__source__.file), __source__.line)
end
文档给我的印象是需要 QuoteNode
才能访问 __source__
内容,实际上您只需将 Symbol
__source__.file
转换为 String
。
还是不明白,为什么__source__.file
一定要Symbol
亲身体验,一定是有原因的。
我正在尝试编写一个不带参数的辅助函数或宏来记录文件名和调用位置的行。
助手位于不同的模块中并导入到脚本中,因此 @__FILE__
和 @__LINE__
不会指向正确的位置。
这是我的辅助模块 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)
运行 julia caller.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_FILE 给我 caller.jl
是偶然还是有更多的保证?
我会更乐意从 __source__.file
中提取路径,因为 __source__.line
将我指向确切文件中的确切行,但是当我尝试时 __source__.file
是 nothing
.
文档中有两部分。 first one:
In addition to the given argument list, every macro is passed extra arguments named
__source__
and__module__
.The argument
__source__
provides information (in the form of aLineNumberNode
object) about the parser location of the@ sign
from the macro invocation.
Source location information is represented as
(line line_num file_name)
where the third component is optional (and omitted when the current line number, but not file name, changes).These expressions are represented as
LineNumberNode
s in Julia.
有没有办法爬上 LineNumberNode
链来获取文件名而不是 nothing
?
也许还有一种方法可以将 %__FILE__
的计算延迟到运行时,这样我就可以在 trace
?
类似讨论:
引用 __source__
是 Julia 手册中推荐的。这是一个例子
文件f1.jl
module Trace
export @trace
macro trace()
return QuoteNode(__source__)
end
end # module
文件f2.jl
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)
文件f3.jl
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
特别是:
@trace
returns 你LineNumberNode
对象有两个字段(但我知道这就是你想要的)- 你可以看到
PROGRAM_FILE
给了你不同的信息:它是从命令行传递给 Julia 的文件的名称(所以在我们的例子中是f3.jl
,虽然它是在f2.jl
文件中调用,该文件由f3.jl
编写include
)。
现在清楚了吗?
这是我根据@Bogumił Kamiński 的回答和 answer on type conversion:
得出的代码struct Location
file:: String
line:: Integer
end
macro trace()
return Location(String(__source__.file), __source__.line)
end
文档给我的印象是需要 QuoteNode
才能访问 __source__
内容,实际上您只需将 Symbol
__source__.file
转换为 String
。
还是不明白,为什么__source__.file
一定要Symbol
亲身体验,一定是有原因的。