从字符串动态创建Lua模块

从字符串动态创建Lua模块,lua,Lua,我的处境如下(请不要怀疑我的动机): 我有一个Lua脚本foo.Lua,它需要一些模块bar,即: -- foo.lua require 'bar' -- more code 但是,应该没有实现此模块的bar.lua文件。相反,我想做的是从另一个脚本main.lua执行foo.lua,该脚本还应该从字符串(字符串的来源不重要)动态创建模块bar,即: 这可能吗?我认为最好的方法是使用包。预加载 在给定模块名称的情况下分配模块解析程序函数: localmybar={message=“来自BAR

我的处境如下(请不要怀疑我的动机):

我有一个Lua脚本
foo.Lua
,它需要一些模块
bar
,即:

-- foo.lua
require 'bar'

-- more code
但是,应该没有实现此模块的
bar.lua
文件。相反,我想做的是从另一个脚本
main.lua
执行
foo.lua
,该脚本还应该从字符串(字符串的来源不重要)动态创建模块
bar
,即:


这可能吗?

我认为最好的方法是使用
包。预加载
在给定模块名称的情况下分配模块解析程序函数:

localmybar={message=“来自BAR的你好!”}
package.preload['bar']=函数(…)
返回myBar
结束
您也可以直接在
包中设置模块。加载
,这样可以
下次调用require()时,您将覆盖已加载的模块:

localmybar={message=“来自BAR的你好!”}
本地myBar2={message=“我已更改!”}
--使用“package.loaded”表示我们已经加载了它
package.loaded['bar']=myBar
打印(需要('bar')。消息)
package.loaded['bar']=myBar2
打印(需要('bar')。消息)
如果需要更具动态性,您可以随时覆盖require函数:

localmybar={
message=“酒吧里的你好!”
}
本地oldRequire=require
函数要求(名称)
如果name==“bar”,则返回myBar end
返回oldRequire(名称)
结束
本地条=要求(“条”)
打印(“栏上写着:”.Bar.message.“”)

你可以查一下
package.searchers
看起来很适合作为通用加载程序,但我似乎无法将其修改为包含我自己的加载程序。

我在ingame Lua控制台中执行类似的操作来加载函数。目标是,所需的Lua文件只保存字符串并返回它。像这个

return {
cmd=[[return function(cm) cm=io.popen(cm, 'r') cm=cm:read('a+') return cm end]]
}
然后你可以做一个

love.code=require('more_functions')
love.cmd=load(love.code.cmd)()
在我的require中,还有一个安装代码,可以将所有这些都带到正确的位置。在我的例子中,我用定义的函数设置了一个元表,整个函数看起来像

-- Name: koys.lua
return {
cat=[[return function(cat) for line in io.lines(cat) do io.write(string.format('%s\n',line)) end end]],
free=[[return function() local a=(collectgarbage('count')*1024) print('Before:',a,'Byte') collectgarbage() print('After:',(collectgarbage('count')*1024),'Byte') a=a-collectgarbage('count')*1024 print('Freed:',a,'Byte') return a end]],
gauss=[[return function(gauss) return ((gauss*gauss+gauss)/2) end]],
shell=[[return function(shell) if (type(shell)=='string') then os.execute(shell) else os.execute('/bin/bash') end end]],
cmd=[[return function(cm) cm=io.popen(cm, 'r') cm=cm:read('a+') return cm end]],
len=[[return function(len) local incr=0 for _ in pairs(len) do incr=incr+1 end return incr end]],
dump=[[return function(dump) for key,value in pairs(dump) do io.write(string.format("%s=%s=%s\n",key,type(value),value)) end end]],
help=[[return function(help) love.dump(getmetatable(help).__index) end]],
printf=[[return function(prf,...) io.write(prf:format(...)) end]],
bl=[[return function(r,g,b,a) love.rrand=function() return r end love.grand=function() return g end love.brand=function() return b end love.arand=function() return a end end]],
install=[[getmetatable(love).__index.cmd=load(package.loaded.koys.cmd)()
getmetatable(love).__index.cat=load(package.loaded.koys.cat)()
getmetatable(love).__index.dump=load(package.loaded.koys.dump)()
getmetatable(love).__index.free=load(package.loaded.koys.free)()
getmetatable(love).__index.len=load(package.loaded.koys.len)()
getmetatable(love).__index.gauss=load(package.loaded.koys.gauss)()
getmetatable(love).__index.shell=load(package.loaded.koys.shell)()
getmetatable(love).__index.printf=load(package.loaded.koys.printf)()
getmetatable(love).__index.help=load(package.loaded.koys.help)()
getmetatable(love).__index.bl=load(package.loaded.koys.bl)()
getmetatable(love).__index.info=debug.getinfo
getmetatable(love).__index.cmd=load(package.loaded.koys.cmd)()
getmetatable(love).__index.concat=table.concat
getmetatable(love).__index.remove=table.remove
getmetatable(love).__index.unpack=table.unpack
getmetatable(love).__index.insert=table.insert
getmetatable(love).__index.sort=table.sort
getmetatable(love).__index.move=table.move
getmetatable(love).__index.pack=table.pack]]
}
…而且只做

love.code=require('koys') -- This is a table with text elements that holding Lua code
setmetatable(love,{__index={}}) -- ...that will expand love...
load(love.code.install)() -- ...with metamethods.
之后,表爱将显示内容与

love:dump()
或者元表的内容与

love:help()
截图

这看起来像是一个循环依赖,这通常是不可能的
main.lua
需要
foo.lua
(在
dofile
调用中),而
foo.lua
需要
main.lua
(创建
bar
)。在调用
dofile
package.preload.bar=loadstring(bar_str)(
可能加/减一对括号之前,您可以使用
main.lua
创建
bar.lua
文件。@EgorSkriptunoff:我想这正是我想要的,谢谢。
love:help()