Skip to content

Using Lua scripts (Part 10): Table parameters

lasers edited this page Jan 5, 2019 · 4 revisions

x: Table parameters

Tables in Lua are extremely useful and versatile, so im going to focus on using them to send information.

We have a bar meter drawing function separate to our main function and i have been through a few methods of getting the information the function needs from the main function via the curved brackets () in the function call to the function itself.

i have so far shown how we can do this by sending strings

--call function domsomething in main and send info dosomething(1,0,0,1,"mono",12)

--dosomething receives info and sets it to strings function dosomething(red,green,blue,alpha,font,foontsize)

this is a nice straightforward way of passing the information BUT it has some drawbacks

you have to send EVERYTHING the function needs EVERY time you call the function if you don't send it everything and miss something out, or put it in the wrong order then you will get unexpected behavior from the function as it sets its strings to the wrong values or, more likely, you will get a nil error.

We can set tables to get around this this way does requires some extra work initially but once set up, you have the ability to, for example, specify default values for strings in advance and then only send the function the required information.

Say you wanted 5 bar indicators you want them all to have gray backgrounds you want them all to be the same height and width you want the indicator to be green from 0 to 45, then yellow up to 75 and then red

the only thing that will be different between each bar will be the value it displays and the x,y coordinates so. possibly we want our bars all to line up in a row, so we may only need to change the x while keeping y the same

so to cut down on typing and save time all we want to send to the function is the value to display and the x coordinate of the meter

when function become complicated, the list of things the function needs to operate can become very large. In addition, the script may allow you to do several different things (eg draw a square or a circle) so you would only want to send the information that the specific part of the script (if you want to draw a circle you don't want to have to specify settings for a square that you wont use!)

Using Tables

There are different kinds of tables.... indexed tables, "dictionary" tables and mixed tables (which have both))

for this use of sending information we will be using a "dictionary" tables which usually take this general form"

name of table
=
open the table with curly brackets {
enter data separated by commas
close the table with }

table={red=1,green=0,blue=0,alpha=1,font="mono",fontsize=12}

as i mentioned before once you have your table open table={ you can space out and use multiple lines to enter the data on and allow for the use of comments... as long as you use commas in the right place!

table={--set table and open
red=1,
green=0,
blue=0,
alpha=1,--alpha of 0 = full transparent, 1=full opaque
font="mono",
fontsize=12,
}--closes table

NOTE - it isn't a good idea to call a table "table" just as it is a bad idea to call a string "string" just as with strings, give your tables unique names with the table name giving some information about what that table contains.

now when we want to send info to our "dosomething" function we can do this i'll be using a better name for the table below

--setup function domsomething in main and call function
dosettings={--set table and open
red=1,
green=0,
blue=0,
alpha=1,--alpha of 0 = full transparent, 1=full opaque
font="mono",
fontsize=12,
}--closes table
dosomething(dosettings)

------------------------------------------------------------------------------

--dosomething receives the table, and puts the info into another table
function dosomething(settings)

NOTE the name of the table you put your settings into (dosettings in the above) and the table name you set for the function itself to use (settings in the above example) don't have to be the same

function "dosomething" just puts the info inside table "dosettings" and puts it into table "settings" in the same order

NOW WE HAVE TO GET THE INFO OUT this is where the extra work comes in :)

when sending the strings, the strings were immediately available to the function when sending tables we need to get the info out and into strings

this will all happen in the "dosomething" function

in the function we have a table called "settings" that contains the info we need because: function dosomething(settings) there are several ways we can get the info out of a dictionary type table

  • using a period this method takes the form tablename.stringname

we know our tablename, "settings" and when we look at what was set in the table, we see that we were setting strings

dosettings={--set table and open
red=1,
green=0,
blue=0,
alpha=1,--alpha of 0 = full transparent, 1=full opaque
font="mono",
fontsize=12,
}--closes table

so red,green,blue,alpha,font and fontsize are the names of the strings within the table

so, we want to get our color values out of the table and into strings... we would do the following:

redvalue=settings.red
greenvalue=settings.green
bluevalue=settings.blue
alphavalue=settings.alpha

NOW: string "redvalue" has a value of 1 string "greenvalue" has a value of 0 string "bluevalue" has a value of 0 string "alphavalue" has a value of 1

and we can use these string in the function like so: cairo_set_source_rgba (cr,redvalue,greenvalue,bluevalue,alphavalue)

BUT we said earlier that we didnt want to have to send "dosomething" colorvalues every time we want to use the function.

when we call the function we only want to specify the font and fontsize

--in main function call dosomething
dosettings={--open
fontsize=12,
font="Sans",
}--close

NOTE - with dictionary type tables, the order in which you enter your data doesn't matter

HOWEVER "dosomething" still needs color and alpha values if we have the line inside "dosomething"

redvalue=settings.red redvalue will be nil and we will get an error when we try and use it to set the color

Conky: llua_do_call: function conky_test execution failed: /home/benjamin/lua/codetest.lua:11: error in function 'cairo_set_source_rgba'.
     argument #2 is 'nil'; 'number' expected.

this error message pops up in the terminal ALWAYS RUN CONKY FROM TERMINAL WHEN TESTING! :D

its quite helpful... it tells us the name of the file that is causing the problem, it tells us the line number in that file where the error occurs and it tells us where in that line the error is

here is my code, lines 10 and 11

red=nil
cairo_set_source_rgba (cr,red,1,1,1)

and we can see the error on line 11, the second data position within the set source brackets ()

WE NEED TO CATCH THE NIL BEFORE ITS USED the error occurred on line 11 (when we tried to use the string) not on line 10 (where the string was set to nill)

we can catch nil values using IF statements

redvalue=settings.red
if redvalue==nil then
redvalue=1
end

you will usually find these short statements written on a single like like so

redvalue=settings.red
if redvalue==nil then redvalue=1 end

so the above is where our default settings come into play if, when calling "dosomething" you don't want to specify color values instead you want to default to white

if you dont set "red" in the function call in the main function then in "dosomething" settings.red will be nill and so redvalue will be nil. If redvalue is nil then the IF evaluation "if redvalue==nil then" is passed and the code inside the If is executed, setting redvalue to 1.

To expand that idea a bit we could set up default settings in the main script then use them in the function

function conky_main
--setup lines
--set default values for color, alpha, font and fontsize
default_red=1
default_green=1
default_blue=1
default_alpha=1
default_font="mono"
default_fontsize=12

--setup and call dosomething function
dosettings={
fontsize=14
}
domseomthing(dosettings)
--closeout lines
end-- of main function

-------------------------------------------------------------------------

function dosomething(settings)
redvalue=settings.red
if redvalue==nil then redvalue=default_red end

greenvalue=settings.green
if greenvalue==nil then greenvalue=default_green end

bluevalue=settings.blue
if bluevalue==nil then bluevalue=default_blue end

alphavalue=settings.alpha
if alphavalue==nil then alphavalue=defualt_alpha end

fontvalue=settings.font
if fontvalue==nil then fontvalue=default_font end

fontsizevalue=settings.fontsize
if fontsizevalue==nil then fontsizevalue=default_fontsize end

--use strings to do something
end--of dosomething function

if we want the default we simply dont send the value in the function call

if we want something other than the default then we need to set it in the call, if we set fontsize=14 then when we look at the relevant lines in dosomething:

fontsizevalue=settings.fontsize
if fontsizevalue==nil then fontsizevalue=default_fontsize end

settings.fontsize is not equal to nil, it is equal to 14 the IF evaluation is not passed and the code inside the IF is not executed so when we use fontsizevalue in the function it retains its value of 14.

Clone this wiki locally