来自awesomewm的这段lua代码是做什么的?
请看下面的代码:来自awesomewm的这段lua代码是做什么的?,lua,scope,metaprogramming,declaration,awesome-wm,Lua,Scope,Metaprogramming,Declaration,Awesome Wm,请看下面的代码: local urgent = {} local capi = { client = client, } local client do client = setmetatable({}, { __index = function(_, k) client = require("awful.client") return client[k] end, __newin
local urgent = {}
local capi =
{
client = client,
}
local client
do
client = setmetatable({}, {
__index = function(_, k)
client = require("awful.client")
return client[k]
end,
__newindex = error -- Just to be sure in case anything ever does this
})
end
我很难理解它的作用。它来自于awesomewm
项目。以下是我难以理解的事情:
client=client
在capi
setmetatable
里面的东西do end
client=client
在capi
capi
具有客户端、鼠标、屏幕和屏幕
对于capi
表中定义的每个项目,都有一个相应的.c文件。这些文件定义了对象,例如客户端
emergency.lua
具有该对象的可见性,很可能是一个全局变量,这就是我们如何设置client=client
第二个客户端引用全局变量的方法
以下是两个文件的示例:
梅因·卢阿
bar = "Hello World!"
local foo = require('foo')
print(foo.bar)
福卢阿
local foo = {
bar = bar
}
return foo
main.lua中的打印功能将导致Hello World代码>
setmetatable
里面的东西do end
这里,通过在do end块中扭曲setmetatable
,代码在受限范围内执行。这样做通常是为了包含块的局部变量,以便它们在代码执行后不会持久化
也就是说,这不是该块的目的,因为该块没有局部变量。在我看来,阻塞只是为了表明被修改的对象是客户端的局部变量,而不是客户端的全局变量
此外,这里的元表用于防止循环依赖循环,在项目中出现类似代码的一些地方,如客户端中的注释中提到了这一点。lua
定义了本地屏幕。@Nifim答案非常好。我只想添加更多的上下文,说明为什么这段代码存在于其适当的历史上下文中。在Lua5.2之前,模块系统是不同的。核心Lua库中定义了一个神奇的module()
函数。创建模块时,必须先创建所有全局变量的本地版本,然后才能调用module()
,否则它将在自己的全局环境中运行。“capi”代表“核心API”或“C(语言)API”,具体取决于天气。如果Awesome是今天用我们现在所掌握的所有知识编写的,那么就不会有一个公共的“C语言”API,它们总是隐藏在私有部分以增加灵活性。现在设置“c.my_own_property”可以在capi.client和sorry.client之间进行两次往返,以适应所有遗留约束
现在,metatable魔术是一种称为meta lazy loading的Lua模式。由于紧急
是可怕的.client
的子模块,因此它无法直接导入可怕的.client
,而不会导致循环依赖关系。随着时间的推移,随着awesomeapi的定义越来越明确,进行了越来越多的重构,它们经常引入奇怪的依赖项来保持某种程度的向后兼容性。在最好的情况下,我们会忽略所有用户的配置,只是重新设计整个代码以避免这些循环依赖。然而,每次我们这样做时,上述API的所有用户都会在一天早上醒来,他们无法再登录到自己的计算机。因此,这种解决方法的存在是为了防止此类事件,以换取一些奇怪的代码和维护负担