Schematically, the workflow looks like this
object = Klass.new
proxy = transaction.wrap(object)
# From this point on, +proxy+ behaves like +object+. Though,
# changes that are made to +proxy+ are "registered" and
# will be applied later on +object+
# Among other things, +proxy+ can be captured by blocks
event.on { proxy.start! }
# The issue is that the code that modify +proxy+ should *not*
# have to know if +proxy+ is a transaction proxy or a "normal"
# object.
# Apply on +object+ the modifications that have been registered
# on +proxy+. We now want the blocks to call methods on +object+
# and not on +proxy+ anymore
transaction.commit
-----------------
The relevant part of #commit looks like:
proxy.commit_transaction # apply changes back to +object+
delegate = Delegate.new(object)
Kernel.swap! proxy, delegate
# From now on, the VALUE of 'proxy' is now the delegate and the VALUE
# of 'delegate' is actually the proxy. I.e. calls on +proxy+ from blocks
# created in the transaction are now forwarded to +object+.
------------------
Another solution I though about: making +proxy+ a dynamic delegate which
points to the actual "proxy" instance until the transaction is committed,
and to the actual object afterwards. No good IMO, since some methods on the
proxy/object return self, one can access instances that have attributes pointing
back to the proxy and so on (so, handling it transparently would be
quite complex).
Sylvain
--
--- !ruby/object:MailingList
name: rubinius-dev
view: http://groups.google.com/group/rubinius-dev?hl=en
post: [email protected]
unsubscribe: [email protected]