1
votes

The below code works:

local randomPick = {
    currentPick = 'N/A',
    pickNode = function(self)
        randomPick = node.random(1, table.getn(availableNodes));
        self.currentPick = availableNodes[randomPick];
        return self.currentPick
    end
};

local sentF = function(port, ip, data)
    print('Sent info to ' .. randomPick.currentPick);
end

But If I assign the values after I declare randomPick, I get an error:

local randomPick = {};
randomPick.currentPick = 'N/A';
randomPick.pickNode = function(self)
        randomPick = node.random(1, table.getn(availableNodes));
        self.currentPick = availableNodes[randomPick];
        return self.currentPick
    end

local sentF = function(port, ip, data)
    print('Sent info to ' .. randomPick.currentPick);
end

This does not work and throws out this error. Why is the function picking up an empty randomPick when I assign values to those 2 members?

PANIC: unprotected error in call to Lua API (attempt to index upvalue '?' (a number value))

2
Show where's the call to function that's failing. Assuming you're talking about sentF, it should work either way: ideone.com/0MduyQ Probably you're getting the function in question called before you get randomPick filled. Or maybe there's a silly typo. - Vlad

2 Answers

3
votes

You create a local table randomPick.

Once you call randomPick.pickNode you overwrite the table randomPick with a random number value.

If you then call setnF you'll index local upvalue randomPick which is a number.

3
votes
local randomPick = {};
randomPick.currentPick = 'N/A';
randomPick.pickNode = function(self)
   local randomPick = node.random(1, table.getn(availableNodes));
   self.currentPick = availableNodes[randomPick];
   return self.currentPick
end

local function sentF(port, ip, data)
    print('Sent info to ' .. randomPick.currentPick);
end

That should fix it; the problem is that you're using randomPick twice without declaring a new local, so you're just overwriting your variable.

The moment you call pickNode, it sets randomPick to a new value and when you then attempt to index it, you get an error because it's now a number.

The question you should be asking is why it even worked in the first example, and it's that the local isn't in scope until after the assignment, so the function doesn't see it as a local and thus tries to access it as a global.

What happens is something like this:

local function f(self)
   -- randomPick isn't a local variable yet, so the function is compiled
   -- to use _ENV.randomPick at this point
   randomPick = node.random(1, table.getn(availableNodes));
   self.currentPick = availableNodes[randomPick];
   return self.currentPick
end

local randomPick = {};
-- Local randomPick is introduced here, shadowing the global _ENV.randomPick
randomPick.currentPick = 'N/A'
randomPick.pickNode = f

local function sentF(port, ip, data)
    print('Sent info to ' .. randomPick.currentPick);
end