|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectgroovy.lang.GroovyObjectSupport
groovy.lang.Closure<V>
public abstract class Closure<V>
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
|
protected int |
maximumNumberOfParameters
|
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. |
protected Class[] |
parameterTypes
|
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. |
Constructor Summary | |
---|---|
Closure(Object owner)
Constructor used when the "this" object for the Closure is null. |
|
Closure(Object owner,
Object thisObject)
|
Method Summary | ||
---|---|---|
Closure |
asWritable()
|
|
V |
call()
Invokes the closure without any parameters, returning any value if applicable. |
|
V |
call(Object... args)
|
|
V |
call(Object arguments)
Invokes the closure, returning any value if applicable. |
|
Object |
clone()
|
|
Closure<V> |
curry(Object... arguments)
Support for Closure currying. |
|
Closure<V> |
curry(Object argument)
Support for Closure currying. |
|
Closure<V> |
dehydrate()
Returns a copy of this closure where the "owner", "delegate" and "thisObject" fields are null, allowing proper serialization when one of them is not serializable. |
|
Object |
getDelegate()
|
|
int |
getDirective()
|
|
int |
getMaximumNumberOfParameters()
|
|
Object |
getOwner()
|
|
Class[] |
getParameterTypes()
|
|
Object |
getProperty(String property)
Retrieves a property value. |
|
int |
getResolveStrategy()
Gets the strategy which the closure users to resolve methods and properties |
|
Object |
getThisObject()
|
|
boolean |
isCase(Object candidate)
|
|
Closure<V> |
leftShift(Closure other)
Support for Closure reverse composition. |
|
V |
leftShift(Object arg)
|
|
Closure<V> |
memoize()
Creates a caching variant of the closure. |
|
Closure<V> |
memoizeAtLeast(int protectedCacheSize)
Creates a caching variant of the closure with automatic cache size adjustment and lower limit on the cache size. |
|
Closure<V> |
memoizeAtMost(int maxCacheSize)
Creates a caching variant of the closure with upper limit on the cache size. |
|
Closure<V> |
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<V> |
ncurry(int n,
Object... arguments)
Support for Closure currying at a given index. |
|
Closure<V> |
ncurry(int n,
Object argument)
Support for Closure currying at a given index. |
|
Closure<V> |
rcurry(Object... arguments)
Support for Closure "right" currying. |
|
Closure<V> |
rcurry(Object argument)
Support for Closure "right" currying. |
|
Closure<V> |
rehydrate(Object delegate,
Object owner,
Object thisObject)
Returns a copy of this closure for which the delegate, owner and thisObject are replaced with the supplied parameters. |
|
|
rightShift(Closure<W> 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)
|
|
void |
setProperty(String property,
Object newValue)
Sets the given property to the new value. |
|
void |
setResolveStrategy(int resolveStrategy)
Sets the strategy which the closure uses to resolve property references. |
|
protected static Object |
throwRuntimeException(Throwable throwable)
|
|
Closure<V> |
trampoline()
Builds a trampolined variant of the current closure. |
|
Closure<V> |
trampoline(Object... args)
Builds a trampolined variant of the current closure. |
Methods inherited from class groovy.lang.GroovyObjectSupport |
---|
getMetaClass, invokeMethod, setMetaClass |
Methods inherited from class java.lang.Object |
---|
equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
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 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 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 + 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.
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 TO_SELF
Note that local variables are always looked up first, independently of the resolution strategy.
public static final int DONE
public static final int SKIP
public static final Closure IDENTITY
protected Class[] parameterTypes
protected int maximumNumberOfParameters
Constructor Detail |
---|
public Closure(Object owner, Object thisObject)
public Closure(Object owner)
owner
- the Closure ownerMethod Detail |
---|
public void setResolveStrategy(int resolveStrategy)
resolveStrategy
- The resolve strategy to setDELEGATE_FIRST
,
DELEGATE_ONLY
,
OWNER_FIRST
,
OWNER_ONLY
,
TO_SELF
public int getResolveStrategy()
DELEGATE_FIRST
,
DELEGATE_ONLY
,
OWNER_FIRST
,
OWNER_ONLY
,
TO_SELF
public Object getThisObject()
public Object getProperty(String property)
GroovyObject
getProperty
in interface GroovyObject
getProperty
in class GroovyObjectSupport
property
- the name of the property of interest
public void setProperty(String property, Object newValue)
GroovyObject
setProperty
in interface GroovyObject
setProperty
in class GroovyObjectSupport
property
- the name of the property of interestnewValue
- the new value for the propertypublic boolean isCase(Object candidate)
public V call()
call
in interface Callable<V>
public V call(Object... args)
public V call(Object arguments)
arguments
- could be a single value or a List of values
protected static Object throwRuntimeException(Throwable throwable)
public Object getOwner()
public Object getDelegate()
public void setDelegate(Object delegate)
delegate
- the new delegatepublic Class[] getParameterTypes()
public int getMaximumNumberOfParameters()
public Closure asWritable()
Object.toString()
in order
to allow rendering the result directly to a String.public void run()
run
in interface Runnable
public Closure<V> 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 Closure<V> curry(Object argument)
argument
- the argument to bind
curry(Object...)
public Closure<V> rcurry(Object... arguments)
def divide = { a, b -> a / b } def halver = divide.rcurry(2) assert halver(8) == 4
arguments
- the arguments to bind
curry(Object...)
public Closure<V> rcurry(Object argument)
argument
- the argument to bind
rcurry(Object...)
public Closure<V> 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
curry(Object...)
public Closure<V> ncurry(int n, Object argument)
argument
- the argument to bind
ncurry(int, Object...)
public <W> Closure<W> rightShift(Closure<W> 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 Closure<V> 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 V leftShift(Object arg)
public Closure<V> memoize()
public Closure<V> memoizeAtMost(int maxCacheSize)
maxCacheSize
- The maximum size the cache can grow to
public Closure<V> memoizeAtLeast(int protectedCacheSize)
protectedCacheSize
- Number of cached return values to protect from garbage collection
public Closure<V> 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<V> 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<V> trampoline()
trampoline(Object...)
public Object clone()
clone
in class Object
public int getDirective()
public void setDirective(int directive)
directive
- The directive to set.public Closure<V> dehydrate()
public Closure<V> rehydrate(Object delegate, Object owner, Object thisObject)
dehydrate()
method.
delegate
- the closure delegateowner
- the closure ownerthisObject
- the closure "this" object
|
Copyright © 2003-2012 The Codehaus. All rights reserved. | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |