-
Posted by lankus on Thu, 30 Jul 2009 22:21:29
So I've been going through the book (awesome btw!) and whenever I come across an example it's just in my nature to try twisting parts of the code around to see what happens and figure out why it gives the result that it does. I was working on the 'factorial' part (page 38) and got a 'nil' value when I swapped some things around and I'm just wracking my brain to figure out where in the math it happened at.
The code is supposed to be:
function factorial(num) local total = 1 while (num > 1) do print("total: " .. total .. " num: " .. num) total = total * num num = num - 1 end return total end
Running print(factorial(5)) afterwards comes out correctly with the total being returned as 120. Being curious I changed the code around to whats below:
function factorial(num) while (num > 1) do local total = 1 print("total: " .. total .. " num: " .. num) total = total * num num = num - 1 end return total end
After running print(factorial(5)) I got a return value of nil at the very bottom. From what I can see, because I moved the "local total = 1" into part of the while statement it simply kept the total at 1 the entire time. If I'm reading this correctly, after the while statement runs its course shouldn't I get a return value of 2 instead of nil at the end? Maybe my math is completely off.
Thanks! :)
-
Posted by jnwhiteh on Thu, 30 Jul 2009 22:28:26
The problem is variable scoping.. when you get to the end of the loop, the variable
total
no longer exists so your code just prints nil. Here's a simpler example with no loopslocal alpha = 3 -- Create a local variable holding '3' do -- Use the do statement to create a new block local beta = 7 -- This is a new local variable, but it only lives -- within the do block. When the block ends, it -- will no longer be available. print(alpha * beta) -- Print out 21 end -- End the do block print(alpha) -- Prints '3' print(beta) -- Prints 'nil'
Hope that makes sense! Experimentation is what this is al about, it's what I expect you to do =) Thanks for stopping by to ask a question!
-
Posted by lankus on Fri, 31 Jul 2009 03:33:15
That does make a lot more sense! So as long as a variable is created outside of the 'block', even though it is redefined within the block it can still carry outside of it?
function factorial(num)
local total = 1
while (num > 1) do
print("total: " .. total .. " num: " .. num)
total = total * num
num = num - 1
end
return total
end
In the original you can see
total
being defined a second time, except with nolocal
in front of it.Thanks for the response, it helped a ton! :)
edit: I think I just need to get a bit more familiar with the relationships that
local
has in the hierarchy of a code block. From what I think I understand if you don't mark something as local, it can continue to drill further down in the block ladder but can't climb it, and a local doesn't climb or go down the ladder but stays within the block it was placed. -
Posted by jnwhiteh on Mon, 10 Aug 2009 16:36:03
More importantly, if you don't mark something as local it becomes a global variable accessible ANYWHERE in your Lua program, or in any addon in the case of WoW. That's why it's important to make sure you know where you're putting your variables (and understand the scoping rules)