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

Reply via email to