Thread Tools Display Modes
01/31/15, 04:15 PM   #1
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,963
Problem with local variable (it is NIL all of sudden)?

Hey developers,

I got a problem with a source code.
Inside my function I use the :GetName() ESO LUA function to get the name of a control.
The name is stored inside the local (only known inside my function) variable "equipmentMarkerControlName"
I'll then determine the digits at the end of the string and remove them.
This works without any problems and the variable will store the new string afterwards, without trailing digits. I know there might be simpler ways to strip the trailing digits in this string but I'm not really well in using RegEx :-(

Afterwards I will use a loop to read an array (markedIcons) and if the iconid from the array differs from a function's parameter (markerId) I try to write the variable "equipmentMarkerControlName" to the chat again.
But it is NIL again here all of sudden? Why?

Lua Code:
  1. --Are we adding a tooltip to an equipment slot?
  2.         if pUpdateAllEquipmentTooltips then
  3.             --Get current controls name
  4.             local equipmentMarkerControlName = markerControl:GetName()
  5.             --Get the offset for the ending digit(s)
  6.             local replaceEnd = string.len(equipmentMarkerControlName) - locVars.gFCOMaxDigitsForIcons     -- locVars.gFCOMaxDigitsForIcons = 1
  7.             --Remove the ending number
  8.             equipmentMarkerControlName = string.sub(equipmentMarkerControlName, 1, replaceEnd)
  9.             d("name: " .. equipmentMarkerControlName)
  10.         end
  11.  
  12.         --Check if the item is marked with several icons
  13.         local markedIcons = {}
  14.         local bagId, slotIndex = MyGetItemDetails(markerControl:GetParent())
  15.         _, markedIcons = FCOIsMarked(GetItemInstanceId(bagId, slotIndex), -1)
  16.         for iconId, iconIsMarked in pairs(markedIcons) do
  17.             if iconIsMarked then
  18.                 markedCounter = markedCounter + 1
  19.                 if markedCounter > 1 then
  20.  
  21. --The variable will be NIL inside this FOR loop, but why?
  22.                 if iconId ~= markerId and pUpdateAllEquipmentTooltips then
  23.                     if equipmentMarkerControlName ~= "" then
  24.                     d("bla: " .. tostring(equipmentMarkerControlName))
  25.                     else
  26.                     d("blubb")
  27.                     end
  28.                 end
  29.             end
  30.         end

Chat output will be:
Lua Code:
  1. name: ZO_CharacterEquipmentSlotsRing2FCOIS
  2. bla: nil
  3. bla: nil

The function will be called once!
For the given example the loop at array "markedIcons" generated 2 chat output rows, because iconIsMarked was true 2 times.

I can't see why this variable is NIL. It should contain the string ZO_CharacterEquipmentSlotsRing2FCOIS :-(

If I declare the variable "equipmentMarkerControlName" as global it works all of sudden.
But why do I have to declare a variable global which I'm using locally inside the same function???
Is is because I'm using a global function (FCOIsMarked(...)) inside my function? I don't think so...

Thanks for your help.
  Reply With Quote
01/31/15, 06:31 PM   #2
katkat42
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 155
Your local variables are local to within that "if...end" statement. Once you pass that "end" your variables go out of scope. If you want them to be local to within the file, you need to declare them before the if statement:

Lua Code:
  1. local equipmentMarkerControlName, replaceEnd
  2. --Are we adding a tooltip to an equipment slot?
  3.         if pUpdateAllEquipmentTooltips then
  4.             --Get current controls name
  5.             equipmentMarkerControlName = markerControl:GetName()
  6.             --Get the offset for the ending digit(s)
  7.             replaceEnd = string.len(equipmentMarkerControlName) - locVars.gFCOMaxDigitsForIcons     -- locVars.gFCOMaxDigitsForIcons = 1
  8.             --Remove the ending number
  9.             equipmentMarkerControlName = string.sub(equipmentMarkerControlName, 1, replaceEnd)
  10.             d("name: " .. equipmentMarkerControlName)
  11.         end
  12.  
  13.         --Check if the item is marked with several icons
  14.         local markedIcons = {}
  15.         local bagId, slotIndex = MyGetItemDetails(markerControl:GetParent())
  16.         _, markedIcons = FCOIsMarked(GetItemInstanceId(bagId, slotIndex), -1)
  17.         for iconId, iconIsMarked in pairs(markedIcons) do
  18.             if iconIsMarked then
  19.                 markedCounter = markedCounter + 1
  20.                 if markedCounter > 1 then
  21.  
  22. --The variable will be NIL inside this FOR loop, but why?
  23.                 if iconId ~= markerId and pUpdateAllEquipmentTooltips then
  24.                     if equipmentMarkerControlName ~= "" then
  25.                     d("bla: " .. tostring(equipmentMarkerControlName))
  26.                     else
  27.                     d("blubb")
  28.                     end
  29.                 end
  30.             end
  31.         end
  Reply With Quote
01/31/15, 07:58 PM   #3
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Hey Baertram, here is what I see. I made some comments on your code with minor fixes showing the problems I see.


Your code with comments:
Warning: Spoiler

Last edited by circonian : 01/31/15 at 10:57 PM.
  Reply With Quote
01/31/15, 08:47 PM   #4
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,963
Thx for the information katkat42 and circonian.

I didn't know that variables declared inside an if...end part won't be accessible outside this part.
Other developing languages, other rules

And about your suggestions:

Thx, but the variable equiptmentMarkerControlName will be always the same. This is why I had filled it outside the for...do loop so it won't be overwritten with the same stuff over and over (8 times in total sometimes) again.

And thank you for the "leaking to global" tip as well. I thought this _ was intended to be that local dummy, coming from LUA itsself.
Or is it just a normal variable and someone has named it _, but it has nothing to do with LUA itsself?

Last edited by Baertram : 01/31/15 at 09:04 PM.
  Reply With Quote
01/31/15, 08:56 PM   #5
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by Baertram View Post
Thx for the information circonian.

I didn't know that variables declared inside an if...end part won't be accessible outside this part.
Other developing languages, other rules

And about your suggestions:

Thx, but the variable equiptmentMarkerControlName will be always the same. This is why I had filled it outside the for...do loop so it won't be overwritten with the same stuff over and over (8 times in total sometimes) again.

And thank you for the "leaking to global" tip as well. I thought this _ was intended to be that local dummy, coming from LUA itsself.
Or is it just a normal variable and someone has named it _, but it has nothing to do with LUA itsself?
Doh yeah your right, it is the same everytime, didn't notice that.

its just a variable, just like naming something x or markerId. You can assign things to it like
Lua Code:
  1. local _ = 4
  2. d(_)
  3. -- output: 4

I guess its just typically used for "unwanted" things because it is small, easy to identify (hard to mix it up with anything else), and naming it unwantedReturnValue or something would just cluter up code. _ is nice and small & easy to ignore.
  Reply With Quote
01/31/15, 09:03 PM   #6
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,963
Ok, thanks for the next explanation ;-)
  Reply With Quote
02/01/15, 05:13 AM   #7
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Two small tips:

1) to strip N characters from the end, you can use negative end index:
Lua Code:
  1. s = s:sub(1, -1-N)

2) to strip all digits from the end, you can use pattern replacement:
Lua Code:
  1. s = s:gsub("%d+$", "")

edit: fixed calls, guess my Lua is waning

Last edited by merlight : 02/01/15 at 05:19 AM.
  Reply With Quote
02/01/15, 11:25 AM   #8
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,963
Thx merlight, didn't know the negative index works. This is pretty faster then, great!
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » Problem with local variable (it is NIL all of sudden)?


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off