要在lua中实现特定于域的语言,
我想在语言中添加裸字。
以便
print("foo")
可以写成print(foo)
我这样做的方法是改变环境表_G
的元表。
mt = {__index = function(tbl,key) return key end}
setmetatable(_G, mt)
这很有效,因为检索变量foo
的值是由_G.foo
完成的,相当于_G["foo"]
这是一个好方法吗?
有隐藏的缺点吗?
有没有更好的办法?
我可以这样做,以便只能在某个文件中使用裸字吗?
(也许通过执行该文件,使用loadstring
)
答案 0 :(得分:4)
只要有人声明一个与您的“关键字”名称相同的本地,它就会影响您的“关键字/全局变量”,并且您的机制将失败:
print(foo) -- does what you think
local foo = 2
print(foo) -- argh!
并注意您无法阻止脚本中局部变量的定义。
修改(回复评论)。
您使用的是定制的Lua引擎吗?您无法阻止进入本地范围,因为您始终在本地范围内。完全相反:从技术上讲,Lua中没有全局 范围 (例如,与C中的含义相同)。相反,有一个全局命名空间(以表格形式实现)。访问全局变量的机制在Lua 5.1(函数环境)和Lua 5.2(隐式_ENV
前缀)之间有所不同,但概念几乎相同。
特别是,当加载Lua脚本时,无论是由解释器,还是load
,loadstring
,dofile
等,它都被解释为匿名的主体函数(闭包),通常称为“主要块”。因此总有一个局部范围。在标准Lua中,当解析器在正在加载的脚本中遇到local
语句时,您无法阻止定义局部变量。