1. 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! :)

    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 loops

     local 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!

    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 no local 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.

    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)