WoWInterface

WoWInterface (http://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (http://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Calling a local function from another local funtion (http://www.wowinterface.com/forums/showthread.php?t=45456)

gmarco 12-17-12 12:08 AM

Calling a local function from another local funtion
 
1 Attachment(s)
Hi all,

I'd like to ask why a code like this will produce exit with an error like unable to find global b():

Lua Code:
  1. local function a()
  2. -- code
  3.  
  4. end
  5.  
  6.  
  7. local function b()
  8. -- code
  9.  
  10. end
  11.  
  12.  
  13. local function c()
  14. -- code
  15.  
  16. b()
  17.  
  18. end

This because if I change my functions to local: RemGank_Validate_DB, RemGank_Check_Player, RemGank_Add_Player and RemGank_Record_Player

this doesn't work anymore:


Lua Code:
  1. -- code
  2.  
  3. local function RemGank_Record_Player(name, note)   
  4.  
  5.     if note == nil or note == "" then  note = default_note end
  6.  
  7.     RemGank_Validate_DB(name)
  8.  
  9.     RemGankDB[name]["name"] = name:lower()
  10.     RemGankDB[name]["desc"] = string.sub(note,1,25)
  11.     RemGankDB[name]["lastloc"] = GetZoneText() .. "/" .. GetSubZoneText() .. " - " .. date("%d.%m.%Y %H:%M:%S")
  12.     RemGankDB[name]["nrkill"] = ( RemGankDB[name]["nrkill"] + 1 )  
  13.    
  14.     print(string_format("%s: adding %s [ %s ] [ kills: %i ] ", prgname, name, note, RemGankDB[name]["nrkill"]))
  15.    
  16. end
  17.  
  18. local function RemGank_Validate_DB(name)
  19.     RemGankDB[name] = RemGankDB[name] or {}
  20.     RemGankDB[name]["name"] = RemGankDB[name]["name"] or {}
  21.     RemGankDB[name]["desc"] = RemGankDB[name]["desc"] or {}
  22.     RemGankDB[name]["lastloc"] = RemGankDB[name]["lastloc"] or {}
  23.     RemGankDB[name]["nrkill"] = RemGankDB[name]["nrkill"] or 0
  24. end
  25.  
  26. -- code


If I declare them not local everything works.

I'll attach the full code if someone wants to check it.

As usual thanks in advance to everyone.

Phanx 12-17-12 01:23 AM

Your example a/b/c code will work fine, because the "b" function is defined before you try to call it in the "c" function. Your real code will not work fine, because your "RemGank_Validate_DB" function is not defined before you try to call it in your "RemGank_Record_Player" function.

You have two options:

1. Define the functions in the proper order so that each one is defined before you try to call it:

Code:

local function A() print("A") end -- create this first
local function B() return A() end -- before you call it here

2. Define all of the locals first, and then set their values in whatever order:

Code:

local A, B

function B() return A() end
function A() print("A") end

However, if you only call "RemGank_Validate_DB" from "RemGank_Record_Player" you should just get rid of the whole "RemGank_Validate_DB" function, and just put its code directly in the "RemGank_Record_Player" function.

Better yet, you should just validate your DB once when your addon loads, instead of every time you add a record.

gmarco 12-17-12 01:06 PM

Hi Phanx,

As usual thanks for the reply.

Lua Code:
  1. function RemGank_Record_Player(name, note) 
  2.  
  3.     if note == nil or note == "" then  note = default_note end
  4.    
  5.     -- Define the new row in the array
  6.     RemGankDB[name] = RemGankDB[name] or {}
  7.    
  8.     -- not mandatory to be initialized anymore.
  9.     -- RemGankDB[name]["name"] = RemGankDB[name]["name"] or {}
  10.     -- RemGankDB[name]["desc"] = RemGankDB[name]["desc"] or {}
  11.     -- RemGankDB[name]["lastloc"] = RemGankDB[name]["lastloc"] or {}
  12.    
  13.     -- To prevent the math err on the sum of ( nil + 1 ) below
  14.     RemGankDB[name]["nrkill"] = RemGankDB[name]["nrkill"] or 0
  15.  
  16.     RemGankDB[name]["name"] = name:lower()
  17.     RemGankDB[name]["desc"] = string.sub(note,1,25)
  18.     RemGankDB[name]["lastloc"] = GetZoneText() .. "/" .. GetSubZoneText() .. " - " .. date("%d.%m.%Y %H:%M:%S")
  19.     RemGankDB[name]["nrkill"] = ( RemGankDB[name]["nrkill"] + 1 )  
  20.    
  21.     print(string_format("%s: adding %s [ %s ] [ kills: %i ] ", prgname, name, note, RemGankDB[name]["nrkill"]))
  22.    
  23. end


Studying better my code I finally realized that I don't need the commented out part.

The line 6 is mandatory as you explained me some messages ago :-) and the 14 is to prevent a math error when trying to add a nil + 1 few lines after.

Quote:

Better yet, you should just validate your DB once when your addon loads, instead of every time you add a record.
This is the part I could not understand how to accomplish.
This because the only way I think I could do is something like :

Lua Code:
  1. if event == "ADDON_LOADED" and arg1 == "Remgank" then
  2.        
  3.         --- other code
  4.  
  5.         for name in pairs(RemGankDB) do
  6.             RemGankDB[name] = RemGankDB[name]
  7.         end
  8.     end

But I have to add the same 2 lines (6 and 14 of the first sample) in the RemGank_Record_Player to prevent an error when RemGankDB[name] is nil ( adding a new player not yet in the DB ) .

So I don't find any utility in use that for ... end in the ADDON_LOADED event.

I am sorry if this message is not so clear but it is not easy for me to explain better.

Thanks again for your time.

Phanx 12-17-12 04:04 PM

This literally does nothing:

Code:

for name in pairs(RemGankDB) do
    RemGankDB[name] = RemGankDB[name]
end

It just spends CPU cycles going through the database and saying "set this key to the same value it alread has". At the end of the loop absolutely nothing has actually been done.

If your database only contains name=data pairs, and not any other settings, then this is all the initialization you need to make sure it is defined as a table the first time your addon runs:

Code:

RemGankDB = RemGankDB or {}
Then, when adding a name, you will need to keep this check:

Code:

RemGankDB[name] = RemGankDB[name] or {}
It would not make sense to do anything with names at load because you do not know, in advance, the names of players who are going to kill you.


All times are GMT -6. The time now is 05:52 AM.

vBulletin © 2014, Jelsoft Enterprises Ltd
©2012 ZAM Network LLC