« 推荐款老游戏:维多利亚 II | 返回首页 | 终于升级了 linode 上的 ubuntu »

扩展 lua require 的行为

今天同事提了个需求,他希望可以给部分 lua 代码(由策划编写)做一个沙盒关起来。在 lua 里做沙盒很容易,只需要控制函数的环境就可以了。不过另一个附加需求是,这些代码还可以直接利用 require 加载。

而我们又不想去修改系统的 api 接口,那么怎么做到这点呢?

首先, 我希望使用的时候看起来像这样:

local xxx = require "xxx" (myEnv)

和传统的 require 用法不同,可以在后面追加一个参数 myEnv 。这样的话,每次 xxx 模块被 require 时,它其实被重复运行一次,但会绑定不同的 _ENV

其次,既然模块会被反复初始化,那么我们甚至还可以约定,每个这种沙盒封装的模块还可以接收 require 的传入的额外参数。

做到这点很容易,我们只需要在 package.searchers 里追加一个自定义的 loader 然后并不返回加载的模块 chunk ,而是做一个函数封装。将 chunk 的运行推迟到传入 myEnv 调用之后。

这样,load chunk 本身还是依靠 require 的 package 机制缓存代码的,只是每次调用后,重新绑定 _ENV 生成了一组新实例。

我在 gist 上贴了一组代码实现这个特性:延迟绑定环境的 require

Comments

请赐教下: lua中require一个so格式的C模块,用完后我想释放掉这个so模块,有没有什么办法?现在是一直占用,不能Free掉。 看了下lua的代码,是存在 CLIBS 的注册表里. 如果我的so需要升级,然后重新加载,难道需要 lua_close 下虚拟机?
酷。这个我可以参考一下,用在我们的项目里,哈哈:)

Post a comment

非这个主题相关的留言请到:留言本