How do I cycle through random fonts in Conky via LUA? - lua

This question here seems to tangentially touch upon it but I cannot get it to work. Here is my LUA file:
function conky_myeval()
local myTable = { " Old London :normal:size=7", "Ethnocentric :normal:size=7"}
var1 = myTable[ math.random( #myTable)]
return var1
end
and the related conky part:
${font ${lua conky_myeval}} Hello World!
Thank you for any assistance and I apologize if this has been asked before; The most similar I found I posted above.

I've found it easier to have a lua script pass conky a string that can be parsed by a lua_parse object that then generates the intended object rather than trying to pass a value to the intended object.
In the case of random fonts, I'd do something like the following, which worked when tested.
Lua file:
function conky_myfont()
local myTable = {"DejaVu Serif:normal:size=12", "MuseJazz Text:normal:size=12"}
var1 = myTable[ math.random( #myTable)]
return "${font "..var1.."}"
end
Conky part:
${lua_parse conky_myfont}Hello World!${font}

Related

How to get the value from SPOP safely and test for value or null

I am currently doing 2 steps in my code and I just realized I can combine both steps in a LUA script.
I am doing:
SPOP on my set
calling a lua script to do other things.
The value from step#1 is being passed and stored in the local variable ele.
My lua script looks like:
local ele = KEYS[1]
local p = KEYS[2]
local u = KEYS[3]
if redis.call("SISMEMBER", u, ele) == 0 then
..
..
return "OK"
else
return "EXISTS"
end
How can I call SPOP from inside my lua script and store it in a variable.
I need to do:
local popped = redis.call("SPOP", "my-set-here")
I'm not sure if that will work, but then I have to check if it is null or has a value I guess. Just want to make sure I am following best practise.
BTW, as a side note, what is the fastest way to create and test lua scripts?
You can check the value of popped for non-nillness with something like:
if popped then
-- do something
end
As for developing Redis Lua scripts, have a look at Zerobrane's integration:
http://notebook.kulchenko.com/zerobrane/redis-lua-debugging-with-zerobrane-studio
https://redislabs.com/blog/zerobrane-studio-plugin-for-redis-lua-scripts/
Disclosure: I was involved in the integration effort ;)

Adding labels to my programming language

Actually I am writting a programming language in Lua. It was quite fun. I've wrote a bit of standard library (stack op and simple io). Then I've thought about labels. It would look like in assembly. While and for loop aren't funny in any bit so programming in that language can be quite challenging. Here are some requirements for this system:
Label stack (or array, dictionary) must be accessible from global context.
Jump instruction handler will be in separate file.
This is how my label-handling function look like:
function handleLabel(name,currentLine)
end
I have no idea how to implement this kind of magic. First I've thought about that:
LabelLineIDS = {}
Labels = {}
Labelamount = 1;
function handleLabel(name,currentLine)
LabelLineIDS[Labelamount]=currentline
Labels[Labelamount]=name
Labelamount=Labelamount+1
end
-- In file "jump.lua":
local function has_value (tab, val)
for index, value in ipairs(tab) do
if value == val then
return index
end
end
print ("Error: Label not defined.") -- Bail out.
os.exit(1)
end
local function _onlabel()
local labelName = globalparams --Globalparams variable contain parameters to each function, at the moment
--this will contain label name. It _can_ be nil.
return LabelLineIDS[has_value(Labels, labelName)]
end
CurrLine = _onlabel() --Currline - current line that get's parsed.
--1 command per one line.
But I'm unsure is this well written or even work. Can you give me idea how to parse labels in my programming language (and write jump functions)? Or if my code is pretty ok at the moment, can you help me to improve it?
Using line counter in my parser I've decided to implement gotos like we can see in BASIC. Thanks everyone for help.

Metamethod lookup through __index?

I've implemented my own class system and I'm having trouble with __tostring; I suspect a similar issue can happen with other metamethods, but I haven't tried.
(Brief detour: each class has a __classDict attribute, holding all methods. It is used as the class instances' __index. At the same time, the __classDict's __index is the superclass' __classDict, so methods in superclasses are authomatically looked up.)
I wanted to have a "default tostring" behavior in all instances. But it didn't work: the "tostring" behavior doesn't "propagate" through subclasses correctly.
I've done this test exemplifying my issue:
mt1 = {__tostring=function(x) return x.name or "no name" end }
mt2 = {}
setmetatable(mt2, {__index=mt1})
x = {name='x'}
y = {name='y'}
setmetatable(x, mt1)
setmetatable(y, mt2)
print(x) -- prints "x"
print(mt2.__tostring(y)) -- prints "y"
print(y) -- prints "table: 0x9e84c18" !!
I'd rather have that last line print "y".
Lua's "to_String" behaviour must be using the equivalent of
rawget(instance.class.__classDict, '__tostring')
instead of doing the equivalent of
instance.class.__classDict.__tostring
I suspect the same happens with all metamethods; rawget-equivalent operations are used.
I guess one thing I could do is copying all the metamethods when I do my subclassing (the equivalent on the above example would be doing mt2.__tostring = mt1.__tostring) but that is kind of inelegant.
Has anyone fought with this kind of issue? What where your solutions?
I suspect the same happens with all metamethods; rawget-equivalent operations are used.
That is correct.
from the lua manual:
... should be read as rawget(getmetatable(obj) or {}, event). That is, the access to a metamethod does not invoke other metamethods, and the access to objects with no metatables does not fail (it simply results in nil).
Generally each class has its own metatable, and you copy all references to functions into it.
That is, do mt2.__tostring = mt1.__tosting
Thanks to daurnimator's comments, I think I found a way to make metamethods "follow" __index as I want them to. It's condensed on this function:
local metamethods = {
'__add', '__sub', '__mul', '__div', '__mod', '__pow', '__unm', '__concat',
'__len', '__eq', '__lt', '__le', '__call', '__gc', '__tostring', '__newindex'
}
function setindirectmetatable(t, mt)
for _,m in ipairs(metamethods) do
rawset(mt, m, rawget(mt,m) or function(...)
local supermt = getmetatable(mt) or {}
local index = supermt.__index
if(type(index)=='function') then return index(t,m)(...) end
if(type(index)=='table') then return index[m](...) end
return nil
end)
end
return setmetatable(t, mt)
end
I hope it is straightforward enough. When a new metatable is set, it initializes it with all metamethods (without replacing existing ones). These metamethods are prepared to "pass on" requests to "parent metatables".
This is the simplest solution I could find. Well, I actually found a solution that used less characters and was a bit faster, but it involved black magic (it involved metatable functions de-referencing themselves inside their own bodies) and it was much less readable than this one.
If anyone finds a shorter, simpler function that does the same, I'll gladly give him the answer.
Usage is simple: replace setmetatable by setindirectmetatable when you want it to "go up":
mt1 = {__tostring=function(x) return x.name or "no name" end }
mt2 = {}
setmetatable(mt2, {__index=mt1})
x = {name='x'}
y = {name='y'}
setmetatable(x, mt1)
setindirectmetatable(y, mt2) -- only change in code
print(x) -- prints "x"
print(mt2.__tostring(y)) -- prints "y"
print(y) -- prints "y"
A little word of warning: setindirectmetatable creates metamethods on mt2. Changing that behavior so a copy is made, and mt2 remains unaltered, should be trivial. But letting them set up by default is actually better for my purposes.
From my experience with Lua 5.1, metamethods are looked up in metatables using rawget(), and that's why you must copy the reference to the function into every class table you create.
See the Inheritance Tutorial on the Lua Users Wiki.

lua - get the list of parameter names of a function, from outside the function

I'm generating some (non-html) documentation for a Lua library that I developed. I will generate the documentation by hand, but I'd appreciate some kind of automation if possible (i.e. generating skeletons for each function so I can fill them in)
I'd like to know if there's a way for lua to know the names of the parameters that a function takes, from outside it.
For example, is there a way to do this in Lua?
function foo(x,y)
... -- any code here
end
print( something ... foo ... something)
-- expected output: "x", "y"
Thanks a lot.
ok,here is the core code:
function getArgs(fun)
local args = {}
local hook = debug.gethook()
local argHook = function( ... )
local info = debug.getinfo(3)
if 'pcall' ~= info.name then return end
for i = 1, math.huge do
local name, value = debug.getlocal(2, i)
if '(*temporary)' == name then
debug.sethook(hook)
error('')
return
end
table.insert(args,name)
end
end
debug.sethook(argHook, "c")
pcall(fun)
return args
end
and you can use like this:
print(getArgs(fun))
Try my bytecode inspector library. In Lua 5.2 you'll be able to use debug.getlocal.
Take a look at debug.getinfo, but you probably need a parser for this task. I don't know of any way to fetch the parameters of a function from within Lua without actually running the function and inspecting its environment table (see debug.debug and debug.getlocal).
function GetArgs(func)
local args = {}
for i = 1, debug.getinfo(func).nparams, 1 do
table.insert(args, debug.getlocal(func, i));
end
return args;
end
function a(bc, de, fg)
end
for k, v in pairs(GetArgs(a)) do
print(k, v)
end
will print
1 bc
2 de
3 fg
Basically we use debug.getinfo to retrieve the nparams attribute (which gives us the information of how many parameters the function takes) and debug.getlocal to access the name of the parameters.
Tested and working with Lua 5.4
Take a look at the luadoc utility. It is sort of like Doxygen, but for Lua. It is intended to allow the documentation to be written in-line with the source code, but it could certainly be used to produce a template of the documentation structure to be fleshed out separately. Of course, the template mechanism will leave you with a maintenance issue down the road...

What's with PCALL or is Wowwiki wrong?

This is a WoW (World of Warcraft) lua script question. Not many of these get asked here but I have no where to turn and Stackoverflow is the programmer oasis for answers.
Question:
Wowwiki states that the 2nd, 3rd, 4th arguments are your calling functions 1st, 2nd, 3rd arguments. I don't find this to be true. I find that the 3rd, 4th, 5th arguments end up being the 1st, 2nd, 3rd arguments.
Link: http://www.wowwiki.com/API_pcall
Function:
function myTest(arg1)
return arg1 .. 10;
end
Problem:
local retOK, ret1 = pcall(myTest,"string value");
when I try the sample I get an error of "trying to perform concatenate on local 'arg1' (a nil value)". If I change the code to:
local retOK, ret1 = pcall(myTest,"string value", "bob");
then I get the output of "bob10". Where does the 2nd argument go and what is it for?
More Testing:
function BobsToolbox:RunTest()
local test1, value1 = pcall(BobsToolbox.Test1, "string value");
SharpDeck:Print("Test1: " .. tostring(test1) .. " Value: " .. tostring(value1));
end
function BobsToolbox:Test1(arg1)
return arg1 .. "10";
end
Results: attempt to concatenate local 'arg1' (a nil value)
function BobsToolbox:RunTest()
local test1, value1 = pcall(Test1, "string value");
SharpDeck:Print("Test1: " .. tostring(test1) .. " Value: " .. tostring(value1));
end
function Test1(arg1)
return arg1 .. "10";
end
Results: string value10
I am new to lua and I can't understand why these are different.
New Question:
The following code works but why?
function BobsToolbox:RunTest()
local test1, value1 = pcall(BobsToolbox.Test1, "string value");
SharpDeck:Print("Test1: " .. tostring(test1) .. " Value: " .. tostring(value1));
end
function BobsToolbox.Test1(arg1)
return arg1 .. "10";
end
What's the difference between the following: ("." vs ":")
function BobsToolbox.Test1(arg1)
function BobsToolbox:Test1(arg1)
Lua Documentation:
http://www.lua.org/pil/16.html
This use of a self parameter is a central point in any object-oriented language. Most OO languages have this mechanism partially hidden from the programmer, so that she does not have to declare this parameter (although she still can use the word self or this inside a method). Lua can also hide this parameter, using the colon operator. We can rewrite the previous method definition as
function Account:withdraw (v)
self.balance = self.balance - v
end
and the method call as
a:withdraw(100.00)
The effect of the colon is to add an extra hidden parameter in a method definition and to add an extra argument in a method call. The colon is only a syntactic facility, although a convenient one; there is nothing really new here. We can define a function with the dot syntax and call it with the colon syntax, or vice-versa, as long as we handle the extra parameter correctly:
Account = { balance=0,
withdraw = function (self, v)
self.balance = self.balance - v
end
}
function Account:deposit (v)
self.balance = self.balance + v
end
Account.deposit(Account, 200.00)
Account:withdraw(100.00)
Possible Conclusion:
With this in mind I assume that when calling a ":" function using "pcall" you must supply the "self" argument.
Related: There are nice live code editors for WoW. I used to use LuaSlinger, but turns out that's no longer developed and the developer recommends Hack instead.
However, what you might be encountering here is that the colon method-call syntax is just syntax sugar, ditto for method definitions, IIRC. Basically, if you do foo:bar("quux!"), where foo is an object, you are in reality just doing foo.bar(foo, "quux!").
Hope that helps!
Well, I don't think WoWWiki is wrong. Here is the code I am using:
function myTest(arg1) return arg1 .. 10; end
local retOK, ret1 = pcall(myTest,"string value");
DEFAULT_CHAT_FRAME:AddMessage(ret1);
local retOK, ret1 = pcall(myTest,"string value", "bob");
DEFAULT_CHAT_FRAME:AddMessage(ret1);
Here is the output I get in my General chat box:
string value10
string value10
How are you trying your sample code? I just pasted my code into an existing mod lua file and made sure that mod was enabled in the addons window before selecting my character and logging in. I made a few changes to the source lua file and typed:
/console reloadui
To try the new changes and have the results output to my screen. I don't have much advice to offer you, because I haven't done much work with WoW addons. Have you tried this code in a blank addon to make sure nothing else is interfering? Have you actually tried the code in game? If you can provide any more information or want me to try anything else, let me know!
Update: Decided to try a few more tests. Here are the tests (with the same function):
local retOK, ret1 = pcall(myTest,"");
DEFAULT_CHAT_FRAME:AddMessage(ret1);
local retOK, ret1 = pcall(myTest, nil, "bob");
DEFAULT_CHAT_FRAME:AddMessage(ret1);
And the results:
10
attempt to concatenate local 'arg1' (a nil value)
It's interesting that the error I see when arg1 is nil is slightly different than the error you see. I'd be interested in knowing how you are testing your code. Or maybe you didn't copy the error down verbatim? I guess you could also try clearing out your WTF folder and disabling the rest of your addons to test this function. If it makes a difference, then you can enable them one a time until you find the problem.

Resources