Reputation: 450
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
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