Take a look at this code:
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
I'm having trouble understanding what it does. It's from the awesome-wm
project. These are the things I'm having trouble understanding:
client = client
in the declaration of capi
setmetatable
stuff inside do-end
client = client
in the declaration ofcapi
This is defining what portion of the capi is available in this file's scope, If you look at the client.lua file you will see that the capi
defined in it has client, mouse, screen, and awesome.
For each item defined in the capi
table there is a corresponding .c file. These files define objects such as client
. urgent.lua
has visibility of that object, likely it is a global variable, that is how we can set client = client
the second client refers to the global variable.
Here is an example of 2 files:
main.lua
bar = "Hello World!"
local foo = require('foo')
print(foo.bar)
foo.lua
local foo = {
bar = bar
}
return foo
The print function in main.lua will result in Hello World!
setmetatable
stuff insidedo-end
Here by warping the setmetatable
in a do-end block the code is executing in a restricted scope. This is normally done to contain the block's local variables so that they do not persist after the code's execution.
That said that is not the purpose of this block as the block has no local variables. As I see it, the blocking is simply to show that the object being modified is the local variable of client and not the global variable of client.
Additionally the metatable here is used to prevent circular dependency loops, this is mentioned comments in some of the places where similar code appears in the project, such as client.lua
where local screen
is defined.