是否可以在 csi (鸡计划解释器)解释程序代码时更新程序代码?如果是这样,怎么样?
这样我就可以交互式地更改部分代码并立即看到这些更改的效果。 例如,假设我编写了以下程序:
(define (loop)
(print "Ciao")
(rest 1)
(loop))
(loop)
(假设(rest 1)
具有暂停程序一秒钟的效果。)
如果我运行这个程序,通过 csi ,它会打印字符串" Ciao"每一秒。如果我改变字符串" Ciao"进入别的东西,例如进入" else",然后我保存程序代码文件,然后 csi 继续解释旧的程序代码,所以我不断看到字符串"侨&#34 ;.在这种情况下,我希望当我用字符串" Ciao"保存修改后的代码时替换为"否则", csi 通过查看修改后的文件而不是旧文件来继续其解释作业。 所以我获得了一些" Ciao"其次是一些"否则":"否则"当我取代" Ciao"时开始出现by" else"在源代码中。
答案 0 :(得分:2)
一般来说,答案是"不要"。你应该使用REPL的方式是评估对它的零碎变化,然后评估一两个函数,以确保一切按预期进行。这种方法的一部分是构建您的程序,以便可以轻松地分段测试,这意味着不会自动启动任何无限循环。在您要询问的特定情况下,您可以改为编写
(define (do-stuff)
(print "Ciao"))
(define (main-loop)
(do-stuff)
(rest 1)
(main-loop))
(define (start) (main-loop))
您现在可以逐步开发do-stuff
,定期评估解释器的新版本并调用它们以确保它们正常工作,然后一旦您确信它已经确认它,最终会调用start
。做正确的事。
你可以从this similar question获得关于Common Lisp的里程数。
顺便说一句,如果您使用的是Common Lisp和SLIME,那么您现在可以做更多或更少的建议:
(defun do-stuff ()
(format t "Ciao~%"))
(defun main-loop ()
(loop (progn (do-stuff)
(sleep 1))))
(main-loop)
启动它会在SLIME REPL中的不同行上开始打印Ciao
。如果您将do-stuff
更改为
(defun do-stuff ()
(format t "else~%"))
然后使用C-c C-c
(slime-compile-defun
的默认绑定)点击它,您将看到您的SLIME REPL开始打印else
行。
CL-USER> (main-loop)
Ciao
Ciao
Ciao
; compiling (DEFUN DO-STUFF ...)else
else
else
else
else
else
; Evaluation aborted on NIL. User break.
CL-USER>
我不确定如何在Scheme中完成同样的事情,但我有理由相信它是可能的。
所有这些,你有时想要运行一个程序,其中一部分是无限的loop
。一个真实世界的例子是在测试某种TCP服务器时。如果您处于这种情况,并且您所需的工作流程
答案 1 :(得分:2)
没有一种常用的方法可以让正在运行的程序检查其变化来源,但是您似乎已经有足够多的可用于自己的游戏:
(use posix)
(use srfi-18)
(define (watch-reload! file)
(define (tsleep n)
(thread-sleep! (seconds->time (+ n (time->seconds (current-time))))))
(define (get-time)
(file-modification-time file))
(thread-start!
(lambda ()
(let loop ((filetime '()))
(let ((newtime (get-time)))
(when (not (equal? filetime newtime))
(load file))
(tsleep 10)
(loop newtime))))))
现在你所要做的就是使用watch-reload!
而不是load
,如果文件被修改,它将每10秒检查并重新加载一次。
如果您在文件无效时保存,它将停止工作,直到您再次呼叫watch-reload!
为止。
可能鸡程序员可能有更好的解决方案。