1
votes

I wrote a function in Lua for Conky to provide a list of top processes to be displayed with a delay of 3 sections (intervals) before refreshing. This requires capturing the refresh data to be stored and displayed on each following interval before the next refresh.

All works well with the code below but I am puzzled that I cannot define global tables t1, t2, t3, and t4 within the function block of conky_top_control(). I've had to create them outside the block but for appearance sake, I wanted to keep table creation inside the function code block. I've tried listing them with no "local" define in front of the tables. And I cannot find the right syntax to use the environmental declaration _G to the table creations either, if that is even correct usage.

So, the question is: how do you define a table inside a function as global? Specifically as it pertains to tables t1, t2, t3, and t4 defined below?

Here is the code in Lua, which is called from Conky ${lua top_control):

function conky_timer(interval)
    return tonumber(conky_parse("${updates}") % interval+1)
end

t1,t2,t3,t4={},{},{},{}
function conky_top_control()
    if conky_timer(3)==1 then   
        for i=1,5 do
        t1[i]=conky_parse('${top name '..i..'}')
        t2[i]=conky_parse('${top pid '..i..'}')
        t3[i]=conky_parse('${top cpu '..i..'}')
        t4[i]=conky_parse('${top mem '..i..'}')
        end
    end
    return conky_parse(t1[1]..'${goto 129}'..t2[1]..'${goto 174}'..t3[1]..'${goto  219}'..t4[1]..'\n'..t1[2]..'${goto 129}'..t2[2]..'${goto 174}'..t3[2]..'${goto 219}'..t4[2]..'\n'..t1[3]..'${goto 129}'..t2[3]..'${goto 174}'..t3[3]..'${goto 219}'..t4[3]..'\n'..t1[4]..'${goto 129}'..t2[4]..'${goto 174}'..t3[4]..'${goto 219}'..t4[4]..'\n'..t1[5]..'${goto 129}'..t2[5]..'${goto 174}'..t3[5]..'${goto 219}'..t4[5])
end
4
All Lua code is compiled as a function so all globals are set "within a function"... This is just to give you the knowledge to figure out that you've arrived at the wrong question for your problem. - Tom Blodget

4 Answers

4
votes

Actually, you don't need globals. In general, they are a poor practice that causes difficult errors in your code and other code.

Try it this way:

local t1,t2,t3,t4={},{},{},{} -- state variables for conky_top_control
function conky_top_control()
    -- use t1,t2,t3,t4
end

Since the locals t1,t2,t3,t4 are in the scope where conky_top_control is defined, they are captured as references. Their values will persist across calls to conky_top_control, which can read and modify them.

Now, appearance considerations give way to a satisfying design.

2
votes

You can move the global variable initialization into the function by just adding a conditional that checks whether the globals were previously initialized.

function conky_top_control()
    if not t1 then
        t1,t2,t3,t4={},{},{},{}
    end
    -- rest of function
end

This way the globals will only be set to blank tables the first call to the function.

1
votes

I am puzzled that I cannot define global tables t1, t2, t3, and t4 within the function block of conky_top_control()

There is no way/need to define global variables. Things stop working when you move the assignment to the function because your variables then get re-assigned every time that function is called.

I cannot find the right syntax to use the environmental declaration _G to the table creations either, if that is even correct usage.

You can use _G.t1 syntax to reference t1 table from the (global) environment. See this reference for details.

0
votes

In Lua every variable is global unless it is declared local.

If you get errors defining global variables inside a function then perhaps Conky has set up some restrictions.