Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在LocalRepl中查看Clojure局部变量?_Clojure_Binding_Var_Read Eval Print Loop - Fatal编程技术网

如何在LocalRepl中查看Clojure局部变量?

如何在LocalRepl中查看Clojure局部变量?,clojure,binding,var,read-eval-print-loop,Clojure,Binding,Var,Read Eval Print Loop,我想通过在函数体中放置一个repl(带有clojure.main/repl)来处理和开发基于局部变量的表达式: (ns something) (defn myfunc [ p ] (let [local (+ p 10)] (clojure.main/repl) (+ local 100))) (myfunc 666) 当我执行此命令时,repl启动ok,但函数和本地let绑定的参数似乎在提示符中不可见: something=> p Compil

我想通过在函数体中放置一个repl(带有clojure.main/repl)来处理和开发基于局部变量的表达式:

(ns something)

(defn myfunc [ p ]
   (let [local (+ p 10)]
        (clojure.main/repl)
        (+ local 100)))

(myfunc 666)
当我执行此命令时,repl启动ok,但函数和本地let绑定的参数似乎在提示符中不可见:

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
我已经能够通过创建新的^:动态变量并使用绑定在本地设置它们的值来传递值,但这相当复杂,需要为每个局部变量单独绑定:

(def ^:dynamic x)

(defn myfunc [ p ]
   (let [local (+ p 10)]
        (binding [x local]
                 (clojure.main/repl))
        (+ local 100)))

在这种本地repl中是否有更简单的方法来传递/访问本地值?或者是否有更好的方法从非局部repl访问局部变量,例如“lein repl”?

我不知道使用repl的好答案,但我喜欢使用好的老式打印输出。这是由
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的文档,还有。

使用
: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)


您可以使用
repl
fn的
:init
钩子来定义变量。谢谢,:init看起来很有希望。文档上说:“init,无参数函数,初始化钩子调用,绑定set!-可设置变量。”但我在谷歌上找不到任何例子如何使用:init传递值,你能提供一个吗?感谢间谍信息!这绝对是我调试工具箱中的一个好工具。我还一直在寻找当场使用repl的方法,因为我的主要用途是方便开发基于现有值的新表达式(而不仅仅是查看现有值)。此
defs
函数不正确。用一个值为列表的本地函数来尝试:它将尝试调用
1
。您至少应该引用以下值:
(eval(list'def(符号k)(list'quote v))
(defn myfunc [p]
  (let [local (+ p 10)]
    (repl)
    (+ local 100)))