Retrieve method content as an `Expr`ession

后端 未结 2 431
长发绾君心
长发绾君心 2021-01-14 16:06

I have a function f defined as follows.

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

How can I retrieve the following quote bloc

相关标签:
2条回答
  • 2021-01-14 16:24

    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.

    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
    

    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.

    0 讨论(0)
  • 2021-01-14 16:32

    First, retrieve the method using methods(f).

    julia> methods(f)
    # 1 method for generic function "f":
    f(x, y) at REPL[1]:1
    
    julia> methods(f).ms
    1-element Array{Method,1}:
     f(x, y) at REPL[1]:1
    
    julia> method = methods(f).ms[1]
    f(x, y) at REPL[1]:1
    

    From here, retrieving the Expression is straightforward; simply use the lambda_template attribute of the method.

    julia> method.lambda_template
    LambdaInfo template for f(x, y) at REPL[1]:1
    :(begin 
            nothing
            return ((3 * x ^ 2 + x * y) - 2 * y) + 1
        end)
    

    Edit: This does not work in Julia v0.6+!

    0 讨论(0)
提交回复
热议问题