codeconsole opened a new pull request, #3190:
URL: https://github.com/apache/groovy/pull/3190

   A memoized closure forwards calls to the closure it wraps, which is held in 
its `closure` field. `rehydrate` and `dehydrate` were inherited from `Closure`, 
so they replaced only the wrapper's own owner, delegate and this object. The 
wrapped closure kept the original ones:
   
   ```groovy
   class O { def foo() { 'o' } }
   class P { def foo() { 'p' } }
   def c = new O().with { o -> { x -> foo() + x } }
   c.rehydrate(null, new P(), new P()).memoize()(1)   // 'p1'
   c.memoize().rehydrate(null, new P(), new P())(1)   // 'o1'
   ```
   
   The same happens for `memoizeAtMost`, `memoizeAtLeast` and `memoizeBetween`, 
in 4.0.33, 5.0.8 and 6.0.0 too. A dehydrated `memoize()` closure could not be 
serialized, because the wrapped closure still referenced the owner.
   
   `MemoizeFunction` now overrides `dehydrate` and `rehydrate`. They dehydrate 
or rehydrate the wrapped closure and memoize the copy again. The copy gets an 
empty cache, since the cached values were computed against the old owner. To 
build that cache the same way, the memoized closure keeps the factory its cache 
came from: `Closure.memoize*` pass a serializable factory to new 
`Memoize.buildMemoizeFunction(Supplier, Closure)` and 
`Memoize.buildSoftReferenceMemoizeFunction(int, Supplier, Closure)` overloads. 
No existing signature changes. The soft-reference variant also keeps its 
protected cache size and gives the copy fresh protection storage and a fresh 
reference queue. The existing overloads that take a cache instance cannot build 
another one, so their copy shares the supplied cache; their Javadoc says so.
   
   This is the memoize counterpart of #3186 (GROOVY-12665), which does the same 
for curried, writable, composed and trampolined closures.
   
   ## Tests
   
   These fail without the change:
   - in `AbstractMemoizeTestCase`, for all four variants: 
`testRehydrateCallsTheRehydratedClosure`, `testRehydrateUsesTheNewDelegate` and 
`testDehydrateClearsTheMemoizedClosure`
   - in `MemoizeTest`: `testRehydratedCopyKeepsAnUnlimitedCache`, 
`testDehydratedCopySerializesAndRehydrates` and 
`testCopyOfClosureMemoizedWithSuppliedCacheSharesTheCache`
   - `MemoizeAtMostTest.testRehydratedCopyKeepsTheMaximumCacheSize`
   - `MemoizeBetweenTest.testRehydratedCopyKeepsTheCacheSizes`
   - `MemoizeAtLeastTest.testRehydratedCopyKeepsTheProtectedCacheSize` and 
`testCopyOfClosureMemoizedWithSuppliedCacheSharesTheCache`
   
   `org.codehaus.groovy.runtime.memoize.*`, `groovy.lang.*Closure*`, 
`groovy.*Closure*`, `groovy.*Memoize*` and `MemoizedASTTransformationTest` 
pass. The Checkstyle and CodeNarc gates pass.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to