What matters is whether the requirement to call the __close metamethod
on out of scope counts as the object being needed for normal
execution. Please just say yes:)
We can't reply yes or no to your statement which is not clear enough:
"counts as the object being needed for normal execution"
is very fuzzy, if it ever has a meaning (how does "a requirement counts" ?)
And if the object is needed for normal execution, then it should have a reference effectively used and really available at runtime. If there's no such reference, no possible access, then the object can be finalized at any time (but not at any predictable time, not even by trying to use an explicit call to the garbage collector, which may just do what is necessary for the program to continue working without being impacted by important shortage of resource, and may still use multiple passes to perform a "complete" garbage collection (which in most cases is just undesirable, as it would be very costly in CPU time and performance, freeing more objects than needed (and notably all weak references that are still useful for having efficient caches).
If you ever need an ordered finalization of any object in a predictable time, don't make your programe depend on finalizers (and don't make explicit calls to the garbage collector, which will seriously impact the performance of your application), but use explicit close()/free() methods and fix your program to use them (finalizers will just run as a last chance to limit the impact of resource leaks over some prolonged period of use), or remove all references (and let the garbage collector do his work only when it really needs to; you can still control separately the threshold limits that cause the garbage collector to run, and set tuning parameters for the free resources it must preserve or the maximum amount of unfinalized objects to maintain).
At best, calling the garbage collector explicitly should be done only in a stress test, to see how if your program still behaves correctly and does not hang or crash, in case of severe limitations of available resources, and does not also cause other running threads to stop working completely (allowing a possible denial of service attack, if your program is used to implement a network service accessible by third parties, forcing you to stop the program abruptly and restart it, possibly with the help of a watchdog timer or a time limit in the hosting server: note that an abrupt interruption will not allow any finalizer to run, so only basic resources will be freed, such as the total memory used by the Lua engine instance, or the file handles and other OS resources, or any open sockets... as a consequence this will be leaving any remote objects or storages in an inconsistant state, and will force your service to restart by first running a state check and a recovery cleanup or rollback process to repair the detected inconsistancies).
Every well-behaved program should explicitly declare (by a best effort) the resources it no longer needs at all, independantly of finalizers that are just helper guards to manage bugs in your program (resource leaks) forgetting to explicitly free these resources. Luya already is smart enough to automatically detect objects that are no longer in scope and without a secondary reference stored elsewhere in another accessible object.