- 论坛徽章:
- 5
|
回复 86# OwnWaterloo
果然是这个………………这个的确叫reload,不过似乎叫“自动重载(auto reload)”我说的云风做的就是这个(不是Pluto神马的,你的dump把我误导了),最开始我说的就是这个。只是你说repl的结果最终可以persistent到文件这个说法把我误导了。
是的,我很想让Lua+Vim可以做到这样,需要做到这样的话,需要这样的工具:
1. Vim能向程序输出一个信号,表示某文件已改变。
2. Lua程序能收到这么一个(跨进程的)信号,得知文件已改变。
3. Lua能在不中断所有执行一致性的前提下,重新载入已改变的文件。
第一点不太难,不过得约定好输出的信号是啥。Vim自己内部本身是可以执行Lua程序的,所以将Vim本身作为host也不是不可以。但是Vim本身是个编辑器,编辑器有自己的事件循环,如果你的程序也有事件循环的话(基本上需要做自动重载的都有自己的事件循环——不然你也没办法重载啊),那基本上就是完蛋了。别的选择就不是很多了,socket,进程间通讯,消息队列,反正事儿不难,但也不太简单。
第一点解决,第二点就解决了。Vim保存文件并通知改变,Luahost的事件循环监听这个信号,并应用改变。
我第一次回的帖子实际上在说第三点。我的观点是,即使你用dofile,依然不能完全解决自动重载中遇到的问题。问题是这样的:
local string_gsub = string.gsub
for line in io.lines() do
string_gsub(line, ....)
end
这样的代码,函数是缓存的……
这样基本上你就完蛋了。
那么,能支持动态重载的模块,你必须保证,它的使用者,完全不会因为各种原因缓存模块里面的函数。因为Lua函数本身的灵活性,所以数据是无所谓的。
但是,如果数据格式上不兼容,为了不报错,恐怕数据重载也是必须的——这一点纯函数式的确是优势,但是恐怕也不明显。
dll的模块绝对不能用这种方式重载,一来是dll本身在注册表里面会留一个存根(用于退出的时候垃圾回收),这个存根得去掉,但是Lua没留办法,这倒不是说退出的时候会崩溃,这是说你根本无法改变这个dll——因为它会被Windows锁住。具体的方案得仔细研究Lua源代码才能得出,反正这不是很容易的事情。退一万步说,就算dll可以被重载,万一其userdat的格式不一样,那崩溃几乎是唯一结果了。
但是,就算只有这一点,保证也不是容易的:你如何保证,你的模块所有的使用者,都不会缓存这个模块呢?
最简单的办法,可能就是仅动态重载某些特定的模块了——我们以前的活动模块,导出函数只有OnDraw, OnInput等等几个,而且这些函数绝对不会被缓存(最初由同学设计的驱动循环是将这些函数逐一缓存的………………我@#¥%#%……@#……后来改过来了……)
通用的动态重载,在Lua里面是不可能的(或者至少是要靠运气的)。 |
|