以“表达式"形式检索方法内容 [英] Retrieve method content as an `Expr`ession

查看:20
本文介绍了以“表达式"形式检索方法内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数f定义如下.

I have a function f defined as follows.

f(x, y) = 3x^2 + x*y - 2y + 1

如何检索此方法的以下 quote 块,其中包括函数内容?

How can I retrieve the following quote block for this method, which includes the function contents?

quote  # REPL[0], line 2:
    ((3 * x ^ 2 + x * y) - 2y) + 1
end

推荐答案

正如人们在评论中提到的那样,像这样挖掘方法的字段并不是一个稳定的或官方支持的 API.此外,您的简单示例具有欺骗性.通常,这并不代表您为该方法编写的原始代码.它是一种简化的中间 AST 表示,具有单赋值变量和大大简化的控制流.通常,它返回的 AST 不是有效的顶级 Julia 代码.对于您的简单示例,恰好是这样.

As folks have mentioned in the comments, digging through the fields of the methods like this isn't a stable or officially supported API. Further, your simple example is deceiving. This isn't, in general, representative of the original code you wrote for the method. It's a simplified intermediate AST representation with single-assignment variables and drastically simplified control flow. In general, the AST it returns isn't valid top-level Julia code. It just so happens that for your simple example, it is.

也就是说,有一个记录在案的方法可以做到这一点.您可以使用 code_lowered() 无需挖掘未记录的字段即可访问此中间表示.这将适用于 Julia 版本,但我认为还没有官方保证中间表示的稳定性.这是一个稍微复杂一点的例子:

That said, there is a documented way to do this. You can use code_lowered() to get access to this intermediate representation without digging through undocumented fields. This will work across Julia versions, but I don't think there are official guarantees on the stability of the intermediate representation yet. Here's a slightly more complicated example:

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 历史记录.看看镓是怎么做到的.

If you really want to see the code exactly as it was written, the best way is to use the embedded file and line information and refer to the original source. Note that this is precisely the manner in which Gallium.jl (Julia's debugger) finds the source to display as it steps through functions. It's undocumented, but you can even access the REPL history for functions defined interactively. See how Gallium does it through here.

这篇关于以“表达式"形式检索方法内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆