3

clj (clojure) 名前空間に次のコードがあります。

(ns project.clojure.clojurescript-macros)

(def trace-history (atom []))

; hmm, you could run out of memory on recursive functions here?
; Fortunately functions aren't actually recursive in clojure. :]
(defmacro push-args [name args]
  `(swap! trace-history
     (fn [stack#]
       (conj stack# [~name (zipmap ~(vec (map str args)) ~args)]))))

(push-args :hello [:a :b :c])

別のcljs(clojurescript)名前空間内に、次のものがあります

(ns project.clojurescript.user   
  (:require-macros [project.clojure.clojurescript-macros :as c]))

(c/push-args :hello [:a :b :c])

clojurescript コードをコンパイルしてブラウザーで開くと、残念ながら次のエラーが表示されます。

Uncaught TypeError: Cannot read property 'trace_history' of undefined main.js:22348
(anonymous function)                                                  main.js:22348

コンパイルした clojurescipt コードの 22348 行を見ると、次のように表示されます。

cljs.core.swap_BANG_.call(null, project.clojure.trace_history, function(stack__6402__auto__) {
  return cljs.core.conj.call(null, stack__6402__auto__, 
    cljs.core.PersistentVector.fromArray(["\ufdd0'hello", 
      cljs.core.zipmap.call(null, 
        cljs.core.PersistentVector.fromArray([":a", ":b", ":c"], true),          
        cljs.core.PersistentVector.fromArray(["\ufdd0'a", "\ufdd0'b", "\ufdd0'c"], 
      true))], 
    true))
  });

問題は、 project.clojure.trace_history が main.js のどこにも定義されていないことです。何が悪いのかは理解していますが、どのように修正すればよいかわかりません。trace-history を共有 clojure ファイルに入れたり、トレース履歴を cljs ファイル自体に入れたりするなど、他の解決策を試しました。どれも機能していないようです。このマクロのすべてのコンパイル間でグローバル アトムを共有したい場合、Clojurescript でどのようにすればよいでしょうか?

4

1 に答える 1

3

アトムは実行時のデータであり、マクロはコンパイル時の構造です。マクロが「共有グローバルアトム」を持つことは実際には意味がありません.マクロが行うことは、現在のNSで呼び出されるシンボルがあることを単に期待するコードにコンパイルすることです.trace-history

アトムを使用できる共通コードを単純に書きたい場合は、ハードコーディングされたシンボル名を介してアトムの存在を想定するのではなく、引数としてアトムを取ることができるように記述する必要があります。

Clojure+ClojureScript アプリケーションのクライアントとサーバーの両方で同じアトムの値を利用できるようにしたい場合は、Ajax 呼び出しを介して値を調整する独自のコードを作成する必要があります...それは構築されたものではありません言語に。

于 2012-10-02T15:43:45.873 に答える