More ipairs Confusion
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
-
- Prole
- Posts: 7
- Joined: Tue Jun 14, 2016 3:05 pm
- Location: Wonderland
More ipairs Confusion
I ran into another development problem that Im having a hard time wrapping my head around.
I was working on a couple functions to create an ingame sign with some text on it.
I have seen a couple of differrent ways to do it, but Im mostly wondering why what I have written doesnt work.
I think the problem is in love.load(), specifically in the ipairs part.(Line 31 - 41)
It seems to not be setting the text to the right values, also won't override previous values.
The first line of text should say "This is line 1 of the Sign," and not "Line 1." ("Line 1" is my placeholder)
Ive had a couple problem with colored text tables, but this has me completely confused.
I've included a .love file for others to audit, your expert opinion is appreciated.
With Löve,
Riley S.
PS: It's probably something obvious, I have problems spotting obvious errors.
I was working on a couple functions to create an ingame sign with some text on it.
I have seen a couple of differrent ways to do it, but Im mostly wondering why what I have written doesnt work.
I think the problem is in love.load(), specifically in the ipairs part.(Line 31 - 41)
It seems to not be setting the text to the right values, also won't override previous values.
The first line of text should say "This is line 1 of the Sign," and not "Line 1." ("Line 1" is my placeholder)
Ive had a couple problem with colored text tables, but this has me completely confused.
I've included a .love file for others to audit, your expert opinion is appreciated.
With Löve,
Riley S.
PS: It's probably something obvious, I have problems spotting obvious errors.
- Attachments
-
- SignTest.love
- (40.37 KiB) Downloaded 123 times
Begin again, let go.
Re: More ipairs Confusion
Your problem is in love.draw(). You're drawing the wrong table, the one that says, "Line 1", which is textLine.one. You really should be printing the table signText.line1.text.
The love.draw you have, incorrect:
The fixed love.draw that prints what you want:
Here's a .love file with your code fixed that it prints "This is line 1" instead of "Line 1".
The love.draw you have, incorrect:
Code: Select all
if signBool then
lg.draw(sign.img, sign.x, sign.y)
lg.print(textLine.one.text, textLine.one.x, textLine.one.y)
lg.print(textLine.two.text, textLine.two.x, textLine.two.y)
lg.print(textLine.three.text, textLine.three.x, textLine.three.y)
end
Code: Select all
if signBool then
lg.draw(sign.img, sign.x, sign.y)
lg.print(signText.line1.text, textLine.one.x, textLine.one.y)
lg.print(signText.line2.text, textLine.two.x, textLine.two.y)
lg.print(signText.line3.text, textLine.three.x, textLine.three.y)
end
- Attachments
-
- SignTest.love
- (39.81 KiB) Downloaded 140 times
I'M SORRY, BUT DOES REALLY BOLD TEXT BOTHER YOU
-
- Prole
- Posts: 7
- Joined: Tue Jun 14, 2016 3:05 pm
- Location: Wonderland
Re: More ipairs Confusion
Hello Janzo,
Thanks for trying to help me out with this problem, unfortunately this solution will not work with what I am going for.
I should probably have mentioned in my post that signText variables are static and will never change.
On the other hand, textLine variables are not static. textLine.lineX.text needs to be able to be switched out with other signText(s).
Example:
There are 4 lines of text, of which 3 can be displayed. When the user presses enter, all text gets shifted up by one spot.
Meaning, the first line of text disapears, all other texts are shifted up by one, and the 4th line is added.
However, I'm not looking for how to do this. I only am wondering why textLine.XXX.text seems to reject any attempt at setting its values through ipairs.
I have uploaded all larger portion of the code if that helps.
Thanks,
Riley S.
Thanks for trying to help me out with this problem, unfortunately this solution will not work with what I am going for.
I should probably have mentioned in my post that signText variables are static and will never change.
On the other hand, textLine variables are not static. textLine.lineX.text needs to be able to be switched out with other signText(s).
Example:
There are 4 lines of text, of which 3 can be displayed. When the user presses enter, all text gets shifted up by one spot.
Meaning, the first line of text disapears, all other texts are shifted up by one, and the 4th line is added.
However, I'm not looking for how to do this. I only am wondering why textLine.XXX.text seems to reject any attempt at setting its values through ipairs.
I have uploaded all larger portion of the code if that helps.
Thanks,
Riley S.
- Attachments
-
- SignTestLarge.love
- (42.11 KiB) Downloaded 127 times
Begin again, let go.
- zorg
- Party member
- Posts: 3470
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: More ipairs Confusion
I found your problem. You haven't read "Programming in lua" or "Pil". But i'll be nice and explain in detail.
In your code, you define textline as such:Now, this does absolutely nothing apart from create an empty table, and assign it to the variable textLine.
After, you create three string keys in the table, "one", "two" and "three", then later, you try, with ipairs, to iterate over the numeric indices of the textLine table... that don't exist.
(Technically, keys and indices are the same in this context, they are used the same, it's just good to treat them separately, depending on whether you're using a table as a numeric sequence or a list/dictionary/whatever.)
Also, your code kinda confuses the two tables you're using; you're actually trying to use textLine[l].tag, which doesn't even exist, only with signText... except you can't, because those are inside the five sub-tables called line1 to line5, which you didn't want to use in the first place?
In your code, you define textline as such:
Code: Select all
textLine = {one, two, three}
After, you create three string keys in the table, "one", "two" and "three", then later, you try, with ipairs, to iterate over the numeric indices of the textLine table... that don't exist.
(Technically, keys and indices are the same in this context, they are used the same, it's just good to treat them separately, depending on whether you're using a table as a numeric sequence or a list/dictionary/whatever.)
Also, your code kinda confuses the two tables you're using; you're actually trying to use textLine[l].tag, which doesn't even exist, only with signText... except you can't, because those are inside the five sub-tables called line1 to line5, which you didn't want to use in the first place?
Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
-
- Prole
- Posts: 7
- Joined: Tue Jun 14, 2016 3:05 pm
- Location: Wonderland
Re: More ipairs Confusion
Heya Zorg,
Sorry for my confusing code, your response has me confused as well.
"Also, your code kinda confuses the two tables you're using; you're actually trying to use textLine[l].tag, which doesn't even exist,"
You are correct, textLine[1].tag does not exist, and it was never supposed to. (textLine should never have a tag value)
Only signText[1].tag exists, and it refuses to be compared using ipairs.
Here is the long and short of it: I hate the implementation of colored text, it drives me nuts.
I tried having a table that was like this:
black = {0, 0, 0, 255}
text1 = {black, "This is Text!", tag = 1}
Because I added tag to the end of the table, it now refuses to be defined as a colored text object.
So instead i tried to have a table for the "colored text object" and it's tag the other table is basically a placeholder for the "colored text object" as well as it's x and y positions.
"because those are inside the five sub-tables called line1 to line5, which you didn't want to use in the first place?"
I actually very much wish to use those values, i just can't seem to call them out of the table.
Thanks,
Riley S.
Edit: Clarity
Edit 2: Added small attachment, If you can tell me whats wrong with this tiny attachment, I wont have to use any of the confusing code.
Sorry for my confusing code, your response has me confused as well.
"Also, your code kinda confuses the two tables you're using; you're actually trying to use textLine[l].tag, which doesn't even exist,"
You are correct, textLine[1].tag does not exist, and it was never supposed to. (textLine should never have a tag value)
Only signText[1].tag exists, and it refuses to be compared using ipairs.
Here is the long and short of it: I hate the implementation of colored text, it drives me nuts.
I tried having a table that was like this:
black = {0, 0, 0, 255}
text1 = {black, "This is Text!", tag = 1}
Because I added tag to the end of the table, it now refuses to be defined as a colored text object.
So instead i tried to have a table for the "colored text object" and it's tag the other table is basically a placeholder for the "colored text object" as well as it's x and y positions.
"because those are inside the five sub-tables called line1 to line5, which you didn't want to use in the first place?"
I actually very much wish to use those values, i just can't seem to call them out of the table.
Thanks,
Riley S.
Edit: Clarity
Edit 2: Added small attachment, If you can tell me whats wrong with this tiny attachment, I wont have to use any of the confusing code.
- Attachments
-
- TinyProblem.love
- (1.15 KiB) Downloaded 111 times
Begin again, let go.
Re: More ipairs Confusion
On line 5 in main.lua you're creating empty keys in textBox. This will fix the problem:
Read this.
Code: Select all
textBox = {text=text, tag} -- note tag is still nil
- zorg
- Party member
- Posts: 3470
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: More ipairs Confusion
Code: Select all
local highlight = "lua highlight pls..."
function HighLight(language) return "I SAID lua", ":(" end
-- Ignore the above lines...
a = {x} -- return a[x] -> nil; return a.x -> nil; return a[1] -> nil
b = {"x"} -- return b[x] -> nil; return b.x -> nil; return b[1] -> "x"
c = {x = "."} -- return c[x] -> nil; return c.x -> "."; return c[1] -> nil
d = {[x] = "."} -- return d[x] -> ***; return d.x -> ***; return d[1] -> ***
e = {["x"] = "."} -- return e[x] -> nil; return e.x -> "."; return e[1] -> nil
-- ***: x is a variable in the d case, so the following will work if and only if the variable is defined
local x = "x"
d = {[x] = "."} -- d[x] is set to ".", x == "x" so d["x"] is "."
return d.x -- also works, since for string keys, t.s is the same as t["s"].
Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Re: More ipairs Confusion
RileySunshine, you really have to consider delving into PiL at some point
Zorg's example is a great one. Just read that very carefully.
1. ipairs
What Zorg tried to convey is that ANY table has TWO parts: indexed one (numeric keys) and hashed one (with anything used as a key).
Now, when you write you create a "numeric" table with 3 elements all of which is nil.
But when you create a table like this you make a "hashed" table.
Now, ipairs CAN'T traverse the hash part of a table. And when all your fields are hashed... Right, you're going to get nothing from ipairs.
To get those elements inside "hashed" part of a table, you should use pairs (w/o "i", just pairs)
Until you'll learn the difference, use "pairs".
2. Now to your sample
You've creates a table "text" with 2 fields. Indexed, numerical fields.
text[1] is equal to the value stored inside the "red" variable.
text[2] is equal to "Help"
You could've write that like this:
Now, textBox contains 2 elements. AGAIN, those are in the numeric-indexed part of a table.
Ergo, textBox does NOT contain the "text" field.
It only contains the "text" table you've declared just prior to declaring the textBox variable.
By printing you're doing a wrong thing, as if you wanted to output a red text which says "Help", you should've done this:
Now if you want to type textBox.text then you should declare thing like this:
Then and only then you'll be good to do this:
Zorg's example is a great one. Just read that very carefully.
1. ipairs
What Zorg tried to convey is that ANY table has TWO parts: indexed one (numeric keys) and hashed one (with anything used as a key).
Now, when you write
Code: Select all
mytable = {one, two, three}
But when you create a table like this
Code: Select all
mytable={one="first item", two={"some item", 42}, ['REALLY UNNECESSARY CAPS HERE']="super glue is the culpit!!!111one"}
Now, ipairs CAN'T traverse the hash part of a table. And when all your fields are hashed... Right, you're going to get nothing from ipairs.
To get those elements inside "hashed" part of a table, you should use pairs (w/o "i", just pairs)
Code: Select all
for k,v in pairs(mytable) do ...
2. Now to your sample
Code: Select all
red = {255, 0, 0, 255}
text = {red, "Help"}
textBox = {text, tag}
text[1] is equal to the value stored inside the "red" variable.
text[2] is equal to "Help"
You could've write that like this:
Code: Select all
text={}
text[1]=red
text[2]="Help"
Code: Select all
textBox[1]=text
textBox[2]=tag -- the "tag" variable is nil, so textBox[2] is going to be nil to
It only contains the "text" table you've declared just prior to declaring the textBox variable.
By printing
Code: Select all
lg.print(textBox.text, 160, 160)
Code: Select all
lg.setColor(textBox[1][1]) lg.print(textBox[1][2], 160, 160)
Code: Select all
red = {255, 0, 0, 255}
linedef = {color=red, line="Help"}
textBox = {text=linedef}
Code: Select all
lg.setColor(textBox.text.color) lg.print(textBox.text.line, 160, 160)
- zorg
- Party member
- Posts: 3470
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: More ipairs Confusion
Actually, i wanted to edit my previous post so it's a bit more clear, but this way is fine too.
I'd mention that pairs is, for a few reasons, actually "worse" of an iterator than ipairs:
- pairs goes in an arbitrary order, and every time you use the iterator even on the same table, the order may be completely different.
- in a "bigger" project, pairs will be very slow, slower than ipairs.
Depending on your use-case, it may be acceptable, of course.
As for a clearer, hopefully complete example of how one can create (and index) tables, i give you a bit more cleaned up code example; this one you can actually run in the online lua testbed.
As for accessing table members/fields, the dot syntax is equivalent to the []-syntax when whatever inside the bracket is a string.
I'd mention that pairs is, for a few reasons, actually "worse" of an iterator than ipairs:
- pairs goes in an arbitrary order, and every time you use the iterator even on the same table, the order may be completely different.
- in a "bigger" project, pairs will be very slow, slower than ipairs.
Depending on your use-case, it may be acceptable, of course.
As for a clearer, hopefully complete example of how one can create (and index) tables, i give you a bit more cleaned up code example; this one you can actually run in the online lua testbed.
Code: Select all
-- Assign the string "j" to the (local) variable i.
local i = "j"
--[[ Very compact ]]--
-- first numerically indexed field of t = the variable i
-- full form: t[1] = i
t = {i}
print(t.i, t[i], t["i"], t[1])
-- first numerically indexed field of t = the string "i"
-- full form: t[1] = "i"
t = {"i"}
print(t.i, t[i], t["i"], t[1])
-- syntax error, you need to assign something to a key
--t = {[i]}
--[[ Compact ]]--
-- the field of the tabe t indexed by the string "i" = the variable i
-- full form: t["i"] = i
t = {i = i}
print(t.i, t[i], t["i"], t[1])
-- the field of the tabe t indexed by the string "i" = the string "i"
-- full form: t["i"] = "i"
t = {i = "i"}
print(t.i, t[i], t["i"], t[1])
-- syntax error, "i" is not a key.
-- t = {"i" = i}
-- syntax error, "i" is still not a key.
-- t = {"i" = "i"}
--[[ Full forms ]]--
-- t[the variable i] = the variable i, errors if the variable i is nil, can't have nil keys.
t = {[i] = i}
print(t.i, t[i], t["i"], t[1])
-- t[the variable i] = the string "i", errors if the variable i is nil, can't have nil keys.
t = {[i] = "i"}
print(t.i, t[i], t["i"], t[1])
-- t[the string "i"] = the variable i
t = {["i"] = i}
print(t.i, t[i], t["i"], t[1])
-- t[the string "i"] = the string "i"
t = {["i"] = "i"}
print(t.i, t[i], t["i"], t[1])
Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
-
- Prole
- Posts: 7
- Joined: Tue Jun 14, 2016 3:05 pm
- Location: Wonderland
Re: More ipairs Confusion
Dear Zorg & 4aiman,
Thank you both so much for your help, really appreciate it. To be fair, I have read PiL a bit.(Haven't read all of it, tables section still confuses me)
To 4aimain:
Thank you so much for your help yet again, you always are able to phrase things in a way that are easy to understand.
What I got out of your reply the most was this line:
"Now, ipairs CAN'T traverse the hash part of a table. And when all your fields are hashed... Right, you're going to get nothing from ipairs."
That helped me understand exactly why this was failing, plus now I know what the "i" in ipairs stands for.
During my short time developing love games, I have always used table.insert to add things to tables, and then ipairs to "use" them.
I see now that table.insert is adding indexed values/tables, whereas I was adding non-indexed values/tables.'
Once again thanks, that one line helped everything click together in my mind.
To Zorg:
Thanks for taking time out of your day to help me understand this.
I had a hard time understanding your second reply, but your third reply is filled with very interesting information.
Lots of good nuggets of information in there, thanks.
I really appreciate the explanation of why pairs may be a worse choice in certain situations, little things like that are hard to pick up from tutorials and refrence documents.
As far as use cases, this section of code will exclusively used to write a few lines of text on a screen. Seeing as it wont happen very often, and wont be called upon often either, I think it may be the proper use case for this.
Seriously though, thanks for that tip. I'll keep your advice on ipairs vs pairs handy, I seem to be using ipairs a lot lately.
To Both:
Once again thanks for the help, I would've been working that out for a long time if you guys had not helped.
With Löve,
Riley S.
Thank you both so much for your help, really appreciate it. To be fair, I have read PiL a bit.(Haven't read all of it, tables section still confuses me)
To 4aimain:
Thank you so much for your help yet again, you always are able to phrase things in a way that are easy to understand.
What I got out of your reply the most was this line:
"Now, ipairs CAN'T traverse the hash part of a table. And when all your fields are hashed... Right, you're going to get nothing from ipairs."
That helped me understand exactly why this was failing, plus now I know what the "i" in ipairs stands for.
During my short time developing love games, I have always used table.insert to add things to tables, and then ipairs to "use" them.
I see now that table.insert is adding indexed values/tables, whereas I was adding non-indexed values/tables.'
Once again thanks, that one line helped everything click together in my mind.
To Zorg:
Thanks for taking time out of your day to help me understand this.
I had a hard time understanding your second reply, but your third reply is filled with very interesting information.
Lots of good nuggets of information in there, thanks.
I really appreciate the explanation of why pairs may be a worse choice in certain situations, little things like that are hard to pick up from tutorials and refrence documents.
As far as use cases, this section of code will exclusively used to write a few lines of text on a screen. Seeing as it wont happen very often, and wont be called upon often either, I think it may be the proper use case for this.
Seriously though, thanks for that tip. I'll keep your advice on ipairs vs pairs handy, I seem to be using ipairs a lot lately.
To Both:
Once again thanks for the help, I would've been working that out for a long time if you guys had not helped.
With Löve,
Riley S.
Begin again, let go.
Who is online
Users browsing this forum: Bing [Bot], Google [Bot] and 3 guests