私は次のように定義された関数f
を持っています。メソッドの内容を `Expr`セッションとして取得する
f(x, y) = 3x^2 + x*y - 2y + 1
はどのようにして、機能の内容が含まれ、この方法は、以下のquote
ブロックを取得することができますか?
quote # REPL[0], line 2:
((3 * x^2 + x * y) - 2y) + 1
end
私は次のように定義された関数f
を持っています。メソッドの内容を `Expr`セッションとして取得する
f(x, y) = 3x^2 + x*y - 2y + 1
はどのようにして、機能の内容が含まれ、この方法は、以下のquote
ブロックを取得することができますか?
quote # REPL[0], line 2:
((3 * x^2 + x * y) - 2y) + 1
end
コメントに記載されているように、このようなメソッドのフィールドを掘り下げることは、安定したAPIまたは正式にサポートされているAPIではありません。さらに、あなたの単純な例は欺かれています。これは、一般に、メソッドのために記述した元のコードを表すものではありません。これは、単一代入変数と大幅に簡素化された制御フローを使用した単純化された中間AST表現です。一般に、返すASTは有効な最上位のジュリアコードではありません。あなたの簡単な例では、それはまさにそうです。
つまり、これを行うための文書化された方法があります。 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履歴にアクセスすることさえできます。 See how Gallium does it through here。
まず、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
ここから、Expr
セッションの取得は簡単です。単にメソッドのlambda_template
属性を使用してください。
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)
編集:これは、ジュリアのv0.6の+にない作業を行います!
これはJuliaのバージョン間では安全ではありません。 –
@ChrisRackauckasおっと、私はそれを実現していませんでした。私はそれを安全にすることができる方法はありますか?そうでなければ、v0.6 +でこの動作を具体的にどのように生成できますか? –
これを安全にする方法がわかりません。参考までに、これと関連する変更は[デバッガGalliumがv0.6で壊れている理由](https://github.com/Keno/Gallium.jl/issues/153)です。本質的に、このような文書では見えないものは、ニュース記事なしでバージョン間で壊れるもの(内部と見なされるため)です。このような内部部品を使用することは、あなた自身の責任で行っています。 –