|
Am 16.11.2015 um 12:47 schröbte Viacheslav Usov:
On Fri, Nov 13, 2015 at 5:16 PM, Soni L. <fakedme@gmail.com> wrote:Where using() runs the function in a coroutine and hooks errors in orderto finalize the font. This is very clever, but: 1. As already commented here, running the entire garbage collector, twice, is expensive. 2. It is fairly common, as in the LuaSQL example, that such scoped objects depend on each other. With C#'s using, one can write code such as using (var a = f(), b = a.foo(), c = b.bar()) { ... } The important part of that is that if, for example, foo() or bar() throws an exception, then everything in the parentheses that was instantiated before the exception will be finalized. With the proposed 'block' keyword, that would also be a natural outcome.
If Lua had a hook that is called whenever an error is about to be thrown, you could do something like the following:
do local destructors local function error_hook() local d = destructors destructors = {} for i = #d, 1, -1 do d[ i ]() end end function on_error( f ) debug.sethook( error_hook, "e" ) local n = #destructors+1 destructors[ n ] = function( ... ) destructors[ n ] = nil return f( ... ) end return destructors[ n ] end end do local a, b, c local cleanup = on_error( function() if c then c:destroy() end if b then b:clear() end if a then a:close() end end ) a = f() b = a:foo() c = b:bar() -- do something with a, b, c -- ... cleanup() -- run cleanup function if no error has been thrown endMaybe that would be good enough (and I think it is relatively easy to implement). A yield hook would probably be useful as well ...
[...] Cheers, V.
Philipp