関数内から、関数外で定義された var の名前を取得したいと思います。名前は、実際に名前を使用しようとしているネストされたバインディングではなく、元の定義のスコープで使用した名前にする必要があります。
だから私は(学術的な例)のようなことをしたいと思います:
(defn f1 [x1] (println "hello, you passed var name >>" (get-var-name x1) "<<")
(defn f2 [x2] (f1 x2))
(defn f3 [x3] (let [zzz x3] (f2 zzz))
(def my-var 3.1414926)
(f3 my-var)
user> hello, you passed var name >>my-var<<
私が見つけたいくつかのものに基づいて、このマクロを実行できます。
(defmacro get-var-name [x]
`(:name (meta (var ~x))))
これは、たとえば REPL から呼び出された場合に機能しますが、「内部」スコープから呼び出された場合、コンパイラはチョークします。
(defn another-func [y]
(get-var-name y))
コンパイラは、「変数 y を解決できないと言っています」と言います。 (macroexpand...)
は、現在の名前空間の元の変数ではなく、現在の名前空間でローカル変数 y を見つけようとしていることを示しています。) は名前空間変数のみを(var...
検索するため、マクロが関数内またはlet
.
変数を定義し、それを追加のパラメーターとして渡すのと同じスコープから変数名を手動で取得する必要があることに行き詰まっていると思います。変数名情報をバインディングのチェーンを介して、それが使用されるポイントに渡すよりエレガントな方法はありますか? それはまずいでしょう。
ありがとう