作者:余挺空荡荡_833 | 来源:互联网 | 2023-02-10 14:15
我有一个f
定义如下的函数.
f(x, y) = 3x^2 + x*y - 2y + 1
如何检索quote
此方法的以下块,其中包括函数内容?
quote # REPL[0], line 2:
((3 * x ^ 2 + x * y) - 2y) + 1
end
Matt B...
5
正如大家在评论中提到的那样,深入研究这样的方法领域并不是一个稳定的或官方支持的API.此外,你的简单例子是欺骗.通常,这不代表您为该方法编写的原始代码.它是一个简化的中间AST表示,具有单指派变量和极大简化的控制流程.通常,它返回的AST不是有效的顶级Julia代码.事实恰恰相反,对于你的简单例子,它就是这样.
也就是说,有一种记录的方法可以做到这一点.您可以使用code_lowered()
访问此中间表示而无需挖掘未记录的字段.这将适用于Julia版本,但我认为尚未对中间表示的稳定性进行官方保证.这是一个稍微复杂的例子:
julia> f(X) = for elt in X; println(elt); end
f (generic function with 1 method)
julia> code_lowered(f)[1]
LambdaInfo template for f(X) at REPL[17]:1
:(begin
nothing
SSAValue(0) = X
#temp# = (Base.start)(SSAValue(0))
4:
unless !((Base.done)(SSAValue(0),#temp#)) goto 13
SSAValue(1) = (Base.next)(SSAValue(0),#temp#)
elt = (Core.getfield)(SSAValue(1),1)
#temp# = (Core.getfield)(SSAValue(1),2) # line 1:
(Main.println)(elt)
11:
goto 4
13:
return
end)
julia> code_lowered(f)[1] == methods(f).ms[1].lambda_template
true
如果您确实希望完全按照编写的方式查看代码,最好的方法是使用嵌入的文件和行信息并参考原始源.请注意,这正是Gallium.jl(Julia的调试器)在逐步执行函数时查找源的方式.它没有文档,但您甚至可以访问交互式定义的函数的REPL历史记录.了解Gallium如何通过这里完成它.
1> Matt B...:
正如大家在评论中提到的那样,深入研究这样的方法领域并不是一个稳定的或官方支持的API.此外,你的简单例子是欺骗.通常,这不代表您为该方法编写的原始代码.它是一个简化的中间AST表示,具有单指派变量和极大简化的控制流程.通常,它返回的AST不是有效的顶级Julia代码.事实恰恰相反,对于你的简单例子,它就是这样.
也就是说,有一种记录的方法可以做到这一点.您可以使用code_lowered()
访问此中间表示而无需挖掘未记录的字段.这将适用于Julia版本,但我认为尚未对中间表示的稳定性进行官方保证.这是一个稍微复杂的例子:
julia> f(X) = for elt in X; println(elt); end
f (generic function with 1 method)
julia> code_lowered(f)[1]
LambdaInfo template for f(X) at REPL[17]:1
:(begin
nothing
SSAValue(0) = X
#temp# = (Base.start)(SSAValue(0))
4:
unless !((Base.done)(SSAValue(0),#temp#)) goto 13
SSAValue(1) = (Base.next)(SSAValue(0),#temp#)
elt = (Core.getfield)(SSAValue(1),1)
#temp# = (Core.getfield)(SSAValue(1),2) # line 1:
(Main.println)(elt)
11:
goto 4
13:
return
end)
julia> code_lowered(f)[1] == methods(f).ms[1].lambda_template
true
如果您确实希望完全按照编写的方式查看代码,最好的方法是使用嵌入的文件和行信息并参考原始源.请注意,这正是Gallium.jl(Julia的调试器)在逐步执行函数时查找源的方式.它没有文档,但您甚至可以访问交互式定义的函数的REPL历史记录.了解Gallium如何通过这里完成它.