[英]How to see Clojure local variables in local repl?
I want to play around and develop expressions based on local variables by placing a repl (with clojure.main/repl) inside a function body: 我想通过在函数体中放置一个repl(使用clojure.main / repl)来开发并基于局部变量开发表达式:
(ns something)
(defn myfunc [ p ]
(let [local (+ p 10)]
(clojure.main/repl)
(+ local 100)))
(myfunc 666)
When I executed this, the repl starts ok, but the parameters of the function and local let-bindings do not seem to be visible in the prompt: 当我执行此操作时,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
I have been able to pass the values by creating new ^:dynamic vars and setting their values locally with binding, but this is quite complex and requires separate binding for each local variable: 我已经能够通过创建新的^:动态变量并通过绑定在本地设置它们的值来传递值,但这非常复杂并且需要为每个局部变量单独绑定:
(def ^:dynamic x)
(defn myfunc [ p ]
(let [local (+ p 10)]
(binding [x local]
(clojure.main/repl))
(+ local 100)))
Is there simpler way to pass/access local values in such local repl? 是否有更简单的方法来传递/访问此类本地repl中的本地值? Or is there some better way to do access the local variables from non-local repl, such as the "lein repl"?
或者是否有更好的方法从非本地repl访问本地变量,例如“lein repl”?
Using the :init
hook, you can define arbitrary vars in the REPL namespace. 使用
:init
钩子,可以在REPL命名空间中定义任意变量。
(defn myfunc [p]
(let [local (+ p 10)]
(clojure.main/repl :init #(do (def p p) (def local local)))
(+ local 100)))
Here's a repl
macro to make adding a breakpoint easier: 这是一个
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#))))
Now you can just drop in (repl)
: 现在你可以直接进入
(repl)
:
(defn myfunc [p]
(let [local (+ p 10)]
(repl)
(+ local 100)))
I don't know a good answer for using the repl, but I favor using good old-fashioned printouts. 我不知道使用repl的好答案,但我赞成使用好的老式打印输出。 This is facilitated by the
spyx
, let-spy
, and let-spy-pretty
macros: 这是通过
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)))
with result: 结果:
p => 666
local => 676
(myfunc 666) => 776
Documentation on spyx
& friends is here in the README , and there is also full API documentation on GitHub pages . 有关
spyx
和朋友的文档在README中 ,并且还有关于GitHub页面的完整API文档 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.