2024 Clojure调查问卷中分享您的想法!

欢迎!请查阅关于页面了解有关如何使用此功能的一些更多信息。

0
REPL
编辑

上下文:我已经从互联网上解析了一些大量的XML数据。现在我想在REPL中探索/过滤/深入挖掘。

我有一个名为xs的未知长度和内容的LazySeq。我想在REPL中探索xs的前几个元素。为了方便,我想要这样def一些变量:

(def x1 (nth xs 0 nil))
...
(def x5 (nth xs 4 nil))

这需要输入很多,尤其是当我需要重复进行,以开发我的“深入挖掘”函数时。有没有什么便利的函数(或宏)可以帮我做到这一点?也许像这样

(defmany xs "x" 5)
;=> #'my.ns/x1
;=> ...
;=> #'my.ns/x5

我尝试写了一个函数来做这个。它使用eval不安全(还有其他缺点)。所以,我的问题是

  1. 这种东西存在吗?
  2. 我需要写一个宏吗?或者可以用一个函数完成这个任务?(我不熟悉编写Clojure宏)
  3. 如何定义这个函数/宏?

为了娱乐,这是我的尝试

(defn def-many
  [xs prefix n]
  (map eval
       (for [i (range n)]
            (list 'def
                  (symbol (str prefix (inc i)))
                  (nth xs i nil)))))

(如果(nth xs i nil)是一个LazySeq或一个列表,那么eval将尝试将其解释为一个函数调用。这可以进行测试,并转换为向量等。但这是不是很好。)

1 回答

+2

已选择
 
最佳答案

此操作不需要 eval(由于你所控制的所有实际被 eval 的事物,在这个上下文中也不存在安全问题)

(let [data (vec (range 10))]
  (dotimes [idx (count data)]
    (intern *ns* (symbol (str "x" idx)) (nth data idx))))

=> x5
5

但是,而不是进行这样的事情,我强烈建议使用 tap> 那些数据,并使用 Portal、Reveal、REBL 等工具。与在纯文本 REPL 中浏览复杂的嵌套数据相比,这种方式方便得多。

`intern`,这就够了!谢谢!是的,关于 Portal/Reveal/REBL 的建议也很有帮助。再次感谢!
...