mike bayko
mike bayko

Reputation: 385

Lua is it possible to return a reference to an element inside of a table?

Lets say that I have a simple table, this table has another table inside of it that contains other values. For simplicity here is the layout:

local a = {b = {X = 123; Y = 321; Z = 456;}};

I have a function that is supposed to return a reference to the given value in the table a.b.

local function GetRef(member)
    --return a reference to a.b[member]
end

The reason I need to call GetRef is because another function that calls it needs to be able to assign a new value to the supplied value inside of the table:

local function AssignValue(key, value)
    local ref = GetRef(key);
    ref = value;
end

Now you could ask "why dont you just return a.b, and type ref[key] to assign it in the assign function instead?", and I could do that, however I wouldn't be learning anything new if I did just decide to implement what I am trying to implement that way now would I?

I would appreciate any help.

Thanks

Upvotes: 1

Views: 3696

Answers (2)

Vlad
Vlad

Reputation: 5857

It's not entirely correct to say that Lua has no references.

Actually, every variable stores reference to some value. Internally there's shortcuts, allowing Lua to store simple values directly in variable instead of referencing it, but you can't check if that's true from Lua side, and it's not important.

What's important is that assigning new value to a variable only changes reference stored in a variable. It's much like with Java - variables of any object type is a reference, and passed by value in functions/methods. So you can't change the value by assigning something to a variable, you can only reference some different value.

As a consequence, to change already stored value you must explicitly mutate it. Most of Lua types are immutable (numbers/booleans/strings), that leaves only tables, threads and closures as a subjects for possible changes. And that means you must store the value you want to mutate.

Going with your example, you can't change table's content by referencing some value stored inside. If you stored value 321 (Y index) in a local ref variable, you can't mutate it, since numbers are immutable. Assigning something new to ref variable would only reference different value. You must store b table's value in order to be able to assign new values under some index, and you need to store also that index (or full path, as @lhf already suggested).

Upvotes: 1

lhf
lhf

Reputation: 72402

There are no references to values in Lua.

But you can use upvalues:

local function AssignValue(key, value)
    a.b[key] = value
end

If you want to do that for several tables, try

function makeSetPath(t)
    return function (key,value) t[key]=value end
end

AssignValue = makeSetPath(a.b)

Upvotes: 2

Related Questions