编辑“正在运行”的程序?怎么用?

2024-05-28 18:54:27 发布

您现在位置:Python中文网/ 问答频道 /正文

这个问题是:Editing programs “while they are running”? Why?的必然结果

我最近才接触到Clojure的世界,对我看到的“live coding”非常着迷。上面链接的问题讨论了“为什么”

我的问题是:这种实时编码技术是如何实现的?它是否是clojure语言的一个特征使它成为可能?或者这仅仅是一种模式,可以应用于任何语言?我有python和java的背景知识。有没有可能像clojure一样用这两种语言中的任何一种“实时代码”?在


Tags: 语言live编码链接世界runningareclojure
3条回答

有些语言实现已经有很长一段时间了,特别是许多Lisp变体和Smalltalk。在

Lisp将标识符作为一种数据结构,称为符号。可以重新分配这些符号,并在运行时查找它们。这个原理被称为晚期结合。符号命名函数和变量。在

另外,Lisp实现在运行时要么有一个解释器或者甚至是一个编译器。接口是函数EVALCOMPILE。另外还有一个函数LOAD,它允许加载源代码和编译代码。在

接下来,像commonlisp这样的语言有一个对象系统,它允许对类层次结构、类本身进行更改,可以添加/更新/删除方法并将这些更改传播到已经存在的对象。因此,面向对象的软件和代码可以自行更新。使用元对象协议甚至可以在运行时重新编程对象系统。在

同样重要的是,Lisp实现可以垃圾收集删除代码。这样,运行中的Lisp不会因为代码被替换而在运行时大小上增长。在

Lisp通常还有一个错误系统,可以从错误中恢复,并允许从调试器中替换有缺陷的代码。在

JRebel是Java的一种解决方案。下面是他们FAQ的一段简短段落:

JRebel integrates with the JVM and application servers mainly on the class loader level. It does not create any new class loaders, instead, it extends the existing ones with the ability to manage reloaded classes.

这里有很多很好的答案,我不确定是否可以改进其中的任何一个,但是我想添加一些关于Clojure和Java的注释。在

首先,Clojure是用Java编写的,所以您肯定可以用Java构建一个实时的编码环境。只需将Clojure看作是一种特定风格的实时编码环境。在

基本上,Clojure中的实时编码是通过主.clj以及中的eval函数核心.clj(src/clj/CLJURE公司/主.clj和src/clj/clojure/核心.clj在github存储库中)。你阅读表格并将其传递给eval,后者调用clojure.lang.Compiler(src/jvm/clojure/lang/编译器.java回购中)。在

在编译器.java使用ASM库(ASM website heredocumentation here)将Clojure表单转换为JVM字节码。我不确定Clojure使用的是哪个版本的ASM库。此字节码(字节数组=>;byte[]字节码是编译器类的成员,该类最终将保存由clojure.asm.ClassWriter然后必须将类通过ClassWriter#toByteArray)转换为类并链接到正在运行的进程中。在

一旦将类表示为字节数组,就需要获取java.lang.ClassLoader,调用defineClass将这些字节转换为一个类,然后将生成的类传递给类加载器的resolve方法以将其链接到Java运行时。这基本上就是当你定义一个新函数时会发生的事情,你可以在编译器$FnExpr中看到编译器的内部结构,它是为函数表达式生成字节码的内部类。在

关于Clojure还有更多的事情要做,比如它处理名称空间和符号内部的方式。我不完全确定它是如何绕过这样一个事实的:标准类加载器不会用新版本的类替换链接类,但我怀疑这与类的命名方式和符号的内接方式有关。Clojure还定义了它自己的类加载器clojure.lang.DynamicClassLoader,继承自java.net.URLClassLoader,所以这可能与此有关;我不确定。在

最后,在类加载器和字节码生成器之间用Java进行实时编码。您只需提供一种方法,将表单输入到正在运行的实例中,评估表单,并将它们链接起来。在

希望这能对这个问题有一点启发。在

相关问题 更多 >

    热门问题