|
Groovy 1.8.4 | |||||||
FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectgroovy.lang.GroovyObjectSupport
groovy.lang.Closure
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() == 1To 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
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 Class[] |
parameterTypes
|
Constructor Summary | |
Closure(Object owner, Object thisObject)
|
|
Closure(Object owner)
Constructor used when the "this" object for the Closure is null. |
Method Summary | |
---|---|
Closure
|
asWritable()
|
Object
|
call()
Invokes the closure without any parameters, returning any value if applicable. |
Object
|
call(Object... args)
|
Object
|
call(Object arguments)
Invokes the closure, returning any value if applicable. |
Object
|
clone()
|
Closure
|
curry(Object... arguments)
Support for Closure currying. |
Object
|
getDelegate()
@return the delegate Object to which method calls will go which is typically the outer class when the closure is constructed |
int
|
getDirective()
@return Returns the directive. |
int
|
getMaximumNumberOfParameters()
@return the maximum number of parameters a doCall method of this closure can take |
Object
|
getOwner()
@return the owner Object to which method calls will go which is typically the outer class when the closure is constructed |
Class[]
|
getParameterTypes()
@return the parameter types of the longest doCall method of this closure |
Object
|
getProperty(String property)
|
int
|
getResolveStrategy()
Gets the strategy which the closure users to resolve methods and properties |
Object
|
getThisObject()
|
boolean
|
isCase(Object candidate)
|
Closure
|
leftShift(Closure other)
Support for Closure reverse composition. |
Object
|
leftShift(Object arg)
|
Closure
|
memoize()
Creates a caching variant of the closure. |
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)
Creates a caching variant of the closure with upper limit on the cache size. |
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, Object... arguments)
Support for Closure currying at a given index. |
Closure
|
ncurry(int n, Object argument)
Support for Closure currying at a given index. |
Closure
|
rcurry(Object... arguments)
Support for Closure "right" currying. |
Closure
|
rcurry(Object argument)
Support for Closure "right" currying. |
Closure
|
rightShift(Closure other)
Support for Closure forward composition. |
void
|
run()
|
void
|
setDelegate(Object delegate)
Allows the delegate to be changed such as when performing markup building |
void
|
setDirective(int directive)
@param directive The directive to set. |
void
|
setProperty(String property, Object newValue)
|
void
|
setResolveStrategy(int resolveStrategy)
Sets the strategy which the closure uses to resolve property references. |
protected static Object
|
throwRuntimeException(Throwable throwable)
|
Closure
|
trampoline(Object... args)
Builds a trampolined variant of the current closure. |
Closure
|
trampoline()
Builds a trampolined variant of the current closure. |
Methods inherited from class GroovyObjectSupport | |
---|---|
getMetaClass, getProperty, invokeMethod, setMetaClass, setProperty |
Methods inherited from class Object | |
---|---|
wait, wait, wait, equals, toString, hashCode, getClass, notify, notifyAll |
Field Detail |
---|
public static final int DELEGATE_FIRST
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.
public static final int DELEGATE_ONLY
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.
public static final int DONE
public static final Closure IDENTITY
public static final int OWNER_FIRST
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.
public static final int OWNER_ONLY
class Test { def x = 30 def y = 40 def run() { def data = [ x: 10, y: 20, z: 30 ] def cl = { y = x + y } 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.
public static final int SKIP
public static final int TO_SELF
Note that local variables are always looked up first, independently of the resolution strategy.
protected int maximumNumberOfParameters
protected Class[] parameterTypes
Constructor Detail |
---|
public Closure(Object owner, Object thisObject)
public Closure(Object owner)
owner
- the Closure owner
Method Detail |
---|
public Closure asWritable()
public Object call()
@SuppressWarnings("unchecked") public Object call(Object... args)
public Object call(Object arguments)
arguments
- could be a single value or a List of values
public Object clone()
public Closure curry(Object... arguments)
Typical usage:
def multiply = { a, b -> a * b } def doubler = multiply.curry(2) assert doubler(4) == 8Note: special treatment is given to Closure vararg-style capability. If you curry a vararg parameter, you don't consume the entire vararg array but instead the first parameter of the vararg array as the following example shows:
def a = { one, two, Object[] others -> one + two + others.sum() } assert a.parameterTypes.name == ['java.lang.Object', 'java.lang.Object', '[Ljava.lang.Object;'] assert a(1,2,3,4) == 10 def b = a.curry(1) assert b.parameterTypes.name == ['java.lang.Object', '[Ljava.lang.Object;'] assert b(2,3,4) == 10 def c = b.curry(2) assert c.parameterTypes.name == ['[Ljava.lang.Object;'] assert c(3,4) == 10 def d = c.curry(3) assert d.parameterTypes.name == ['[Ljava.lang.Object;'] assert d(4) == 10 def e = d.curry(4) assert e.parameterTypes.name == ['[Ljava.lang.Object;'] assert e() == 10 assert e(5) == 15
arguments
- the arguments to bind
public Object getDelegate()
public int getDirective()
public int getMaximumNumberOfParameters()
public Object getOwner()
public Class[] getParameterTypes()
public Object getProperty(String property)
public int getResolveStrategy()
public Object getThisObject()
public boolean isCase(Object candidate)
public Closure leftShift(Closure other)
def twice = { a -> a * 2 } def thrice = { a -> a * 3 } def times6 = thrice << twice // equivalent: times6 = { a -> thrice(twice(a)) } assert times6(3) == 18
other
- the Closure to compose with the current Closure
public Object leftShift(Object arg)
public Closure memoize()
public Closure memoizeAtLeast(int protectedCacheSize)
protectedCacheSize
- Number of cached return values to protect from garbage collection
public Closure memoizeAtMost(int maxCacheSize)
maxCacheSize
- The maximum size the cache can grow to
public Closure memoizeBetween(int protectedCacheSize, int maxCacheSize)
protectedCacheSize
- Number of cached return values to protect from garbage collectionmaxCacheSize
- The maximum size the cache can grow to
public Closure ncurry(int n, Object... arguments)
def caseInsensitive = { a, b -> a.toLowerCase() <=> b.toLowerCase() } as Comparator def caseSensitive = { a, b -> a <=> b } as Comparator def animals1 = ['ant', 'dog', 'BEE'] def animals2 = animals1 + ['Cat'] // curry middle param of this utility method: // Collections#binarySearch(List list, Object key, Comparator c) def catSearcher = Collections.&binarySearch.ncurry(1, "cat") [[animals1, animals2], [caseInsensitive, caseSensitive]].combinations().each{ a, c -> def idx = catSearcher(a.sort(c), c) print a.sort(c).toString().padRight(22) if (idx < 0) println "Not found but would belong in position ${-idx - 1}" else println "Found at index $idx" } // => // [ant, BEE, dog] Not found but would belong in position 2 // [ant, BEE, Cat, dog] Found at index 2 // [BEE, ant, dog] Not found but would belong in position 2 // [BEE, Cat, ant, dog] Not found but would belong in position 3
n
- the index from which to bind parameters (may be -ve in which case it will be normalized)arguments
- the arguments to bind
public Closure ncurry(int n, Object argument)
argument
- the argument to bind
public Closure rcurry(Object... arguments)
def divide = { a, b -> a / b } def halver = divide.rcurry(2) assert halver(8) == 4
arguments
- the arguments to bind
public Closure rcurry(Object argument)
argument
- the argument to bind
public Closure rightShift(Closure other)
def twice = { a -> a * 2 } def thrice = { a -> a * 3 } def times6 = twice >> thrice // equivalent: times6 = { a -> thrice(twice(a)) } assert times6(3) == 18
other
- the Closure to compose with the current Closure
public void run()
public void setDelegate(Object delegate)
delegate
- the new delegate
public void setDirective(int directive)
directive
- The directive to set.
public void setProperty(String property, Object newValue)
public void setResolveStrategy(int resolveStrategy)
resolveStrategy
- The resolve strategy to set
protected static Object throwRuntimeException(Throwable throwable)
public Closure trampoline(Object... args)
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
args
- Parameters to the closure, so as the trampoline mechanism can call it
public Closure trampoline()
Copyright © 2003-2011 The Codehaus. All rights reserved.