Is it accurate to rephrase your goal as snapshotting some variable-per-scenario current state, running code, and then rolling back any changes to the snapshot?
On Sat, Nov 21, 2020 at 8:02 PM MG <mg...@arscreat.com> wrote: > > Hi Eric, > > do these references (it seems you do not need to open the can of worms that > is deep copying in your problem) you need to save/restore reside in a single > class, or could such a class be introduced (maybe in a generic manner) ? I am > unclear how wide the different scenarios are here you want to solve in a > generic manner... > > Cheers, > mg > > > On 22/11/2020 02:03, Milles, Eric (TR Technology) wrote: > > Thanks for the reply. So if I use an AutoCloseable, I would have something > like: > > > > class Foo { > > private state > > def bar() { > > def temp = state > > state = newState > > try ({ -> state = temp } as AutoCloseable) { // or rewrite this line > using withCloseable > > baz() > > } > > } > > } > > > > In my case, Foo is something that visits the elements of a tree or list. I > don't want to create a new instance to visit each element. bar represents a > method that advances to the next element and baz (maybe from super type) > processes the next element set in "state". state is a field or property so I > am expecting the assignments to live inside the bar method's scope. > > > > My goal is to eliminate repetitious typing of assigning the current value to > a temporary variable, assigning the next value to the field and at the end > restoring the previous value. > > > > > > From: Leo Gertsenshteyn <leo...@gmail.com> > Sent: Saturday, November 21, 2020 5:34 PM > To: dev@groovy.apache.org > Subject: Re: Alternatives to try/finally code structure > > > > Hi Eric, > > > > Am I correctly interpreting that baz() in the above examples calls into 3rd > party code and that code has direct reference to the state and controls the > state variables' lifecycle? If that's not the case, there may much much > simpler solutions involving intermediate objects, recursion, etc., but I will > assume those are not available to you. > > > > In that case, these look like scenarios for which Java's "try-with-resources" > was meant to reduce verbosity. It allows a try block to take objects that > implement the AutoCloseable interface and it will call their "close()" > methods at the end of the block -- no "finally" needed. > > > > In Groovy, we can leverage that with ".withCloseable { ... }" closure blocks. > Here's an example script: > > > > class Foo implements AutoCloseable { > > Foo { > > // set up state as needed > > println("Opened a Foo!") > > } > > > > @Override > > void close() throws Exception { > > // tear down state as needed > > println("Closed a Foo!") > > } > > } > > def main() { > > new Foo().withCloseable { > > // baz() > > println("Hello!") > > } > > } > > > > main() > > > > Cheers, > > Leo > > > > On Sat, Nov 21, 2020 at 11:29 AM Milles, Eric (TR Technology) > <eric.mil...@thomsonreuters.com> wrote: > > Groovy Devs, > > > > I have been pondering how to automate the writing of try/finally blocks used > to unconditionally restore object state. Does anyone know of a Groovier way > to do something like this before I pursue a macro method, an AST > transformation, or something more involved? It currently requires a lot of > typing to do this. > > > > Scenario 1: stack-ify a scalar field/property -- often used when traversing a > list or tree and "state" is the current element > > > > class Foo { > > private state > > def bar() { > > def temp = state // may be any number of fields saved to temp vars > > state = newState > > try { > > baz() > > } finally { > > state = temp > > } > > } > > def baz() { > > // make use of state; does not require previous values > > } > > } > > > > Scenario 2: mutation rollback -- similar but "state" is not written to > beforehand > > > > class Foo { > > private state > > def bar() { > > def temp = state // may be any number of fields saved to temp vars > > try { > > baz() > > } finally { > > state = temp > > } > > } > > def baz() { > > // modifies state > > } > > } > > > > Note: "state" is not always convertible into a java.util.Stack. Sometimes > this is 3rd-party code that is being extended. > > > > > > > > I was thinking of something like this so as not to overload the try keyword: > > > > class Foo { > > def bar() { > > push (field1 = value, field2) { // AST would be re-written to try/finally > like Scenario 1/2 > > baz() > > } > > } > > ... > > } > > > > This e-mail is for the sole use of the intended recipient and contains > information that may be privileged and/or confidential. If you are not an > intended recipient, please notify the sender by return e-mail and delete this > e-mail and any attachments. Certain required legal entity disclosures can be > accessed on our website: > https://www.thomsonreuters.com/en/resources/disclosures.html > > -- Christopher Smith