[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: block-scope finalization
- From: Philipp Janda <siffiejoe@...>
- Date: Tue, 17 Nov 2015 17:50:36 +0100
Am 17.11.2015 um 15:01 schröbte Viacheslav Usov:
On Mon, Nov 16, 2015 at 6:28 PM, Philipp Janda <firstname.lastname@example.org> wrote:
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
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.