Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Due to spam on this forum, all posts now need moderator approval.
Entire forum
➜ MUSHclient
➜ Lua
➜ Question about tprint function and recursion
|
Question about tprint function and recursion
|
It is now over 60 days since the last post. This thread is closed.
Refresh page
| Posted by
| XRei
(2 posts) Bio
|
| Date
| Wed 20 Aug 2014 04:04 AM (UTC) Amended on Wed 20 Aug 2014 04:10 AM (UTC) by XRei
|
| Message
| Hello. I have a question about the tprint function included with MUSH Client. I am a super novice at programming in general. I've been casually toying around in Lua for a few weeks now, and I've been using my understanding of the tprint function to gauge how far my understanding of Lua is coming along. I finally feel like I can follow and understand everything going on with it now.. EXCEPT one part which has me confused. Let met set up an example:
Here is the tprint() function from the forum for clarity sake:
function tprint (t, indent, done)
done = done or {}
indent = indent or 0
for key, value in pairs (t) do
Tell (string.rep (" ", indent)) -- indent it
if type (value) == "table" and not done [value] then
done [value] = true
Note (tostring (key), ":");
tprint (value, indent + 2, done)
else
Tell (tostring (key), "=")
print (value)
end
end
end
Here is the table I want to recursively print.
t = {
keyOne = "This is the first key.",
keyTwo = { "This", "is", "the", "second", "key." },
keyThree = { "This", "is", "the", "third", "key." },
keyFour = { { "This", { "is", { "the", { "fourth", { "key." }}}}} }
}
If I run it through the tprint(t) function like normal, I get the expected result, where each key and value is indented to the correct depth like so:
keyThree:
1=This
2=is
3=the
4=third
5=key.
keyFour:
1:
1=This
2:
1=is
2:
1=the
2:
1=fourth
2:
1=key.
keyTwo:
1=This
2=is
3=the
4=second
5=key.
keyOne=This is the first key.
So where I get confused is this.. What is the purpose of the 'done' table in the code? As far I can see, each iteration of the key/value pairs in the table(or in a sub table) checks to see if that particular value(or table in this case) has been set to 'true' in the 'done' table. At first I thought this was to make sure that when the function calls itself again that the new function block which is passed the 'done' table would see that the value in the 'done' table has already been previously iterated and would skip it to go to the next one.. But I later found out that the way function call stacks work that each instance of a function is 'stored' in the stack until the algorithm works it's way back down to the bottom of the stack in sequence.. but that also means that the iteration of each table is only ever traversed once?
(Not sure if I'm even making sense)
Anyways, as a test I tried making a copy of the tprint() function and removed all instances and references to 'done'. I ran the program on my table and.. it produced the exact same output. It seems like 'done' isn't even required. What am I missing?
Thanks. | | Top |
|
| Posted by
| Nick Gammon
Australia (23,173 posts) Bio
Forum Administrator |
| Date
| Reply #1 on Wed 20 Aug 2014 05:35 AM (UTC) Amended on Wed 20 Aug 2014 05:36 AM (UTC) by Nick Gammon
|
| Message
| It's a good question, and there is a simple answer:
It's to prevent infinite loops for tables with self-references.
Here's an example:
foo = { }
foo.bar = foo
tprint (foo)
With the supplied tprint that prints:
"bar":
"bar"=table: 00D0C5F0
Note that it doesn't expand "bar" again. If it did, it would have to expand bar.bar, and then bar.bar.bar and so on.
If you comment-out the line:
Then (in this case) the client goes into an infinite loop and you have to force-quit it.
Now you might say "well no-one would do that", but there is one big example of exactly that. The "global" table, which you can reference with the _G variable.
If you do this:
You will see _G listed in there somewhere. Without that "done" code everyone that did a tprint of _G would have to force-quit their client. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | | Top |
|
| Posted by
| XRei
(2 posts) Bio
|
| Date
| Reply #2 on Wed 20 Aug 2014 05:55 AM (UTC) |
| Message
| Ah ha! That actually makes perfect sense now. Thanks for clearing that up.
Oh, and also thanks for MUSHClient being so awesome. *thumbsup* | | Top |
|
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.
12,566 views.
It is now over 60 days since the last post. This thread is closed.
Refresh page
top