如何抓住已经提到:#和#x27;clojure.core/=在命名空间:user中,替换为:#';用户/=”;在Clojure?

如何抓住已经提到:#和#x27;clojure.core/=在命名空间:user中,替换为:#';用户/=”;在Clojure?,clojure,Clojure,在我的应用程序中,我为用户提供了一些界面,他们可以提供代码,并且应用程序在沙盒中评估代码(因此evalfn是不允许的)。问题是,如果用户覆盖了一些内置函数,例如= 有没有办法抓住并阻止这件事 代码: (defn = [] //some code) WARNING: = already refers to: #'clojure.core/= in namespace: user, being replaced by: #'user/= 一种解决方案可能是: 我试图以String的形式获

在我的应用程序中,我为用户提供了一些界面,他们可以提供代码,并且应用程序在沙盒中评估代码(因此
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 = [])) 
;=> ""
还写道,带有err str的
(在没有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工具重新定义变量:

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=> 
另一个选择,也许你最好的选择是使用
处理这个(以及许多其他事情)。如果您正在寻找sandbox Clojure,我建议您看看。

一个解决方案可能是这样的:

(def before (set (vals (ns-map *ns*))))

(defn = [])

(def after (set (vals (ns-map *ns*))))

(clojure.set/difference before after)

;=> #{#'clojure.core/=}

>他们可以提供代码,应用程序会评估这些代码,然后你们怎么做?(编辑问题plz)是的,你是对的,但有一些内部的事情我没有说,我想我需要说,因为它在沙箱中运行eval fn是不允许的:/但我真的很喜欢你的答案,我会尝试让它对我的用例起作用我已经在使用clojail了,是的,它也起作用了!(让[writer(java.io.StringWriter.)](sb)(println“blah”){#err writer}(str writer));返回“blah\n”