lua table index is null error - lua

I am trying to write a lua switch, based on what I have read so far it seems this is achieved by using a table. So I made a really barebones table but when I try to run it I get an error saying table index is null.
Ultimately what I want is based on different input, this code should call on different lua files. But for now since I am new to this language I figured I would settle for not having that index error.
thanks
#!/usr/bin/lua
-- hello world lua program
print ("Hello World!")
io.write('Hello, where would you like to go?\n')
s = io.read()
io.write('you want to go to ',s,'\n')
--here if i input a i get error
location = {
[a] = '1',
[b] = '2',
[c] = '3',
[d] = '4',
}
location[s]()
Above is the code that I got so far. Below is the error.
~$ lua lua_hello.lua
Hello World!
Hello, where would you like to go?
a
you want to go to a
lua: lua_hello.lua:11: table index is nil
stack traceback:
lua_hello.lua:11: in main chunk
[C]: in ?
The table code is based on this example here: Lua Tables Tutorial section:Tables as arrays

What appears to be the issue is that location[a] is setting location at index a, which is not a string. When you enter a into your input, it gets read as 'a' which IS a string. Index [a] is different from index ['a']. What you want is to replace your assignments so that they're assigned to strings (location['a'] = '1').
As Ihf has said, if you want to print the output then you need to call print(location[s]) because location[s] will simply return the string '1' (or whichever value, just as a string). If you want to assign the numeric value (to use for calculations or etc) then you should use location['a'] = 1.
Alternatively, keep the value as-is as a string and when you attempt to use the value, simply use tonumber().
Example: x = 5 * tonumber(location[s]).
I hope this was helpful, have a great week!

Try
location = {
['a'] = '1',
['b'] = '2',
['c'] = '3',
['d'] = '4',
}
Then that error goes away but is replaced by attempt to call a string value (field '?') because location['a'] is the string '1'.
Perhaps you want
print(location[s])

Related

how do i call for a vaiable using user_input

the file im working on is a feckin mess so im going to use this instead
a = 1
b = 2
c = 3
user_input =
I want to be able to write b in the terminal and get back 2
ive tried all the different io functions and I don't want to use print
… sorry if this is stupid simple im a new programmer (learning)
also please don't out right tell me how to solve this problem just get me on the right track please
If you are asking how to output something based on the user input you could instead make a table like
values = {
['a'] = 1,
['b'] = 2,
['c'] = 3,
--continued for as many as you want
}
and then simply print the value at the index they input
if values[user_input] then --Make sure the index is valid before trying to print it
print(values[user_input])
end
I think what you are saying is:
if (user_input=="b"){
print(b)
}
Since you use globals a, b and c, you can refer to them as _G[var]:
var = io.read()
print _G[var]
Also, you can use getfenv()/setfenv() in Lua 5.1 and _ENV in Lua 5.2+ to avoid polluting the global scope (see http://lua-users.org/wiki/EnvironmentsTutorial).
#! /usr/bin/env lua
local table = {}
table .a = 1
table .b = 2
table .c = 3
local function test_inclusion()
io .write( 'key: ' )
key = io .read()
if table[ key ] then
value = table[ key ]
io .write( 'value: ' ..value ..'\n' )
end
end
test_inclusion()

Lua - get table hex identifier

I want to know how to get the table hex id. I know that doing:
local some_var = {}
print (some_var)
the result is (for instance):
table: 0x21581c0
I want the hex without the table: string. I know that maybe some of you suggest me to make a regular expression (or something similar) to remove those chars, but I want to avoid that, and just get the 0x21581c0
Thanks
This is simpler and works for all types that are associated with pointers:
local function getId(t)
return string.format("%p", t)
end
print("string:", getId("hi"))
print("table:", getId({}))
print("userdata:", getId(io.stdin))
print("function:", getId(print))
print("number:", getId(1))
print("boolean:", getId(false))
print("nil:", getId(nil))
Result:
string: 0x0109f04638
table: 0x0109f0a270
userdata: 0x01098076c8
function: 0x0109806018
number: NULL
boolean: NULL
nil: NULL
In the standard implementation, there is the global 'print' variable that refers to a standard function that calls, through the global variable 'tostring', a standard function described here. The stanard 'tostring' function is the only way to retrieve the hexadecimal number it shows for a table.
Unfortunately, there is no configuration for either of the functions to do anything differently for all tables.
Nonetheless, there are several points for modification. You can create you own function and call that every time instead, or point either of the the global variables print or tostring to you own functions. Or, set a __tostring metamethod on each table you need tostring to return a different answer for. The advantage to this is it gets you the format you want with only one setup step. The disadvantage is that you have to set up each table.
local function simplifyTableToString(t)
local answer = tostring(t):gsub("table: ", "", 1)
local mt = getmetatable(t)
if not mt then
mt = {}
setmetatable(t, mt)
end
mt.__tostring = function() return answer end
end
local a = {}
local b = {}
print(a, b)
simplifyTableToString(a)
print(a, b)
Without complex patterns, you can just search for the first space, and grab the substring of what follows.
function get_mem_addr (object)
local str = tostring(object)
return str:sub(str:find(' ') + 1)
end
print(get_mem_addr({})) -- 0x109638
print(get_mem_addr(function () end)) -- 0x108cf8
This function will work with tables and functions, but expect errors if you pass it anything else.
Or you can use a little type checking:
function get_mem_addr (o)
return tostring(o):sub(type(o):len() + 3)
end
The table id stated by the OP is invalid in the version of Lua I am using (5.1 in Roblox). A valid ID is length 8, not 9 as in your example. Either way, just use string.sub to get the sub-string you are after.
string.sub(tostring({}), 8)
The reason is, 'table: ' is 7 characters long, so we take from index 8 through the end of the string which returns the hex value.

Trying to understand Lua simple codes

I'm having some trouble with Lua. The thing is: there are some Lua codes I know what they do but I didn't understood them, so if the professors ask me to explain them, I wouldn't be able to do it.
Can you help me with this?
I know this code separates the integer part from the decimal part of a number, but I didn't understand the "(%d*)(%.?.*)$" part.
int, dec = string.match(tostring(value), "(%d*)(%.?.*)$")
This code insert on a table all the data from a text file, which is written following this model entry {name = "John", age = 20, sex = "Male"). What I didn't understand is how do I know what parameters the function load needs? And the last parameter entry = entry, I don't know if I got exactly its meaning: I think it gets the text_from_file as a piece of Lua code and everything that is after entry is sent to the function entry, which inserts it on a table, is it right?
function entry(entrydata)
table.insert(data, entrydata)
end
thunk = load(text_from_file, nil, nil, {entry = entry})
thunk()
That's it. Please, if it's possible, help me understand these 2 pieces of Lua code, I need to present the whole program working and if a professor ask me about the code, I want to be sure about everything.
For the first question, you need to learn a little about lua patterns and string.match.
The pattern (%d*)(%.?.*)$ is comprised of two smaller ones. %d* and %.?.*. The $ at the end merely indicates that the matching is to be done till the end of string tostring(value). The %d* will match 0 or more numerical values and store the result (if found, otherwise nil) t the variable int.
%.? matches a literal . character. The ? means that the . may or may not be present. The .* matches everything and stores them into dec variable.
Similarly, for the second code segment, please go through the load() reference. You have the following text in your file:
entry {name = "John", age = 20, sex = "Male")
It is equivalent to executing a function named entry with the parameter (notice that I used parameter and not parameters) a table, as follows:
entry( {name = "John", age = 20, sex = "Male") )
The last parameter to load defines the environment for the loaded string. By passing {entry = entry}, you're defining an environment in which you have a function named entry. To understand it better, look at the changes in the following segment:
function myOwnFunctionName(entrydata)
table.insert(data, entrydata)
end
thunk = load(text_from_file, nil, nil, {entry = myOwnFunctionName})
Now, the custom environment passed to load will have a variable named entry which is actually the function myOwnFunctionName.

Elder Scroll Online Addon

This is my first time working with Lua, but not with programming. I have experience in Java, Action Script, and HTML. I am trying to create an addon for Elder Scroll Online. I managed to find the ESO API at the following link:
http://wiki.esoui.com/API#Player_Escorting
I am trying to make a function that returns a count of how many items each guild member has deposited in the bank. The code I have so far is as follows
function members()
for i=0, GetNumGuildEvents(3, GUILD_EVENT_BANKITEM_ADDED)
do
GetGuildEventInfo(3, GUILD_EVENT_BANKITEM_ADDED, i)
end
I am having trouble referencing the character making the specific deposit. Once I am able to do that I foresee making a linked list storing character names and an integer/double counter for the number of items deposited. If anyone has an idea of how to reference the character for a given deposit it would be much appreciated.
I don't have the game to test and the API documentation is sparse, so what follows are educated guesses/tips/hints (I know Lua well and programmed WoW for years).
Lua supports multiple assignment and functions can return multiple values:
function foo()
return 1, "two", print
end
local a, b, c = foo()
c(a,b) -- output: 1, "two"
GetGuildEventInfo says it returns the following:
eventType, secsSinceEvent, param1, param2, param3, param4, param5
Given that this function applies to multiple guild event types, I would expect param1 through param5 are specific to the particular event you're querying. Just print them out and see what you get. If you have a print function available that works something like Lua's standard print function (i.e. accepts multiple arguments and prints them all), you can simple write:
print(GetGuildEventInfo(3,GUILD_EVENT_BANKITEM_ADDED,i))
To print all its return values.
If you don't have a print, you should write one. I see the function LogChatText which looks suspiciously like something that would write text to your chat window. If so, you can write a Lua-esque print function like this:
function print(...)
LogChatText(table.concat({...}, ' '))
end
If you find from your experimentation that, say, param1 is the name of the player making the deposit, you can write:
local eventType, secsSinceEvent, playerName = GetGuildEventInfo(3,GUILD_EVENT_BANKITEM_ADDED, i)
I foresee making a linked list storing character names and an integer/double counter for the number of items deposited.
You wouldn't want to do that with a linked list (not in Lua, Java nor ActionScript). Lua is practically built on hashtables (aka 'tables'), which in Lua are very powerful and generalized, capable of using any type as either key or value.
local playerEvents = {} -- this creates a table
playerEvents["The Dude"] = 0 -- this associates the string "The Dude" with the value 0
print(playerEvents["The Dude"]) -- retrieve the value associated with the string "The Dude"
playerEvents["The Dude"] = playerEvents["The Dude"] + 1 -- this adds 1 to whatever was previous associated with The Dude
If you index a table with a key which hasn't been written to, you'll get back nil. You can use this to determine if you've created an entry for a player yet.
We're going to pretend that param1 contains the player name. Fix this when you find out where it's actually located:
local itemsAdded = {}
function members()
for i=0, GetNumGuildEvents(3, GUILD_EVENT_BANKITEM_ADDED ) do
local eventType, secsSinceEvent, playerName = GetGuildEventInfo(3, GUILD_EVENT_BANKITEM_ADDED, i)
itemsAdded[playerName] = (itemsAdded[playerName] or 0) + 1
end
end
itemsAdded now contains the number of items added by each player. To print them out:
for name, count in pairs(itemsAdded) do
print(string.format("Player %s has added %d items to the bank.", name, count))
end

How to manipulate number in Redis using Lua Script

I am trying to multiply two numbers stored in Redis using the Lua Script. But I am getting ClassCastException. Could someone point out What is wrong in the program
jedis.set("one", "1");
jedis.set("two", "2");
String script = "return {tonumber(redis.call('get',KEYS[1])) * tonumber(redis.call('get',KEYS[2]))}";
String [] keys = new String[]{"one","two"};
Object response = jedis.eval(script, 2, keys );
System.out.println(response);
throws
Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to [B
at redis.clients.jedis.Jedis.getEvalResult(Jedis.java:2806)
at redis.clients.jedis.Jedis.eval(Jedis.java:2766)
at com.test.jedis.script.SimpleScript.main(SimpleScript.java:18)
You can't cast a table to a number in lua. What you want is to grab the number of elements in the table instead. You can do this by using the last element point #. Also, I'd highly recommend separating out your Lua script from the rest of your code, so it's cleaner. Your Lua script should look like:
local first_key = redis.call('get',KEYS[1])
local second_key = redis.call('get',KEYS[2])
return #first_key * #second_key
EDIT: Misunderstood the question. OP correctly pointed out he is trying to multiple two numbers stored as strings rather than a table length. In that case:
local first_key = redis.call('get',KEYS[1])
if not tonumber(first_key) then return "bad type on key[1]" end
local second_key = redis.call('get',KEYS[2])
if not tonumber(second_key) then return "bad type on key[2]" end
return tonumber(first_key) * tonumber(second_key)

Resources