7

作業中の Clojure コード (Leiningen プロジェクト) を 1.2 から 1.3 に移植していますが、問題があります。コード自体が機能しなくなったことに加えて、次のような警告メッセージが多数表示されます。

Warning: *tooltip-width* not declared dynamic and thus is not dynamically rebindable, 
but its name suggests otherwise. Please either indicate ^:dynamic *tooltip-width* 
or change the name.

これは、状態を維持するために使用している変数に正しい変更を加えたように見えるにもかかわらず、発生しています。たとえば、上記のエラーの場合、コードには既に次のものが含まれています。

(def ^:dyanamic *tooltip-width*   (* 1.8 *slip-width*))

これらのエラーは 2 つの場所で発生しlein swankます。次に、Emacs REPL から、core.cljファイルをコンパイルした後、 C-c C-w.

完全に完了するために、ここに私のproject.cljファイルがあります:

(defproject infwb "1.0.0-SNAPSHOT"
  :description "an evolving, experimental workspace for manipulating infocards"
  :main infwb.core

  :dependencies [[org.clojure/clojure "1.3"]
             [seesaw "1.2.1"]
         [org.clojars.gw666/sxqj "beta2"]
         [org.clojars.gw666/piccolo2dcore "1.3"]
         [org.clojars.gw666/piccolo2dextras "1.3"]
         [com.miglayout/miglayout "3.7.4"]
         ]
  :dev-dependencies [[swank-clojure "1.3.2"]
             [org.clojars.weavejester/autodoc "0.9.0"]]
  :autodoc {:name "Infocard Workbench (InfWb)",
        :web-src-dir "https://github.com/gw666/infwb/blob"})

コードを機能させることに加えて、これらのエラーが発生する理由と、両方の場所でエラーが発生する理由を理解したいと思います。ご協力いただきありがとうございます。

4

2 に答える 2

16

単純なタイプミスです。

(def ^:dyanamic ...

次のようにする必要があります。

(def ^:dynamic ...

私たち全員に起こります!

于 2011-11-21T23:34:08.080 に答える
12

状態を維持するために、var の代わりに ref または atom を使用することを検討することをお勧めします。

Clojureのドキュメントを引用するには:

Vars は、スレッドごとに (新しいストレージの場所に) 動的に再バインドできる変更可能なストレージの場所を参照するメカニズムを提供します。

(私のものを強調してください。)

bindingVars は、マクロを使用して (現在のスレッドの) 新しい値に設定できます。Clojure 1.2 までは、任意の変数をこのように再バインドできましたが、Clojure 1.3 以降では、^:dynamicこれを許可するために変数を明示的に宣言する必要があります。(私が知る限り、その理由は、再バインドがない一般的なケースでの var ルックアップの大幅な高速化です。)

次のようなリバウンド名を意図した vars を与えることは一般的な規則です (ただし、それ以上のものではありません) *foobar*。この慣例により、動的として宣言されていないこのような名前の var を検出すると、コンパイラは警告を出します。

総括する:

  • 実行時に変更されない値を宣言するだけの場合は、var を使用して、名前の前後の * を削除します。
  • スレッドごとに値を変更する場合は、var dynamic を宣言します。
  • (スレッドごとではなく)グローバルな状態を維持する場合は、他の参照型のいずれかを使用します: atomref(トランザクションが必要な場合) またはagent(非同期変更の場合)。
于 2011-11-22T09:11:37.450 に答える