Lua script wont accept args - lua

I was trying to get an hologram projector working, but in run into these errors:
bad arguments #3 (number expected, got no value)
My script is:
local component = require("component")
local hologram = component.hologram
function setVoxel(x, y, z, value)
print(x)
print(y)
print(z)
print(value)
local current = hologram.get(x, z)
local positiveMask = bit32.lshift(1, y - 1)
if value then
hologram.set(x, z, bit32.bor(current, positiveMask))
else
local negativeMask = bit32.bnot(positiveMask)
hologram.set(x, z, bit32.band(current, negativeMask))
end
end
local args = {...}
print(args[1])
print(args[2])
print(args[3])
print(args[4])
setVoxel(tonumber(args[1]), tonumber(args[2]), tonumber(args[3]), args[4])
I used:
holo-set 8 16 20 true
The print commands returned:
8
16
20
true
but its not working.
I have checked the spelling.
Also the hologram is correctly initialized.

That error means some function (what's the rest of the error?) which expected to get three arguments only got two.
Given that code snippet the only function I can see to which that might apply is hologram.get.
Which, given a quick look at the documentation (thank you Google), does in fact appear to require three arguments.
get(x:number, y:number, z:number):number
Returns the value at the specified position.

Related

Functions in lua tables

I have
someTabe = {}
someTabe.foo = function (x,y)
return x + y
end
How can I get pint(function"(function (x,y) return x + y end)??? Not return result.
You cannot recover the source code of a function from inside Lua.
> print(someTabe.foo)
function: 0x7fed0bc091f0
This is telling you that someTabe.foo contains a function, which has been converted to internal representation stored at the address shown.
If you need to recover the source code of a function from inside Lua, you need to compile it manually with load and then use the debug library to get the source code.
You could could look for a decompiler online if you are just trying to see the code. However in your own code it is impossible.
You can't get code itself, but you can get bytecode using string.dump():
local f = function(x,y) print('AAA') end)
local bytecode = string.dump(f) -- Get bytecode of function
local f2 = load(f) -- It is copy of f, but (f ~= f2)
f2() -- prints AAA

wrk executing Lua script

My question is that when I run
wrk -d10s -t20 -c20 -s /mnt/c/xxxx/post.lua http://localhost:xxxx/post
the Lua script that is only executed once? It will only put one item into the database at the URL.
-- example HTTP POST script which demonstrates setting the
-- HTTP method, body, and adding a header
math.randomseed(os.time())
number = math.random()
wrk.method = "POST"
wrk.headers["Content-Type"] = "application/json"
wrk.body = '{"name": "' .. tostring(number) .. '", "title":"test","enabled":true,"defaultValue":false}'
Is there a way to make it create the 'number' variable dynamically and keep adding new items into the database until the 'wrk' command has finished its test? Or that it will keep executing the script for the duration of the test creating and inserting new 'number' variables into 'wrk.body' ?
Apologies I have literally only being looking at Lua for a few hours.
Thanks
When you do
number = math.random
you're not setting number to a random number, you're setting it equal to the function math.random. To set the variable to the value returned by the function, that line should read
number = math.random()
You may also need to set a random seed (with the math.randomseed() function and your choice of an appropriately variable argument - system time is common) to avoid math.random() giving the same result each time the script is run. This should be done before the first call to math.random.
As the script is short, system time probably isn't a good choice of seed here (the script runs far quicker than the value from os.time() changes, so running it several times immediately after one another gives the same results each time). Reading a few bytes from /dev/urandom should give better results.
You could also just use /dev/urandom to generate a number directly, rather than feeding it to math.random as a seed. Like in the code below, as taken from this answer. This isn't a secure random number generator, but for your purposes it would be fine.
urand = assert (io.open ('/dev/urandom', 'rb'))
rand = assert (io.open ('/dev/random', 'rb'))
function RNG (b, m, r)
b = b or 4
m = m or 256
r = r or urand
local n, s = 0, r:read (b)
for i = 1, s:len () do
n = m * n + s:byte (i)
end
return n
end

Why is this function to add the contents of a table together in Lua returning nothing

I am stuck trying to make the contese of a table (all integers) add together to form one sum. I am working on a project where the end goal is a percentage. I am putting the various quantities and storing them in one table. I want to then add all of those integers in the table together to get a sum. I haven't been able to find anything in the standard Library, so I have been tyring to use this:
function sum(t)
local sum = 0
for k,v in pairs(t) do
sum = sum + v
end
return sum
However, its not giving me anything after return sum.... Any and all help would be greatly appreciated.
A more generic solution to this problem of reducing the contents of a table (in this case by summing the elements) is outlined in this answer (warning: no type checking in code sketch).
If your function is not returning at all, it is probably because you are missing an end statement in the function definition.
If your function is returning zero, it is possible that there is a problem with the table you are passing as an argument. In other words, the parameter t may be nil or an empty table. In that case, the function would return zero, the value to which your local sum is initialized.
If you add print (k,v) in the loop for debugging, you can determine whether the function has anything to add. So I would try:
local function sum ( t ) do
print( "t", t ) -- for debugging: should not be nil
local s = 0
for k,v in pairs( t ) do
print(k,v) --for debugging
s = s + v
end
return s
end
local myTestData = { 1, 2, 4, 9 }
print( sum( myTestData) )
The expected output when running this code is
t table: [some index]
1 1
2 2
3 4
4 9
16
Notice that I've changed the variable name inside the function from sum to s. It's preferable not to use the function name sum as the variable holding the sum in the function definition. The local sum in the function overrides the global one, so for example, you couldn't call sum() recursively (i.e. call sum() in the definition of sum()).

Return multiple values to a function, and access them separately in Lua?

If I have a function that returns multiple values, how can I access those values separately? Something like table[i].
angles = function()
x = function()
local value = 0
return value
end
y = function()
local value = 90
return value
end
z = function()
local value = 180
return value
end
return x(), y(), z()
end
A problem arises here when wanting to use, for example, the x value separately, while keeping it in the function angles.
print(????)
Sort of wish functions worked like tables in this respect, so I could type something like print(angles.x)
Also, I know that code seems really redundant, but it's actually a much more simplified version of what I'm actually using. Sorry if it makes less sense that way.
x, y, z= angles()
print (x,y,z)
There's a couple of ways to do this.
Most obvious would be
local x, y, z = angles()
print(x)
If you want the first value specifically
local x = ( angles() )
-- `local x = angles()` would work too. Lua discards excess return values.
print(x)
or, somewhat less readably
print((angles()))
You could also return a table from the function, or use the standard module table to pack the return values into one.
local vals = table.pack(angles())
print(vals[1])
Another way of accessing them individually (as the question wording implies) rather than all at once is this:
print((select(1,angles())))
print((select(2,angles())))
print((select(3,angles())))
Output:
0
90
180
The select() call needs to be in parentheses in order to return individual entries rather than all after the given offset.

How can I tell when ANY variable is set to a given value in Lua?

If a local variable in some unknown scope gets set to 256, how can I know that it happened?
I'd like to be able to look for one value at a time, assuming that's possible.
I have access to the debug API.
You can loop over all local variables at the current scope inside debug hook and check which one has the value you need:
do
local seen = {}
debug.sethook(function(ev, line)
local level = 2
local target = 256
local i = 1
while true do
local name, value = debug.getlocal(level, i)
if not name then break end
if value == target and string.sub(name, 1, 1) ~= '(' and not seen[name] then
print("at line", line, "variable", name, value)
seen[name] = true
elseif seen[name] and value ~= target then
seen[name] = nil
end
i = i + 1
end
end, "l")
end
local a = 256
local b = 11
a = 13
a, b = 256, 256
print("done")
This prints the following for me:
at line 23 variable a 256
at line 26 variable a 256
at line 26 variable b 256
done
This only applies to local variables. For global variables you can iterate over _G or _ENV tables and compare the values.
Note that the lines printed are the lines of the next statement and not the lines on which the change happens (as the hook stops before the line is executed).
There are two other options to track variable changes (with some limitations): (1) using metamethods and a proxy table, and (2) using a debugger.

Resources