|
|
||
|
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
end
Maybe 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