lua-users home
lua-l archive

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


Am 17.11.2015 um 15:01 schröbte Viacheslav Usov:
On Mon, Nov 16, 2015 at 6:28 PM, Philipp Janda <siffiejoe@gmx.net> wrote:

What about:

     local t = transaction( function( a, b, c )
       if c then c:destroy() end
       if b then b:clear() end
       if a then a:close() end
     end )
     local a = t( f() )
     local b = t( a:foo() )
     local c = t( b:bar() )
     -- do something with a, b, c
     -- ...
     t:commit() -- or t:rollback(), or t:cleanup()

No locals declared before initialization, and you could provide a default
rollback function that invokes `__gc` metamethods on all stored values
(although I find that rather ugly and unsafe).


I do not think I understand how that will work. I understand that the
transaction thing, when initialized, gets a finalizer, which is a function
of some arguments, and those arguments will be finalized. But how do you
specify which argument is which?

Currently I use customized (x)pcall functions like you suggested instead of (or actually in addition to) finalizers. Each call to one of those functions creates a stack of transactions, and `transaction()` pushes a transaction object to the current stack. A transaction is just a simple array, so `t( f() )` will append the value returned by `f()` to the array. When an error occurs, or when `t:rollback()` or `t:cleanup()` is called, the elements are `unpack()`ed and passed to the cleanup function (so the order of the arguments and the `t()` calles must match). `t:commit()`/`t:rollback()` pop the transaction from the stack (if it's the most recent).

You can see the current state of my experiments here[1].


Cheers,
V.


Philipp

  [1]:  https://gist.github.com/siffiejoe/2c01b690bfdbc34b85a6