WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Table iteration question (https://www.wowinterface.com/forums/showthread.php?t=49576)

Haleth 08-05-14 09:37 AM

Table iteration question
 
I was cleaning up some of my code when I noticed something that might be obvious, but I didn't realise before: Attempting to access variables that do not exist by iterating a table and calling functions on them does not result in any errors.

For example:

Lua Code:
  1. for k, v in pairs({ThisDoesNotExist, NorDoesThis}) do v:Show() end

This doesn't cause any errors.

Why is this? I find it rather counter-intuitive. I'm now going over all my code where I attempt to access global variables through tables and making sure I do a _G lookup by name instead - otherwise, I never know when one of the frames I'm trying to access no longer exists.

p3lim 08-05-14 09:42 AM

They do fail, only silently ;)

Lombra 08-05-14 09:49 AM

It doesn't work exactly like I think that you think it does. What happens here is, when the variables are nil, there will be no entry created in the table, and so, nothing to iterate over. If both of those are nil, it will simply be an empty table.

Resike 08-05-14 09:51 AM

Quote:

Originally Posted by Lombra (Post 294781)
It doesn't work exactly like I think that you think it does. What happens here is, when the variables are nil, there will be no entry created in the table, and so, nothing to iterate over. If both of those are nil, it will simply be an empty table.

Yep, the things inside the for loop wont even run, thats why there is no error.
However it's intresting, because you would expect that the pairs call would throw a nil error but it doesn't.
Probably there is a missing nil check in the pairs function, about it's intended or not i'm not sure.

Haleth 08-05-14 10:01 AM

I see, thank you.

It's easy enough if my table contains only single frames - I can make sure they exist by using a _G lookup by name.

What if I'm also trying to refer frames that are table values of those frames, though?

Let's say I have something like this:

Code:

for _, bu in pairs({BonusFrame.RandomBGButton, BonusFrame.Arena1Button, BonusFrame.Arena2Button}) do
        bu.SelectedTexture:SetDrawLayer("BACKGROUND")
        bu.SelectedTexture:SetTexture(r, g, b, .2)
        bu.SelectedTexture:SetAllPoints()
end

What would be the correct syntax to ensure that both BonusFrame and its child members actually exist and that my code is executed?

Tageshi 08-05-14 10:07 AM

How about to re-write like this?
Code:


local function job1(bu)
        bu.SelectedTexture:SetDrawLayer("BACKGROUND")
        bu.SelectedTexture:SetTexture(r, g, b, .2)
        bu.SelectedTexture:SetAllPoints()
end
job1(BonusFrame.RandomBGButton);
job1(BonusFrame.Arena1Button);
job1(BonusFrame.Arena2Button);


p3lim 08-05-14 10:11 AM

Or this:
Lua Code:
  1. for _, method in pairs({'RandomBGButton', 'Arena1Button', 'Arena2Button'}) do
  2.     local bu = BonusFrame[method]
  3.     bu.SelectedTexture:SetDrawLayer("BACKGROUND")
  4.     bu.SelectedTexture:SetTexture(r, g, b, .2)
  5.     bu.SelectedTexture:SetAllPoints()
  6. end

I do exactly this for disabling the textures for the stock OverrideActionBar in my action bar addon:
https://github.com/p3lim-wow/pAction...rd.lua#L58-L75

Sharparam 08-05-14 10:30 AM

Quote:

Originally Posted by Resike (Post 294783)
However it's intresting, because you would expect that the pairs call would throw a nil error but it doesn't.

Because there is no nil error in the call. {nil, nil} doesn't evaluate to nil, it evaluates to an empty table: {}. But since it has no values there is nothing to iterate over and the loop is "skipped".

Code:

> type({nil, nil})
'table'
> for _,_ in pairs(nil) do end
[string "local"]:1: bad argument #1 to 'pairs' (table expected, got nil)
> for _,_ in pairs({}) do end
> -- No output


Haleth 08-05-14 10:39 AM

Tageshi: That's a possibility, but it seems a little wasteful using function calls for what can be done using just table lookups.

p3lim: That's what I was looking for, thank you! Sometimes the solution is easier than you expect it to be. :)


All times are GMT -6. The time now is 02:41 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI