2011-10-27 12 views
2

[OK]を内部に具体化の一環として形をしましょう以下のように見えるScriptプロトコルのインスタンスであることを:ダイナミックは、のまっすぐこれを取得してみましょうマクロ

(defprotocol Script 
    (run [this model])) 

アイデアはdefscriptへの最初の引数はmodelに対応キーにバインドする必要のあるシンボルのリストであるということで

(.run (defscript [a b] (println a)) {:a 1}) ;; yields 1 

modelパラメータを使用しようとすると、マクロ展開時に、それはただの記号だから、私は常に、ハンガーノックてるように私は、効果的にこのような効果を生み出すことができます任意のコードを考え出すことはできません。

(defmacro invoke- 
    [params model body] 
    (let [p (flatten (map (fn [x] [x (model (keyword x))]) params))] 
    `(let [[email protected]] 
     ~body))) 

(defmacro defscript 
    [params & body] 
    `(reify Script 
    (run [~'this ~'model] 
     (invoke- ~params ~'model [email protected])))) 

invoke-直接呼び出す場合は正常に動作します:

(invoke- [a] {:a 1} (println a)) ;; prints 1 

しかし modelとして defscript内で使用されるとき、それは動作しませんが正しく展開することができません。

(.run (defscript [a] (println a)) {:a 1}) ;; prints nil 

どうすればこのポイントを超えて一緒に接着することができますか?それは基本的に、あなたの引数ベクトルが結合非構造のショートカットであると思われ

+0

「clojure.template」で提供されている機能とぼんやりとしているようです。 –

答えて

4

(defscript [a b] body) -> (reify Script (run [this {:keys [a b]}] body)) 

そのようにそれがあるべきように、モデルは、実行時に非構造されます。

+0

本当に素敵です! – kotarak

+0

純粋なawesomeness、ありがとう! – skuro

関連する問題