|
Am 09.06.2013 20:35 schröbte Kevin Martin:
On 9 Jun 2013, at 18:42, Philipp Janda wrote:But then you need to maintain a set of valid userdata handles for each class to make it safe, or else: do local o1, o2 = class1.new(), class2.new() o1.udata, o2.udata = o2.udata, o1.udata end collectgarbage() collectgarbage() -- boomI don't understand the point of your example. udata is a private member of the object, not meant to be altered in Lua code (I tend to prefix with _). If you go and mess with it, then that's your fault, and so is the resultant crash.
I can't find a quote right now, but once there was this guarantee that you cannot crash a program from within Lua code. I find this guarantee very useful, so I try to make sure that my C modules follow this practice. (There are some unsafe modules, where this isn't possible: e.g. alien). Btw., a crash is only one possibility, stack/data/heap corruption would be even worse ...
With full userdata, I believe you have the same problem if someone does do local o1, o2 = class1.new(), class2.new() local o1_mt, o2_mt = getmetatable(o1), getmetatable(o2) o1_mt.__gc, o2_mt = o2_mt.__gc, o1_mt.__gc end
Only if you don't use luaL_checkudata in your __gc metamethods. In that case you only get a Lua error and some resource leaks, which leaves us with ...
Now, I think you can use the __metatable metamethod to stop this, but then you lose the ability to modify the metatable from Lua which loses a lot of flexibility.
Why would you want this flexibility in Lua code? You don't have direct access to the object from Lua anyway, so you need accessor methods for everything which breaks encapsulation. If you just want to add methods, you can put your index table into the __metatable field.
Philipp