Groovy Documentation

## groovy.lang
[Java] Class Closure

    java.lang.Object
      groovy.lang.GroovyObjectSupport
          groovy.lang.Closure

All Implemented Interfaces:
  java.lang.Cloneable, GroovyCallable, java.lang.Runnable, java.io.Serializable

    public abstract class Closure
    extends GroovyObjectSupport

Represents any closure object in Groovy.

Groovy allows instances of Closures to be called in a short form. For example:

     def a = 1
     def c = { a }
     assert c() == 1

To be able to use a Closure in this way with your own subclass, you need to provide a doCall method with any signature you want to. This ensures that getMaximumNumberOfParameters() and getParameterTypes() will work too without any additional code. If no doCall method is provided a closure must be used in its long form like

     def a = 1
     def c = {a}
     assert c.call() == 1

Authors:
  James Strachan
  John Wilson
  Jochen Theodorou
  Graeme Rocher
  Paul King

Version:
  \$Revision\$

Field Summary
`static int` | `DELEGATE_FIRST` With this resolveStrategy set the closure will attempt to resolve property references to the delegate first then the owner.
`static int` | `DELEGATE_ONLY` With this resolveStrategy set the closure will resolve property references to the delegate only and entirely bypass the owner.
`static int` | `DONE`
`static Closure` | `IDENTITY`
`static int` | `OWNER_FIRST` With this resolveStrategy set the closure will attempt to resolve property references to the owner first, then the delegate (this is the default strategy).
`static int` | `OWNER_ONLY` With this resolveStrategy set the closure will resolve property references to the owner only and not call the delegate at all.
`static int` | `SKIP`
`static int` | `TO_SELF` With this resolveStrategy set the closure will resolve property references to itself and go through the usual MetaClass look-up process.
`protected int` | `maximumNumberOfParameters`
`protected java.lang.Class[]` | `parameterTypes`

Constructor Summary
`Closure(java.lang.Object owner, java.lang.Object thisObject)`
`Closure(java.lang.Object owner)` Constructor used when the "this" object for the Closure is null.

Method Summary
`Closure` | `asWritable()`
`java.lang.Object` | `call()` Invokes the closure without any parameters, returning any value if applicable.
`java.lang.Object` | `call(java.lang.Object... args)`
`java.lang.Object` | `call(java.lang.Object arguments)` Invokes the closure, returning any value if applicable.
`java.lang.Object` | `clone()`
`Closure` | `curry(java.lang.Object... arguments)`
`Closure` | `curry(java.lang.Object argument)`
`Closure` | `dehydrate()`
`java.lang.Object` | `getDelegate()`
`int` | `getDirective()`
`int` | `getMaximumNumberOfParameters()`
`java.lang.Object` | `getOwner()` @return the owner Object to which method calls will go which is typically the outer class when the closure is constructed
`java.lang.Class[]` | `getParameterTypes()`
`java.lang.Object` | `getProperty(java.lang.String property)`
`int` | `getResolveStrategy()` Gets the strategy which the closure users to resolve methods and properties
`java.lang.Object` | `getThisObject()`
`boolean` | `isCase(java.lang.Object candidate)`
`Closure` | `leftShift(Closure other)`
`java.lang.Object` | `leftShift(java.lang.Object arg)`
`Closure` | `memoize()`
`Closure` | `memoizeAtLeast(int protectedCacheSize)` Creates a caching variant of the closure with automatic cache size adjustment and lower limit on the cache size.
`Closure` | `memoizeAtMost(int maxCacheSize)`
`Closure` | `memoizeBetween(int protectedCacheSize, int maxCacheSize)` Creates a caching variant of the closure with automatic cache size adjustment and lower and upper limits on the cache size.
`Closure` | `ncurry(int n, java.lang.Object... arguments)`
`Closure` | `ncurry(int n, java.lang.Object argument)`
`Closure` | `rcurry(java.lang.Object... arguments)`
`Closure` | `rcurry(java.lang.Object argument)`
`Closure` | `rehydrate(java.lang.Object delegate, java.lang.Object owner, java.lang.Object thisObject)` Returns a copy of this closure for which the delegate, owner and thisObject are replaced with the supplied parameters.
`Closure` | `rightShift(Closure other)`
`void` | `run()`
`void` | `setDelegate(java.lang.Object delegate)`
`void` | `setDirective(int directive)`
`void` | `setProperty(java.lang.String property, java.lang.Object newValue)`
`void` | `setResolveStrategy(int resolveStrategy)` Sets the strategy which the closure uses to resolve property references.
`protected static java.lang.Object` | `throwRuntimeException(java.lang.Throwable throwable)`
`Closure` | `trampoline(java.lang.Object... args)` Builds a trampolined variant of the current closure.
`Closure` | `trampoline()`

Methods inherited from class GroovyObjectSupport
getMetaClass, getProperty, invokeMethod, setMetaClass, setProperty

Methods inherited from class java.lang.Object
java.lang.Object#wait(long), java.lang.Object#wait(long, int), java.lang.Object#wait(), java.lang.Object#equals(java.lang.Object), java.lang.Object#toString(), java.lang.Object#hashCode(), java.lang.Object#getClass(), java.lang.Object#notify(), java.lang.Object#notifyAll()

Field Detail

### DELEGATE_FIRST

    public static final int DELEGATE_FIRST

  With this resolveStrategy set the closure will attempt to resolve property references to the delegate first then the owner. For example the following code :

       class Test {
           def x = 30
           def y = 40

           def run() {
               def data = [ x: 10, y: 20 ]
               def cl = { y = x + y }
               cl.delegate = data
               cl.resolveStrategy = Closure.DELEGATE_FIRST
               cl()
               println x
               println y
               println data
           }
       }

       new Test().run()

  will output :

       30
       40
       [x:10, y:30]

  because the x and y variables declared in the delegate shadow the fields in the owner class.

  Note that local variables are always looked up first, independently of the resolution strategy.

### DELEGATE_ONLY

    public static final int DELEGATE_ONLY

  With this resolveStrategy set the closure will resolve property references to the delegate only and entirely bypass the owner. For example the following code :

       class Test {
           def x = 30
           def y = 40
           def z = 50

           def run() {
               def data = [ x: 10, y: 20 ]
               def cl = { y = x + y + z }
               cl.delegate = data
               cl.resolveStrategy = Closure.DELEGATE_ONLY
               cl()
               println x
               println y
               println data
           }
       }

       new Test().run()

  will throw an error because even if the owner declares a "z" field, the resolution strategy will bypass lookup in the owner.

  Note that local variables are always looked up first, independently of the resolution strategy.

### DONE

    public static final int DONE

### IDENTITY

    public static final Closure IDENTITY

### OWNER_FIRST

    public static final int OWNER_FIRST

  With this resolveStrategy set the closure will attempt to resolve property references to the owner first, then the delegate (this is the default strategy). For example the following code :

       class Test {
           def x = 30
           def y = 40

           def run() {
               def data = [ x: 10, y: 20 ]
               def cl = { y = x + y }
               cl.delegate = data
               cl()
               println x
               println y
               println data
           }
       }

       new Test().run()

  will output :

       30
       70
       [x:10, y:20]

  because the x and y fields declared in the Test class the variables in the delegate.

  Note that local variables are always looked up first, independently of the resolution strategy.

### OWNER_ONLY

    public static final int OWNER_ONLY

  With this resolveStrategy set the closure will resolve property references to the owner only and not call the delegate at all. For example the following code :

       class Test {
           def x = 30
           def y = 40

           def run() {
               def data = [ x: 10, y: 20, z: 30 ]
               def cl = { y = x + y + z }
               cl.delegate = data
               cl.resolveStrategy = Closure.OWNER_ONLY
               cl()
               println x
               println y
               println data
           }
       }

       new Test().run()

  will throw "No such property: z" error because even if the z variable is declared in the delegate, no lookup is made.

  Note that local variables are always looked up first, independently of the resolution strategy.

### SKIP

    public static final int SKIP

### TO_SELF

    public static final int TO_SELF

  With this resolveStrategy set the closure will resolve property references to itself and go through the usual MetaClass look-up process. This means that properties are neither resolved from the owner nor the delegate, but only on the closure object itself. This allows the developer to override getProperty using ExpandoMetaClass of the closure itself.

  Note that local variables are always looked up first, independently of the resolution strategy.

### maximumNumberOfParameters

    protected int maximumNumberOfParameters

### parameterTypes

    protected java.lang.Class[] parameterTypes

Constructor Detail

### Closure

    public Closure(java.lang.Object owner, java.lang.Object thisObject)

### Closure

    public Closure(java.lang.Object owner)

  Constructor used when the "this" object for the Closure is null. This is rarely the case in normal Groovy usage.
  Parameters:
    `owner` - the Closure owner

Method Detail

### asWritable

    public Closure asWritable()

### call

    public java.lang.Object call()

  Invokes the closure without any parameters, returning any value if applicable.
  Returns:
    the value if applicable or null if there is no return statement in the closure

### call

    }
    public java.lang.Object call(java.lang.Object... args)

### call

    public java.lang.Object call(java.lang.Object arguments)

  Invokes the closure, returning any value if applicable.
  Parameters:
    `arguments` - could be a single value or a List of values
  Returns:
    the value if applicable or null if there is no return statement in the closure

### clone

    public java.lang.Object clone()

### curry

    public Closure curry(java.lang.Object... arguments)

### curry

    public Closure curry(java.lang.Object argument)

### dehydrate

    return result;
    public Closure dehydrate()

### getDelegate

    public java.lang.Object getDelegate()

### getDirective

    public int getDirective()

### getMaximumNumberOfParameters

    public int getMaximumNumberOfParameters()

### getOwner

    public java.lang.Object getOwner()

  Returns:
    the owner Object to which method calls will go which is typically the outer class when the closure is constructed

### getParameterTypes

    public java.lang.Class[] getParameterTypes()

### getProperty

    public java.lang.Object getProperty(java.lang.String property)

### getResolveStrategy

    public int getResolveStrategy()

  Gets the strategy which the closure users to resolve methods and properties
  Returns:
    The resolve strategy
  See Also:
    Closure.DELEGATE_FIRST
    Closure.DELEGATE_ONLY
    Closure.OWNER_FIRST
    Closure.OWNER_ONLY
    Closure.TO_SELF

### getThisObject

    public java.lang.Object getThisObject()

### isCase

    public boolean isCase(java.lang.Object candidate)

### leftShift

    public Closure leftShift(Closure other)

### leftShift

    public java.lang.Object leftShift(java.lang.Object arg)

### memoize

    public Closure memoize()

### memoizeAtLeast

    public Closure memoizeAtLeast(int protectedCacheSize)

  Creates a caching variant of the closure with automatic cache size adjustment and lower limit on the cache size. Whenever the closure is called, the mapping between the parameters and the return value is preserved in cache making subsequent calls with the same arguments fast. This variant allows the garbage collector to release entries from the cache and at the same time allows the user to specify how many entries should be protected from the eventual gc-initiated eviction. Cached entries exceeding the specified preservation threshold are made available for eviction based on the LRU (Last Recently Used) strategy. Given the non-deterministic nature of garbage collector, the actual cache size may grow well beyond the limits set by the user if memory is plentiful. The returned function can be safely used concurrently from multiple threads, however, the implementation values high average-scenario performance and so concurrent calls on the memoized function with identical argument values may not necessarily be able to benefit from each other's cached return value. Also the protectedCacheSize parameter might not be respected accurately in such scenarios for some periods of time. With this having been mentioned, the performance trade-off still makes concurrent use of memoized functions safe and highly recommended. The cache gets garbage-collected together with the memoized closure.
  Parameters:
    `protectedCacheSize` - Number of cached return values to protect from garbage collection
  Returns:
    A new function forwarding to the original one while caching the results

### memoizeAtMost

    public Closure memoizeAtMost(int maxCacheSize)

### memoizeBetween

    public Closure memoizeBetween(int protectedCacheSize, int maxCacheSize)

  Creates a caching variant of the closure with automatic cache size adjustment and lower and upper limits on the cache size. Whenever the closure is called, the mapping between the parameters and the return value is preserved in cache making subsequent calls with the same arguments fast. This variant allows the garbage collector to release entries from the cache and at the same time allows the user to specify how many entries should be protected from the eventual gc-initiated eviction. Cached entries exceeding the specified preservation threshold are made available for eviction based on the LRU (Last Recently Used) strategy. Given the non-deterministic nature of garbage collector, the actual cache size may grow well beyond the protected size limits set by the user, if memory is plentiful. Also, this variant will never exceed in size the upper size limit. Once the upper size limit has been reached, the values in the cache start rotating using the LRU (Last Recently Used) strategy. The returned function can be safely used concurrently from multiple threads, however, the implementation values high average-scenario performance and so concurrent calls on the memoized function with identical argument values may not necessarily be able to benefit from each other's cached return value. Also the protectedCacheSize parameter might not be respected accurately in such scenarios for some periods of time. With this having been mentioned, the performance trade-off still makes concurrent use of memoized functions safe and highly recommended. The cache gets garbage-collected together with the memoized closure.
  Parameters:
    `protectedCacheSize` - Number of cached return values to protect from garbage collection
    `maxCacheSize` - The maximum size the cache can grow to
  Returns:
    A new function forwarding to the original one while caching the results

### ncurry

    public Closure ncurry(int n, java.lang.Object... arguments)

### ncurry

    public Closure ncurry(int n, java.lang.Object argument)

### rcurry

    public Closure rcurry(java.lang.Object... arguments)

### rcurry

    public Closure rcurry(java.lang.Object argument)

### rehydrate

    return result;
    public Closure rehydrate(java.lang.Object delegate, java.lang.Object owner, java.lang.Object thisObject)

  Returns a copy of this closure for which the delegate, owner and thisObject are replaced with the supplied parameters. Use this when you want to rehydrate a closure which has been made serializable thanks to the dehydrate() method.
  Parameters:
    `delegate` - the closure delegate
    `owner` - the closure owner
    `thisObject` - the closure "this" object
  Returns:
    a copy of this closure where owner, delegate and thisObject are replaced
  Since:
    1.8.5

### rightShift

    public Closure rightShift(Closure other)

### run

    public void run()

### setDelegate

    public void setDelegate(java.lang.Object delegate)

### setDirective

    public void setDirective(int directive)

### setProperty

    public void setProperty(java.lang.String property, java.lang.Object newValue)

### setResolveStrategy

    public void setResolveStrategy(int resolveStrategy)

  Sets the strategy which the closure uses to resolve property references. The default is Closure.OWNER_FIRST
  Parameters:
    `resolveStrategy` - The resolve strategy to set
  See Also:
    Closure.DELEGATE_FIRST
    Closure.DELEGATE_ONLY
    Closure.OWNER_FIRST
    Closure.OWNER_ONLY
    Closure.TO_SELF

### throwRuntimeException

    protected static java.lang.Object throwRuntimeException(java.lang.Throwable throwable)

### trampoline

    public Closure trampoline(java.lang.Object... args)

  Builds a trampolined variant of the current closure. To prevent stack overflow due to deep recursion, functions can instead leverage the trampoline mechanism and avoid recursive calls altogether. Under trampoline, the function is supposed to perform one step of the calculation and, instead of a recursive call to itself or another function, it return back a new closure, which will be executed by the trampoline as the next step. Once a non-closure value is returned, the trampoline stops and returns the value as the final result. Here is an example:

       def fact
       fact = { n, total ->
           n == 0 ? total : fact.trampoline(n - 1, n * total)
       }.trampoline()
       def factorial = { n -> fact(n, 1G)}
       println factorial(20) // => 2432902008176640000

  Parameters:
    `args` - Parameters to the closure, so as the trampoline mechanism can call it
  Returns:
    A closure, which will execute the original closure on a trampoline.

### trampoline

    public Closure trampoline()

Groovy Documentation