向Lua添加裸文

为了实现Lua内的特定领域语言, 我想要向该语言添加裸单词。 这样, print("foo")可以写成print(foo)

我所做的方式是改变环境表_G的元表。

mt = {__index = function(tbl,key) return key end}
setmetatable(_G, mt)

这有效,因为通过_G.foo检索变量foo的值相当于_G["foo"]

这是一个好的方法吗? 有隐藏的缺点吗? 有更好的方法吗? 能否使裸单词仅在某个文件内起作用? (也许是通过从另一个Lua脚本使用loadstring来执行该文件)

点赞
用户2633423
用户2633423

只要有人声明一个与你的“关键字”同名的本地变量,它就会遮盖住你的“关键字/全局变量”,导致你的机制失败:

print(foo)   -- 做你想的那样
local foo = 2
print(foo)   -- 唉!

请注意,你无法阻止脚本中定义本地变量。

编辑:(回应评论)

你在使用自定义的 Lua 引擎吗?你无法阻止 _进入本地作用域_,因为你总是在本地作用域内。事实上,情况恰恰相反:在 Lua 中,不存在与 C 等语言中全局范围相同的全局 作用域 的概念。相反,Lua 中实现了一个全局 命名空间(由一个表实现)。访问全局变量的机制在 Lua 5.1(使用函数环境)和 Lua 5.2(使用隐式 _ENV 前缀)之间有所不同,但其概念几乎相同。

特别地,当 Lua 脚本被加载时,无论是由解释器还是由 loadloadstringdofile 等方式加载,它都被解释为一个匿名函数(闭包)的主体。因此,总会有一个本地作用域。在标准 Lua 中,当解析器在正在加载的脚本中遇到 local 语句时,你无法阻止其定义一个本地变量。

2013-09-06 08:21:44