如何在本地 repl 中查看 Clojure 局部变量?
How to see Clojure local variables in local repl?
我想通过在函数体内放置一个 repl(使用 clojure。main/repl)来尝试和开发基于局部变量的表达式:
(ns something)
(defn myfunc [ p ]
(let [local (+ p 10)]
(clojure.main/repl)
(+ local 100)))
(myfunc 666)
当我执行这个时,repl 启动正常,但是函数的参数和本地 let-bindings 似乎在提示中不可见:
something=> p
CompilerException java.lang.RuntimeException: Unable to resolve symbol: p in this context
something=> local
CompilerException java.lang.RuntimeException: Unable to resolve symbol: local in this context
我已经能够通过创建新的 ^:dynamic 变量并通过绑定在本地设置它们的值来传递值,但这非常复杂并且需要为每个局部变量单独绑定:
(def ^:dynamic x)
(defn myfunc [ p ]
(let [local (+ p 10)]
(binding [x local]
(clojure.main/repl))
(+ local 100)))
是否有更简单的方法来 pass/access 此类本地 repl 中的本地值?或者是否有更好的方法从非本地 repl 访问本地变量,例如 "lein repl"?
我不知道使用 repl 的好答案,但我喜欢使用好的 old-fashioned 打印输出。 spyx
、let-spy
和 let-spy-pretty
宏有助于实现这一点:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test))
(defn myfunc [ p ]
(spyx p)
(let-spy [local (+ p 10)]
(+ local 100)))
(dotest
(spyx (myfunc 666)))
结果:
p => 666
local => 676
(myfunc 666) => 776
关于 spyx
和朋友 is here in the README, and there is also full API documentation on GitHub pages 的文档。
使用 :init
钩子,您可以在 REPL 命名空间中定义任意变量。
(defn myfunc [p]
(let [local (+ p 10)]
(clojure.main/repl :init #(do (def p p) (def local local)))
(+ local 100)))
这里有一个 repl
宏,可以更轻松地添加断点:
(defmacro locals []
(into {}
(map (juxt name identity))
(keys &env)))
(defn defs [vars]
(doseq [[k v] vars]
(eval (list 'def (symbol k) (list 'quote v)))))
(defmacro repl []
`(let [ls# (locals)]
(clojure.main/repl :init #(defs ls#))))
现在您可以直接进入 (repl)
:
(defn myfunc [p]
(let [local (+ p 10)]
(repl)
(+ local 100)))
我想通过在函数体内放置一个 repl(使用 clojure。main/repl)来尝试和开发基于局部变量的表达式:
(ns something)
(defn myfunc [ p ]
(let [local (+ p 10)]
(clojure.main/repl)
(+ local 100)))
(myfunc 666)
当我执行这个时,repl 启动正常,但是函数的参数和本地 let-bindings 似乎在提示中不可见:
something=> p
CompilerException java.lang.RuntimeException: Unable to resolve symbol: p in this context
something=> local
CompilerException java.lang.RuntimeException: Unable to resolve symbol: local in this context
我已经能够通过创建新的 ^:dynamic 变量并通过绑定在本地设置它们的值来传递值,但这非常复杂并且需要为每个局部变量单独绑定:
(def ^:dynamic x)
(defn myfunc [ p ]
(let [local (+ p 10)]
(binding [x local]
(clojure.main/repl))
(+ local 100)))
是否有更简单的方法来 pass/access 此类本地 repl 中的本地值?或者是否有更好的方法从非本地 repl 访问本地变量,例如 "lein repl"?
我不知道使用 repl 的好答案,但我喜欢使用好的 old-fashioned 打印输出。 spyx
、let-spy
和 let-spy-pretty
宏有助于实现这一点:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test))
(defn myfunc [ p ]
(spyx p)
(let-spy [local (+ p 10)]
(+ local 100)))
(dotest
(spyx (myfunc 666)))
结果:
p => 666
local => 676
(myfunc 666) => 776
关于 spyx
和朋友 is here in the README, and there is also full API documentation on GitHub pages 的文档。
使用 :init
钩子,您可以在 REPL 命名空间中定义任意变量。
(defn myfunc [p]
(let [local (+ p 10)]
(clojure.main/repl :init #(do (def p p) (def local local)))
(+ local 100)))
这里有一个 repl
宏,可以更轻松地添加断点:
(defmacro locals []
(into {}
(map (juxt name identity))
(keys &env)))
(defn defs [vars]
(doseq [[k v] vars]
(eval (list 'def (symbol k) (list 'quote v)))))
(defmacro repl []
`(let [ls# (locals)]
(clojure.main/repl :init #(defs ls#))))
现在您可以直接进入 (repl)
:
(defn myfunc [p]
(let [local (+ p 10)]
(repl)
(+ local 100)))