コンパイラとの対話 (:meta を使った操作)
特定のコードブロックが特殊な意味を持つというヒントあるいは指令をコンパイラに与えたくなる状況が存在します。例えばコードを必ずインライン化したい場合や、特別なコンパイラ最適化パスを有効にしたい場合です。バージョン 0.4 以降の Julia では、こういった指令は :meta
式に配置するという慣習になっています。通常 :meta
は関数本体の最初の式となります (が、そうでなくても構いません)。
:meta
式はマクロを使って作成します。例として @inline
マクロの実装を考えます:
macro inline(ex)
esc(isa(ex, Expr) ? pushmeta!(ex, :inline) : ex)
end
ここで ex
には関数を定義する式が与えられると想定しています。このとき式
@inline function myfunction(x)
x*(x+3)
end
は、次の式に変換されます:
quote
function myfunction(x)
Expr(:meta, :inline)
x*(x+3)
end
end
Base.pushmeta!(ex, :symbol, args...)
は ex
内の :meta
式の最後に :symbol
を追加します (ex
が :meta
式を持たなければ新しく作成します)。args
が与えられると、:symbol
を先頭に持ち以降に引数を持つ式が追加されます。これは追加情報を指定するときに利用できます。
メタデータを使うには、追加した :meta
式をパースする必要があります。行いたい操作が Julia だけで実装できるときは Base.popmeta!
を利用できます: Base.popmeta!(body, :symbol)
は関数の body
式 (関数シグネチャを持たない式) をスキャンして :symbol
を持つ最初の :meta
式を見つけ、引数を取り出し、タプル (found::Bool, args::Array{Any})
を返します。メタデータが引数を持たないときと :symbol
が見つからなかったときは args
は空になります。
C++ から :meta
式をパースする手軽なインフラはまだ提供されていません。