扩展 lua require 的行为
扩展 lua require 的行为
来源 https://blog.codingnow.com/2015/10/lua_require_env.html
今天同事提了个需求,他希望可以给部分 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 。
local M = {}
function M.test(...)
print(...)
end
return M
local package = package
local debug = debug local function load_env(filename)
local f,err = loadfile(filename)
if f == nil then
return err
end
return function()
return function(env)
if env then
debug.setupvalue(f, , env)
end
return f(filename)
end
end
end local function searcher_env(name)
local filename, err = package.searchpath(name, package.upath)
if filename == nil then
return err
else
return load_env(filename)
end
end table.insert(package.searchers, searcher_env)
require "requirenv"
package.upath = "./?.user.lua"
local myprint = print
local env = {
print = function (...)
myprint("hook", ...)
end
}
local s = require "mymod"(env)
s.test "hello world" -- hook hello world
扩展 lua require 的行为的更多相关文章
- Lua Require函数
转自:http://www.cppblog.com/cslover/archive/2013/12/21/204934.html Lua提供高级的require函数来加载运行库.粗略的说require ...
- ulua 路径小记 以及 lua require 机制整理
ulua 路径小记 在学习ulua时,require模块的根路径可以为项目的Lua文件夹或者ToLua文件夹(Editor下),但是在package.path和package.cpath中并没有看到当 ...
- Lua require 相对路径
lua require 加载方式与我们现在熟知的路径系统不太一样,想要知道lua require 方法的工作原理也很简单 随便写一个错误的require 代码即可: 1 require("l ...
- lua require路径设置实例
1.首先要强调的是,lua require的路径用的是斜杠"/",而不是从Windows文件属性那里复制来的反斜杠"\". 2.通过 print(pagckag ...
- LUA require 搜索路径指定方法
如果是一个 *.LUA 的文件, 里面用到了自己写的库, 或者第三方写的库, 但是你不想把它放到 lua 的安装目录里, 则在代码里面可以指定require搜索的路径. package.path = ...
- Lua require搜索路径指定方法
在自己的lua文件中,如果使用到了自己写的C库或者第三方库,想让lua编译到自己指定的目录下寻找*.lua或*.so文件的时候,可以再自己的Lua代码中添加如下代码,可以指定require搜索的路径. ...
- unity lua require dofile loadfile 区别
oadfile,加载文件,编译文件,并且返回一个函数,不运行 dofile其实就是包装了Loadfile,根据loadfile的返回函数运行一遍 require加载文件的时候,不用带目录,有lua自己 ...
- lua加载函数require和dofile
lua加载函数require和dofile Lua提供高级的require函数来加载运行库.粗略的说require和dofile完成同样的功能但有两点不同: 1. require会搜索目录加载文件; ...
- Lua中的loadfile,dofile,require使用,最后还有调试
1.loadfile---只编译,不运行. loadfile编译代码成中间码并且返回编译后的chunk作为一个函数,而不执行代码:另外loadfile不会抛出错误信息而是返回错误代号. loadstr ...
随机推荐
- Cnblogs关于嵌入js和css的一些黑科技
#pong .spoiler{cursor:none;display:inline-block;line-height:1.5;}sup{cursor:help;color:#3BA03B;} Pon ...
- 翻译 | 使用A-Frame打造WebVR版《我的世界》
原文地址:Minecraft in WebVR with HTML Using A-Frame 原文作者:Kevin Ngo 译者:Felix 校对:阿希 我是 Kevin Ngo,一名就职于 Moz ...
- php数组合并,反转,去重,添加元素等;
//参数默认值//function abc($a,$b,$c = 0){// echo $a,$b,$c;//}//abc(1,3);//结果等于130://echo "<br> ...
- Linux 启动详解之init
1.init初探 init是Linux系统操作中不可缺少的程序之一.init进程,它是一个由内核启动的用户级进程,然后由它来启动后面的任务,包括多用户环境,网络等. 内核会在过去曾使用过init的几个 ...
- 小符号反映大问题,Shell中下划线_与变量的关系。
之前写过一个根据日期和时间自动命名文件名的时候遇到一个问题. #! /bin/bash read -p "please input the filename:" filename ...
- M-移动端的webapp页面布局教程和webapp实战分析
http://www.25xt.com/html5css3/8092.html 响应式设计 1 媒体查询 适用于不同固定宽度设计 媒体类型 : screen 屏幕 print 打印机 handheld ...
- jsp 四大域范围
JSP中四种作用域的不同 作用域规定的是变量的有效期限. 1.如果把变量放到pageContext里,就说明它的作用域是page,它的有效范围只在当前jsp页面里. 从把变量放到pageCont ...
- JS实现数组每次只显示5条数据
var array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]; //循环样式结构function fun(arr,index){ var str = &qu ...
- 图片与字符串(base64编码)的转化
package com.demo; import java.util.*; import java.io.*; import sun.misc.BASE64Decoder; import sun.mi ...
- iOS自动化环境搭建——macaca
macaca-java for ios 自动化环境搭建 基础原理解析:https://testerhome.com/topics/6608 一.环境搭建 1.安装eclipse; -----Java开 ...