Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Destroy lua object by his method

Tags:

oop

lua

I want to destroy class instance by its own method. For example:

obj = Object()
obj:destroy()
type(obj) == nil

Object is implemented on C. Is it possible?

If it's not possible, Second way is:

_G["obj"] = nil
collectgarbage()

Thanks!

like image 819
Andrey Dyldin Avatar asked Jul 06 '12 09:07

Andrey Dyldin


People also ask

How do I destroy an object in Lua?

Lua does automatic memory management. A program only creates objects (tables, functions, etc.); there is no function to delete objects. Lua automatically deletes objects that become garbage, using garbage collection.

Does Lua have OOP?

OOP in Lua You can implement object orientation in Lua with the help of tables and first class functions of Lua. By placing functions and related data into a table, an object is formed.


3 Answers

I want to destroy class instance by its own method.

You should avoid this at all costs. Only expose an explicit destructor routine in Lua if you absolutely need to.

The correct way to handle this is to give your Lua C object a metatable with an __gc metamethod. This metamethod will be called right before Lua garbage collects the object.

If you absolutely must use an explicit destructor function (because you want the user to be able to release expensive resources immediately when they're done, without waiting for garbage collection), then you need to do two things:

  1. Do not require the user to explicitly destroy the object. That is, the object should be able to be destroyed either via destructor or via garbage collection.

  2. Do not break the object when it is explicitly destroyed. Every function that takes this object (member functions or free functions) needs to still work if the user called the explicit destruction function. Those functions may do nothing, which is fine. But the program shouldn't crash.

    Basically, your object needs to still be in an "alive" state when it was explicitly destroyed. You need to have the object be a zombie: alive, but not very useful. That way, your program will still function even if it doesn't do the right thing.

like image 68
Nicol Bolas Avatar answered Nov 15 '22 10:11

Nicol Bolas


Simple obj = nil in your example is enough. Note that you do not destroy content of object, you delete a reference that was in the variable obj, making real object somewhere in memory have one less reference and, if it reached 0 references, unreferenced an eligible for GC.

If your object doesn't have some external task to perform on destruction, that's pretty much all you need. Just lose all references by letting them go out of scope or overwriting variables/table members that contain those references with something else or nil. Otherwise you'd need to call object-specific destructor first and only then remove references.

It is not possible to make such a destructor automatically remove all references from everywhere, but at least it can clear object's internal state and set some internal flag that object is no longer usable or ready to be re-initialized.

like image 20
Oleg V. Volkov Avatar answered Nov 15 '22 09:11

Oleg V. Volkov


It is possible, to some degree. You can create a subtable within the object as a private data store. That subtable is managed solely by the object and therefore can only have one reference. If you define a destructor method for the object, then it would delete the respective subtable, making it eligible for garbage collection. Of course, the parent table would still exist, leaving only the methods which do not occupy any significant resources.

Whether this is "good design" is subjective. I am merely offering a solution for the question asked.

like image 44
Leslie Krause Avatar answered Nov 15 '22 09:11

Leslie Krause