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
>

Reply via email to