2017-02-03 5 views
2

値が特定の型の場合にのみ式の値を変更できるマクロを定義できるかどうかは疑問です。マクロを使用した式の値へのアクセス

はここで、最小限の例です:

type Special 
    x::Int 
end 

f1(s, n::Special) = println("f1", s, n) 
f2(s, n::Special) = println("f2", s, n) 

x1 = Special(3) 
x2 = Special(5) 

expr = :(
    f1("this is f1", x1), 
    f2("this is f2", x2) 
    ) 

今、マクロ、関数に引数の値を調べx1x2がタイプSpecialであることを確認、修正するためにいくつかの機能を実行することができるかもしれませんそれらの値は、例えば3と4と5と2(2つの値の比較を含むかもしれない)を変更して、呼び出し元に式を戻します。最終的な結果は、呼び出すのと同じようになります:

f1("this is f1", 4) 
f2("this is f2", 2) 

私はそれを介して、マクロの値にアクセスすることができますことを発見:

eval(eval(filter(x -> typeof(eval(x)) == Special, expr.args[1].args))[1]).x 

=> 3 

が、これは動作しますが、それは間違って見える、と私はかもしれませんよ間違っているか、あまりにも何かをやろうとしているか...

答えて

3

いいえ、あなたはではありませんマクロ内の型または値をチェックしようとします。 evalを使ってマクロの中の何かのタイプや値を知ることは、非常に限られた状況ではうまくいくかもしれませんが、ほとんどの実際の使用では壊れてしまいます。代わりに、単にマクロの挿入にジェネリック関数の呼び出しを持っている - ジュリア(メソッド内)(メソッドの派遣など)のタイプと値を離れて選ぶに優れていることがあります:

munge_special(x::Special) = Special(x.x + 42) 
munge_special(x) = x 
macro do_something_special(x) 
    return :(munge_special($(esc(x)))) 
end 

julia> @do_something_special Special(2) 
Special(44) 

julia> @do_something_special 3 
3 
+0

おかげでマットを。私は私のアプローチを考え直しています... :) – daycaster

関連する問題