lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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 order
to 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