gpt4 book ai didi

clojure - 如何捕获命名空间 : user, 中的 "= already refers to: #' clojure.core/= 被 : #'user/= " in Clojure? 替换

转载 作者:行者123 更新时间:2023-12-02 10:40:06 25 4
gpt4 key购买 nike

在我的应用程序中,我向用户提供一些接口(interface),他们可以提供代码,应用程序会在沙箱中评估该代码(因此不允许使用 eval fn)。问题是,如果用户覆盖一些内置函数,例如 =

有什么想法如何捕捉和防止那件事吗?(想法是他们不应该能够做到这一点)

代码:

(defn =
[]
//some code)

WARNING: = already refers to: #'clojure.core/= in namespace: user, being replaced by: #'user/=

一种解决方案可能是:

我试图以 String 形式获取警告消息,但 with-out-str 函数不起作用。

(with-out-str
(defn = []))
;=> ""

还写道with-err-str(稍微改变了with-out-str)也不起作用。

(defmacro with-err-str
[& body]
`(let [s# (new java.io.StringWriter)]
(binding [*err* s#]
~@body
(str s#))))

(with-err-str
(defn = []))
;=> ""

需要:“警告:=已引用:命名空间:user中的#'clojure.core/=,被替换为:#'user/="

最佳答案

当您使用eval时它确实有效:

user=> (with-err-str (eval '(defn - [] 11)))
"WARNING: - already refers to: #'clojure.core/- in namespace: user, being replaced by: #'user/-\n"
user=> (re-seq #"WARNING" (with-err-str (eval '(defn / [] 11))))
("WARNING")

或者您可以在用户代码中重新定义 defn 宏,但没有什么可以阻止他们使用其他 clojure 工具来重新定义 var:

user=> (defmacro defn-safe
#_=> [nam & decls]
#_=> (if (resolve (symbol "clojure.core" (name nam)))
#_=> (print "Whoops")
#_=> (list* `defn (with-meta nam (assoc (meta nam) :private true)) decls)))
#'user/defn-safe
user=> (defn-safe foo [x] (+ x 2))
#'user/foo
user=> (foo 22)
24
user=> (defn-safe = [a b] (- a b))
Whoopsnil
user=>

另一个选择,可能你最好的选择是使用 https://github.com/clojure/tools.analyzer

关于clojure - 如何捕获命名空间 : user, 中的 "= already refers to: #' clojure.core/= 被 : #'user/= " in Clojure? 替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45954973/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com