在read-string和load-string之间是否有一个Clojure函数?

3

我想把整个字符串读入一个列表中,但不进行评估。有没有什么函数或组合函数可以做到这一点,wtf?

user=> (wtf?  " S  I I ( S I I)")
(S I I (S I I))

该功能还应具备以下几个方面的能力:
user=> (last (wtf?  " S  I I ( S I I)"))
(S I I)

read-string只返回第一个对象,而load-string返回它们全部,但试图对它们进行求值。

2个回答

2

这是我使用的:

(defn safe-read
  "Evaluate the string in a safe way"
  [s]
  (binding [*read-eval* false]
    (read-string s)))

文档中提到:

"When set to logical false, the EvalReader (#=(...)) is disabled in the read/load in the thread-local binding. Example:

(binding [*read-eval* false] (read-string \"#=(eval (def x 3))\"))

这个函数会像平常一样读取字符串,但是禁用了计算功能。

因此,您可以使用此函数来读取打印出的地图、列表和向量,而不必担心评估恶意代码。(好吧,我确定在日常使用中它是安全的,但是这只是做到了工作而已)。


运行完美,但它看起来像魔法。它是如何使read-string读取所有对象的? - dansalmo

2

我是一个技术菜鸟。很高兴知道了“安全读取safe read”的方法,但实际上我的问题通过在表单周围添加()圆括号来解决了。我在试用“安全读取”时不经意间使用了这个方法。

user=> (read-string  "( S  I I ( S I I))")
(S I I (S I I))

user=> (last (read-string  "( S  I I ( S I I))"))
(S I I)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接