Is it a bad idea to have functions calling each other or should I just be fine as long as they don't loop?
It's fine to have functions call each other (the stack can hold over a couple of hundred instances, after all), but it's usually a bad idea to form any sort of loop out of function calls.
Personally I discourage defining functions
at all unless you're going to call them from multiple points in your script. If the code block is large enough then sure it might be worth bundling away, but don't try and use functions as comments. Creating a one-shot two-line function is of no benefit; it simply makes your code harder to read.
I also don't really understand the whole "for name, data in pairs(item) do" thing and how it all works. Can someone explain that?
The basic structure at work here is "for
<values> in
<function> do". The loop calls the provided function over and over, assigning its return values to the variables you supply, stopping once the function returns nil.
In this case, the function used is
returned by "pairs(item)". pairs() accepts a table and returns
another function that'll return values from that table each time
it's called, finally returning nil once it runs out of unique table keys. Functions such as the ones generated by pairs() are dubbed "iterator functions", as they're most frequently used inside loops.
The first value returned is the name of each table key, and the second value returned is the data associated with that key. Hence another way you could write your deletion loop is:
for i, data in pairs(item) do
if data["num"] == p1 then
item[i] = nil -- Remove the table pointer from the "item" table.
break -- Exit the loop.
end
end
I need to find a way to convert the color input from the newItem() function to the actual color number. As of right now the function only takes in say color.magenta as "color.magenta" and saves it under the color key in the table. I need someway to convert that over to the number version of color.magenta so it can be added with the rest of the colors and set the bundled output.
I notice that you're overwriting
the default "colors" table on line 4. It's generally better to avoid
pre-existing APIs when choosing your variable names.
You'd be better off having your newItem() function accept strings representing keys in the original colors table. Let's say the user enters "magenta"; you can then later get the numeric color representation via colors[ item[ name ][ "colorString" ] ].
It's also worth noting that in a conditional statement, anything that isn't false / nil counts as true. This means, for example, that you can do:
repeat
write("Enter a valid colour: ")
colorString = read()
until colors[ colorString ]
This likewise means that code such as "if on == true then" is redundant (just do "if on then").
Truth be told, you'd really be better off indexing your "items" table by
number rather than
name. This'd allow you to use table.remove(), which'd re-index all the other table entries: allowing you to easily keep the numbers contiguous. It'd also mean that you wouldn't have to use loops to figure out where key number X is.
A couple of other quick tips, this sort of thing:
repeat
event, p1 = os.pullEvent()
until event == "char"
… can be done by simply passing the desired event type to os.pullEvent():
event, p1 = os.pullEvent("char")
If you want to convert "items" to a string (as you seem to be doing on line 108), it's much neater to run it through tostring() than it is to concatenate it.