can you use a colon in a key for a lua table - lua

So I'm writing a program for the minecraft mod computercraft. I wanted to know if it was possible to do something like this:
tbl = {}
var = "minecraft:dirt"
tbl[var] = {pos ={0,0,0,1}}
For some reason I feel it doesnt save this table correctly so when I go to do
print(tbl["minecraft:dirt"].pos[4])
it errors
Can you use colons in keys?

tbl = {}
var = "minecraft:dirt"
tbl[var] = {pos ={0,0,0,1}}
print(tbl["minecraft:dirt"].pos[4])
prints 1
This is syntactically correct and should not result in any error message.
The only thing that won't work with colon is the syntactic sugar tbl.minecraft:dirt as Lua names may not contain colons. But if you use it like that tbl["minecraft:dirt"] colon is perfectly fine.
Long story short: Yes you can use colons in table keys.

Related

Lua/print table error : ( attempt to concatenate a table value)

I got a simple code like:
table = {}
print(table.."hello")
then got a error like the title. I know i need to use tostring(table) to fix it . Why table or other types can't convert to string to concatenate a String automatically except number type ?
print(table) is available But print(table.."hello") is not .
Does lua have some rules?
Thanks you.
Why table or other types can't convert to string to concatenate a String automatically except number type?
This is a deliberate choice made by the Lua language designers. Strings and numbers are coerced: Every operation that expects a string will also accept a number and tostring it; every operation that expects a number will also accept a string and tonumber it.
Coercion is an operation applied to strings. Numbers will be tostringed. Any other type won't. For other primitive types like bools and nils this is somewhat questionable, since they can be converted to string without issue. For tables it's reasonable though since they are a reference type.
Unlike other languages which make such decisions for you, Lua is highly metaprogrammable: You can simply override the decision! In this case, metatables are the solution, specifically the __concat metamethod which gets called if concatenation (..) is applied to two values of which one has the metamethod (and is neither a string or number):
table = setmetatable({}, {
__concat = function(left, right)
if type(left) == "string" then
return left .. tostring(right)
end
return tostring(left) .. tostring(right)
end
})
print(table .. "hello") -- hellotable: 0x563eb139bea0
You could even extend this to primitive types (nils, booleans), some other reference types (functions, coroutines) using debug.setmetatable, but I'd advise against this.
The declaration of table = {} destroying the table library
The datatype table is not a string or number so concat with .. must fail
Try this instead...
mytab = {}
table.insert(mytab, "hello")
print(table.concat(mytab))
For the table library functions look: https://www.lua.org/manual/5.4/manual.html#6.6

navigate table without using pairs in Lua

Hello im a newbie in Lua i just want to know if there is a way to get key and value of table not using pairs,ipairs,next or other iterators? thanks in advance.!
I don't believe this is possible, as you've phrased your question in such a way that implies that the key is unknown. The only way to check for a certain value and its corresponding key would be to iterate through the whole table.
However, maybe I misunderstood and you want to get a certain value from a key without iterating through the whole table.
Say you have a table named morse as follows:
morse = { a = ".-"; b = "-..."; } -- And so on
If you wanted to convert a single character to morse you could do as follows:
morse["a"] --Which will return the string ".-"
You can do the opposite, and define a table with all the morse values and their corresponding letters like below. Note the use of square brackets to 'escape' the characters.
morse = { [".-"] = "a"; ["-..."] = "b" }
morse[".-"] -- This will return "a"
Based on your comment, I think you are looking for a string substitution using a mapping table. I think you can use string.gsub here (if your teacher still insists that .gsub is an iterator; you can ask them politely that you are unaware of the method they claim and would be delighted to actually learn about the same):
local str = "sos sos sos"
local morse = {s = "...", o = "---"}
print( str:gsub("%a", morse) )

Lua Semicolon Conventions

I was wondering if there is a general convention for the usage of semicolons in Lua, and if so, where/why should I use them? I come from a programming background, so ending statements with a semicolon seems intuitively correct. However I was concerned as to why they are "optional" when its generally accepted that semicolons end statements in other programming languages. Perhaps there is some benefit?
For example: From the lua programming guide, these are all acceptable, equivalent, and syntactically accurate:
a = 1
b = a*2
a = 1;
b = a*2;
a = 1 ; b = a*2
a = 1 b = a*2 -- ugly, but valid
The author also mentions: Usually, I use semicolons only to separate two or more statements written in the same line, but this is just a convention.
Is this generally accepted by the Lua community, or is there another way that is preferred by most? Or is it as simple as my personal preference?
Semi-colons in Lua are generally only required when writing multiple statements on a line.
So for example:
local a,b=1,2; print(a+b)
Alternatively written as:
local a,b=1,2
print(a+b)
Off the top of my head, I can't remember any other time in Lua where I had to use a semi-colon.
Edit: looking in the lua 5.2 reference I see one other common place where you'd need to use semi-colons to avoid ambiguity - where you have a simple statement followed by a function call or parens to group a compound statement. here is the manual example located here:
--[[ Function calls and assignments can start with an open parenthesis. This
possibility leads to an ambiguity in the Lua grammar. Consider the
following fragment: ]]
a = b + c
(print or io.write)('done')
-- The grammar could see it in two ways:
a = b + c(print or io.write)('done')
a = b + c; (print or io.write)('done')
in local variable and function definition. Here I compare two quite similar sample codes to illustrate my point of view.
local f; f = function() function-body end
local f = function() function-body end
These two functions can return different results when the function-body section contains reference to variable "f".
Many programming languages (including Lua) that do not require semicolons have a convention to not use them, except for separating multiple statements on the same line.
Javascript is an important exception, which generally uses semicolons by convention.
Kotlin is also technically an exception. The Kotlin Documentation say not only not to use semicolons on non-batched statements, but also to
Omit semicolons whenever possible.
In local variable definitions, we get ambiguous results from time to time:
local a, b = string.find("hello world", "hello") --> a = nil, b = nil
while sometimes a and b are assigned the right values 7 and 11.
So I found no choice but to follow one of these two approaches:
local a, b; a, b = string.find("hello world", "hello") --> a, b = 7, 11
local a, b
a, b = string.find("hello world", "hello") --> a, b = 7, 11
For having more than one thing on a line, for example:
c=5
a=1+c
print(a) -- 6
could be shortened to:
c=5; a=1+c; print(a) -- 6
also worth noting that if you're used to Javascript, or something like that, where you have to end a line in a semicolon, and you're especially used to writing that, then this means that you won't have to remove that semicolon, and trust me, i'm used to Javascript too, and I really, really forget that you don't need the semicolon, every time I write a new line!

mysql_real_escape_string when echoing out?

I know I have to use mysql_real_escape_string when running it in a query, for example:
$ProjectHasReservationQuery = ("
SELECT *
FROM reservelist rl
INNER JOIN project p on rl.projectid = p.projectid
WHERE rl.projectid = ". mysql_real_escape_string($record['projectid']) ."
AND restype = 'res'
");
But how about echoing it out, like:
query1 = mysql_query("SELECT * FROM users");
while ($record = mysql_fetch_array($query1 ))
{
echo "".stripslashes(mysql_real_escape_string($record['usersurname']))."";
// OR
echo "".$record['usersurname']."";
}
Which one is it? Personally I think echo "".$record['usersurname']."";, since this is coming FROM a query and not going INTO. But want to be 100% sure.
(I am aware about PDO and mysqli)
I know I have to use mysql_real_escape_string when running it in a query
Quite contrary, you should not use mysql_real_escape_string on a query like this.
It will do no good but leave you with false feeling of safety.
As you can say from the function name, it is used to escape strings, while you are adding a number. So, this function become useless, while your query still remains wide open for injection.
One have to use this function only to format quoted strings in the SQL query.
Thus you can conclude the answer from this rule: no, there is no point in using this function for output.
As for the protection, either treat your number as a string (by quoting and escaping it) or cast it using intval() function.
Or, the best choice, get rid of this manual formatting and start using placeholders to represent dynamical data in the query. it is not necessarily prepared statements - it could use the same escaping, but encapsulated in some placeholder handling function

Error in string.gsub with backslash

local a = "te\st"
local b = string.gsub(a,'\','\\\\')
assert(false,b)
What am I doing wrong?
When I do assert, I want that to the screen the string te\st will be printed... but it's not working
I have a JSON file, that I want to decode it into Lua table. I don't need to print out nothing, I did the assert just to test a local problem.
So what I need is to keep all data in the JSON file that has '\'.
Use [[]] instead of "" or '' if you don't want backslash to have special meaning.
Read about literal strings in the manual.
Have you tried escaping it with the % character instead of \
I don't know if this will help, but I was having a HELL of a time making Lua's gsub match my string with special characters in it that I wanted treated literally... it turned out that instead of using \ as an escape character, or doubling the character, that I needed to prefix the special character with % to make it be treated literally.
Your question wasn't too clear so I'm not 100% sure what you mean. Do you mean that you want the assert to fire when b is equal to the string "te\st"? If so you can do a simple:
assert(b ~= "te\st")
Or I suppse...
assert(b ~= a)
You don't need the gsub. But here it is anyways.
local a = "te\\st"
local b = string.gsub(a,'\\','\\')
assert(false,b)

Resources