Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
来自awesomewm的这段lua代码是做什么的?_Lua_Scope_Metaprogramming_Declaration_Awesome Wm - Fatal编程技术网

来自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的哪些部分在此文件范围内可用,如果查看client.lua文件,您将看到其中定义的
    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的所有用户都会在一天早上醒来,他们无法再登录到自己的计算机。因此,这种解决方法的存在是为了防止此类事件,以换取一些奇怪的代码和维护负担