编译后,一个程序可以假设运行而无需调用eval吗?

时间:2012-12-02 15:12:54

标签: macros clojure lisp eval

我正在学习Clojure是如何工作的,我想知道是否有可能(只是为了理解Clojure和Lisps方言一般是如何工作的)来编译Clojure程序然后运行它同时“禁止”使用 eval

请注意,我不会问,在技术上是否可以编写一个正在运行的Clojure程序,这样一旦编译了一个Clojure程序就会抛出异常,如果 eval 被调用。< / p>

我要问的是如果在技术上可以禁止使用 eval ,那么大多数Clojure程序都不使用REPL而不是具体 eval 还能运作吗?

或者是在运行时使用 eval 的默认/内置API /宏/函数?

3 个答案:

答案 0 :(得分:10)

eval是将交互式编程带到Clojure(和Lisps)的原因。一旦将Clojure代码编译为jvm字节代码(不在任何地方使用eval函数调用)或其他Lisp方言到目标运行时(主要是本机代码),就不需要eval。

eval应用程序的主要目的是在运行时生成代码并执行它,基本上它可以创建“运行时宏”,这不是语言的核心API需要做的它做了什么。

答案 1 :(得分:1)

我很久以前就问过这个问题而且我正在回答我自己的问题,因为其他信息出现了,漏洞也出现了,另一个问题 正确地解决了这个问题。 / p>

基本上,默认的读取功能是不安全的。

在所有关于这个问题的Ruby漏洞(人们突然感到担心安全问题)之后,2013年对Clojure团队进行了激烈的讨论,讨论的话题是:

  

read-eval 默认为false”

Clojure文档自己明确指出:

http://clojuredocs.org/clojure_core/clojure.core/read

;; WARNING: You SHOULD NOT use clojure.core/read or
;; clojure.core/read-string to read data from untrusted sources.  They
;; were designed only for reading Clojure code and data from trusted
;; sources

请注意,即使将 read-eval 设置为 false 也是不够的(至少直到至少Clojure 1.5为止),因为可以强制调用某些Java构造函数并通过精心制作恶意输入来产生副作用。

在博客文章中详细解释了这一点:“Clojure的读者不安全”

http://www.learningclojure.com/2013/02/clojures-reader-is-unsafe.html

长话短说:使用其他内容,例如clojure.edn

答案 2 :(得分:0)

可能公平地说:

  • eval的大多数使用是以交互方式(在REPL中)或在编译时(例如在扩展和执行宏期间)完成的。
  • eval的一些使用发生在常规代码中。它可能是一个有用的技巧,例如在电子表格程序中执行动态生成的数学公式时。

由于第二个原因,如果你全局禁止使用eval,即使所有内容都已经编译,你也会在运行时破坏很多代码/库。