IsawU
IsawU

Reputation: 450

Lua 5.1.4 Handing data(not the handle) from table(array) to function

I'm working on a script in Lua 5.1.4 with function that uses tables as arguments. My problem is that whenever I call the function with table as argument it actually passes the handle of the table instead of the data.

I made a simple script to make it easier for me to explain this...

function test(a)
    a[2]="not something"
    return a
end

alpha={"hello","something"}
bravo=test(alpha)

print(alpha[2])
print(bravo[2])

returns

not something

not something

From this example it is clear that a is the same handle as alpha so table alpha gets changed, but I would somehow like to preserve the original value of alpha(in this example).

I have some ideas but it would make the function bigger and slower so I want to know if there is an easy way to do this. It is important to mention that my tables are not fixed length and are quite big.

Upvotes: 1

Views: 138

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473212

You would have to make a copy of the table. This means walking through the table and copying every single value.

Of course, if one of those values itself is a table, then you need to make a copy of that table. Recursively. Also, if one of the tables is referenced twice, you should reference your copy twice, instead of making a new copy.

If a table uses a metatable... well, you can't really be sure how to copy that at all. The values you use pairs to iterate over may not even be real values.

And copying functions is difficult, because they often have upvalues that would need to be copied to make a true copy of the function. Copying userdata is impossible without knowing what C function to call to copy it (if there is even an API for doing so).

If this sort of manipulation is a problem, then you should write your functions to avoid this problem, rather than copy tables.

The way to do this is to treat tables taken as parameters as immutable. You can look, but not touch. Instead, have the function return values; this leaves it up to the caller's discretion to decide where to store them. Note that self should be excluded from this, since you probably want a conceptual member function to be able to modify the object it's being called on.

In short, this is a design problem.

Upvotes: 2

Related Questions