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

欢迎!请查看关于页面以了解更多此网站的工作方式。

0
REPL
编辑

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

我有一个名为xs的未知长度和未知内容的LazySeq。我想在REPL中探索xs的前几个元素。出于方便,我想这样做

(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或list,则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 的建议非常好。再次感谢!
...