如何替换Common Lisp中正在运行的功能? [英] How to replace a running function in Common Lisp?

查看:44
本文介绍了如何替换Common Lisp中正在运行的功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们使用SBCL的#'save-lisp-die来创建服务器应用程序App1,该服务器应用程序效果很好.现在我们要用新版本替换功能#'func1而不停止App1.我们如何在Common Lisp中做到这一点?

Suppose we use SBCL's #'save-lisp-and-die to create an server applicatioon App1, which works very well. Now we want to replace a function #'func1 with a new version without stopping App1. How can we do it in Common Lisp ?

任何建议都值得赞赏!

推荐答案

您需要加载新的函数定义.然后新功能将立即可用;代码将调用新加载的函数.

You need to load the new function definition. Then new function will be available immediately; code will call newly loaded function.

可以通过多种方式加载新函数定义:

New function definition may be loaded in many ways:

  • (load (compile-file "file.lisp")),其中file.lisp是函数的源代码
  • (load "file.fasl")其中file.fasl是已编译的源代码
  • (eval (defun ...))
  • (load (compile-file "file.lisp")) where file.lisp is a source code for function
  • (load "file.fasl") where file.fasl is compiled source code
  • (eval (defun ...))

当然,有例外和复杂之处:

Of course, there are exceptions and complications:

  • 这不会替代先前功能的已经运行的调用;例如,无法以这种方式更改无限事件循环-它必须支持某种停止和调用新函数.但是,这种长时间运行的功能很少见.可以通过使用递归而不是循环来解决此问题(但并非所有编译器都进行尾调用优化).
  • 如果您在某处抓取了一个指向函数的指针(例如,按(function FOO),其中FOO是函数的名称),它将保留其旧值.为避免这种情况,请使用符号代替函数指针(符号可以funcall).
  • 函数的代码需要进行垃圾回收.您应注意不要留下对函数旧版本的引用.另外,如果不需要某些功能,则不要忘记fmakunbound它们的符号.
  • 如果该函数是在编译时使用的,则所有受影响的代码也都应重新加载
  • 如果您进行了高级优化(默认情况下未启用),则编译器可能会将函数内联到其他函数中. CLHS会区分重新定义功能成为未定义行为"的情况.
  • This will not replace already running calls of previous functions; for example, an infinite event loop can not be changed this way - it will have to support some kind of stopping and calling a new function. However, such long-running functions are rare. It can be worked around by using recursion instead of looping (but not all compilers do tail-call optimization).
  • If you somewhere grabbed a pointer to function (for example, by (function FOO) where FOO is the name of a function), it will retain its old value. To avoid this, use symbols instead of function pointers (symbols are funcallable).
  • The code of a function is a subject to garbage collection. You should be careful not to leave references to old versions of a function lying around. Also, if some functions become not needed, you should not forget to fmakunbound their symbols.
  • If the function was used at compile time, all of the affected code should also be reloaded
  • If you had high levels of optimization (which is not by default), compiler might have inlined the function into others. CLHS discriminates the cases when redefining a function becomes «undefined behavior».

但是实际上,代码重装在大多数Common Lisp实现中都可以很好地工作.

But in practice, code reloading works well in most Common Lisp implementations.

这篇关于如何替换Common Lisp中正在运行的功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆