When using # to find array length, the array is Null - lua

So I have an array of people that I want to choose from at random...
local strong = {
'Laura',
'David',
'Christopher'
}
How would I pick randomly from this table? So far I have ran
print(math.random(#strong))
But when I run that get this error
lua: again.lua:19: attempt to get length of global 'strong' (a nil value)
Why would the array be nil, even though there is something inside the array?

If you use Lua interactively, put everything inside a do block, or remove local from your table variable to make it global. The interpreter executes each statement separately, losing the local of the previous statement.
Also, set the random seed with something like: math.randomseed(os.time()) to avoid getting the same value each run.

Related

Basic Lua/ FREESWITCH array command

I am new to Lua, and this is an elementary question.
I a Lua script, I am querying the Postgress DB for two records via Freeswitch dbh.
I am able to set the first value as a local variable.
I am stuck at how to set the second value as a variable.
local dbh = Database.new('system');
local settings = Settings.new(dbh, A, B);
local sql = "SELECT A, B FROM TABLE WHERE A = '" .. A.."'";
local A = dbh:first_value(sql); --this gets saved correctly
local B = WHAT DO PUT HERE? ; -- Perhaps, I need to create an array instead?
dbh:release()
If you only want a specific row you should do this in the SQL command.
Alternatively you can query the entire table and run through the rows of the result.
I don't know freeswitch but that's what I found here:
https://freeswitch.org/confluence/display/FREESWITCH/Lua+API+Reference
dbh:query("query", function()) takes the query as a string and an optional Lua callback function that is called on each row returned by
the db. The callback function is passed a table representation of the
current row for each iteration of the loop.
Syntax of each row is: { ["column_name_1"] = "value_1", ["column_name_2"] = "value_2" }.
If you (optionally) return a number other than 0 from the
callback-function, you'll break the loop.
In order to use this you should learn how to define functions and how to use function values. Then it should be obvious what to do.
Maybe there is also a function that returns the query result as a table. At least that is the case for many other database interfaces. Ideally you should read the manual of the freeswitch Lua API first. Then you know what commands exist. Together with the Lua manual you'll know how to use them.

We giving a task for Lua table but it is not working as expectable

Our task is create a table, and read values to the table using a loop. Print the values after the process is complete. - Create a table. - Read the number of values to be read to the table. - Read the values to the table using a loop. - Print the values in the table using another loop. for this we had written code as
local table = {}
for value in ipairs(table) do
io.read()
end
for value in ipairs(table) do
print(value)
end
not sure where we went wrong please help us. Our exception is
Input (stdin)
3
11
22
abc
Your Output (stdout)
~ no output ~
Expected Output
11
22
abc
Correct Code is
local table1 = {}
local x = io.read()
for line in io.lines() do
table.insert(table1, line)
end
for K, value in ipairs(table1) do
print(value)
end
Let's walk through this step-by-step.
Create a table.
Though the syntax is correct, table is a reserved pre-defined global name in Lua, and thus cannot should not be declared a variable name to avoid future issues. Instead, you'll need to want to use a different name. If you're insistent on using the word table, you'll have to distinguish it from the function global table. The easiest way to do this is change it to Table, as Lua is a case-sensitive language. Therefore, your table creation should look something like:
local Table = {}
Read values to the table using a loop.
Though Table is now established as a table, your for loop is only iterating through an empty table. It seems your goal is to iterate through the io.read() instead. But io.read() is probably not what you want here, though you can utilize a repeat loop if you wish to use io.read() via table.insert. However, repeat requires a condition that must be met for it to terminate, such as the length of the table reaching a certain amount (in your example, it would be until (#Table == 4)). Since this is a task you are given, I will not provide an example, but allow you to research this method and use it to your advantage.
Print the values after the process is complete.
You are on the right track with your printing loop. However, it must be noted that iterating through a table always returns two results, an index and a value. In your code, you would only return the index number, so your output would simply return:
1
2
3
4
If you are wanting the actual values, you'll need a placeholder for the index. Oftentimes, the placeholder for an unneeded variable in Lua is the underscore (_). Modify your for loop to account for the index, and you should be set.
Try modifying your code with the suggestions I've given and see if you can figure out how to achieve your end result.
Edited:
Thanks, Piglet, for corrections on the insight! I'd forgotten table itself wasn't a function, and wasn't reserved, but still bad form to use it as a variable name whether local or global. At least, it's how I was taught, but your comment is correct!

Lua: getting environment of element that belongs to specified table

Is it possible to check if some object is really element of specified table? I tried to use debug.getfenv(o) but didn't work.
someTable = {}
someTable.someValue = "Some String"
--gettable(someTable.someValue)
--so that could return table that stores someValue: someTable
getfenv is so named because it returns a function's environment. Because only functions have environments.
Values in Lua have no particular knowledge of which tables that they're in. If you need to know that, you'll have to keep track of it yourself.

Can I detect the moment of a value is just assigned to a table in Lua?

I made an interactive command shell which is operating by Lua interpreter. User input some command, shell calls something like lua_dostring to execute it. I want to allow users to define their own functions in arbitrary table, and save it to separated storage (like a file) automatically. According to the manual, I can get exact source code input by user with lua_Debug.
It looks possible to save the functions sources to some files after all execution done. But I want to save automatically when it's just added/remove.
Can I detect the moment of some value is just added to a table?
Yes. If you have a table tbl, every time this happens:
tbl[key] = value
The metamethod __newindex on tbls metatable is called. So what you need to do is give tbl a metatable and set it's __newindex metamethod to catch the input. Something like this:
local captureMeta = {}
function captureMeta.__newindex(table, key, value)
rawset(table, key, value)
--do what you need to with "value"
end
setmetatable(tbl, captureMeta);
You will have to find a way to set the metatable on the tables of interest, of course.
Here's another way to do this with metatables:
t={}
t_save={}
function table_newinsert(table, key, value)
io.write("Setting ", key, " = ", value, "\n")
t_save[key]=value
end
setmetatable(t, {__newindex=table_newinsert, __index=t_save})
Here's the result:
> t[1]="hello world"
Setting 1 = hello world
> print(t[1])
hello world
Note that I'm using a second table as the index to hold the values, instead of rawset, since __newindex only works on new inserts. The __index allows you to get these values back out from the t_save table.

What's the Javascript 'delete' keyword equivalent in Lua?

Javascript delete keyword deletes a named variable slot from nearest execution environment which it defined.
What's the equivalent in Lua?
var = nil
Environments in Lua are tables, and tables cannot contain nil value - assigning nil to a key in a table effectively deletes that key from the table.
Here is a quote from "Programming in Lua":
Like global variables, table fields
evaluate to nil if they are not
initialized. Also like global
variables, you can assign nil to a
table field to delete it. That is not
a coincidence: Lua stores global
variables in ordinary tables

Resources