6

「clojure dynamic」と「clojure dynamic scope」をグーグル検索し、10 以上の記事を読みましたが、何が機能するのかまだ明確に理解してい^:dyanmicません。 この記事は私の質問に答えている可能性があると思いますが、コードサンプルが「欠落」しているように見えるため、混乱しているのと同じことを参照しているかどうかさえわかりません.

clj-httpプロジェクトの問題を修正しようとしていますが、まずコードを理解する必要があります。次のように定義された関数があります。

(defn ^:dynamic parse-html
  "Resolve and apply crouton's HTML parsing."
  [& args]
  {:pre [crouton-enabled?]}
  (apply (ns-resolve (symbol "crouton.html") (symbol "parse")) args))

しかし、それが何を意味するのか/何をするのかわかりません^:dynamic。誰かが本当に簡単な方法で私に説明できますか?

4

1 に答える 1

8

関数を動的スコープとして定義しています。

つまり、これにより、誰かが特定の関数呼び出しで再バインドparse-htmlし、その新しいバインディングをその特定の呼び出しから呼び出された関数にのみ適用することができます。

parse-html動的にスコープされていない場合、再バインドするとparse-html、再バインドを行った関数呼び出しによってアクティブ化されたコードだけでなく、使用するすべてのコードで新しいバインドが表示されます。

動的スコープは、グローバル スコープの変数の代わりとして役立ちます。関数は、「let current_numeric_base = 16; call other functions;」と言うことができます。他の関数はすべて 16 進数で出力されます。その後、それらが返され、ベース設定関数が返されると、ベースは元の状態に戻ります。 http://c2.com/cgi/wiki?DynamicScoping


以下のコメントで指摘されているように、Clojure では動的にスコープされていない変数を実際に再バインドすることはできません。可能であれば、レキシカル スコープの変数を更新すると、再バインドが発生した場所とは異なるコール スタックで実行されている場合でも、実行されるすべてのコードに影響します。

したがって、おそらくいくつかの疑似コードによって、動的スコープとレキシカル スコープの違いが明確になるでしょう。

動的スコープ変数の使用例:

(def ^:dynamic a 0)

(defn some-func [x] (+ x 1))

; re-binds a to 1 for everything in the callstack from the (binding)
; call and down
(binding [a 1] 
   (print (some-func a)))

 ; a was only re-bound for anything that was called from
 ; within binding (above) so at this point a is bound to 0.
(print (some-func a))

印刷します: 2 1

レキシカルスコープ変数の例:

(def a 0)

(defn some-func [x] (+ x 1))

; re-binds a to 1 for everyone, not just things that 
; are in the callstack created at this line
(set-var [a 1]  ; set-var is a made up function that can re-bind lexically scoped variables
   (print (some-func a)))

; a was lexically scoped so changing it changed
; it globally and not just for the callstack that
; contained the set-var.
(print (some-func a))

印刷します: 2 2

于 2013-04-01T02:58:42.440 に答える