What is the Groovy 'it'? - groovy

I have a collection which I process with removeIf {} in Groovy. Inside the block, I have access to some it identifier. What is this and where is it documented?

it is an implicit variable that is provided in closures. It's available when the closure doesn't have an explicitly declared parameter.
When the closure is used with collection methods, such as removeIf, it will point to the current iteration item.
It's like you declared this:
List<Integer> integers = [1, 2, 3]
for(Integer it: integers) {print(it)}
When you use each, instead (and that's an example), you can get it implicitly provided:
integers.each{print(it)} //it is given by default
Or
integers.removeIf{it % 2 == 0} //it is the argument to Predicate.test()
it will successively take the values 1, 2, and 3 as iterations go.
You can, of course, rename the variable by declaring the parameter in the closure:
integers.each{myInteger -> print(myInteger)}
In this case, Groovy doesn't supply the implicit it variable. The documentation has more details

If you create a closure without an explicit argument list, it defaults to having a single argument named it. Here's an example that can be run in the Groovy console
Closure incrementBy4 = { it + 4 }
// test it
assert incrementBy4(6) == 10
In the example above the closure is identical to
Closure incrementBy4 = { it -> it + 4 }
Here's another example that uses removeIf
Closure remove2 = { it == 2 }
def numbers = [1, 2, 3]
numbers.removeIf(remove2)
// verify that it worked as expected
assert numbers == [1, 2]

Related

Override methods used with GroovyBeans notation

Today I stumbled with what it looked like a little Groovy magic when I found out I could get a property from a List of Maps using the GroovyBeans dot notation:
List list = [[a: 1, b: 2], [c: 3, d: 4]]
assert list.b == [2, null]
This will be great for my use case if the value returned was, in the example above, 2 only. I thought that to override the getAt method would do the trick, and in fact this works (in this example if there is more than 1 non null result it will return the first which is OK)
List.metaClass.getAt = { String s -> return delegate.findAll({ Map m -> m.get(s) }).get(0).get(s) }
List list = [[a: 1, b: 2], [c: 3, d: 4]]
assert list.getAt("b") == 2
but... if I use the dot notation the method being invoked is not the getAt(String)
List.metaClass.getAt = { String s -> return delegate.findAll({ Map m -> m.get(s) }).get(0).get(s) }
List list = [[a: 1, b: 2], [c: 3, d: 4]]
assert list.b == 2 // Assertion failed
I couldn't find what method is being invoked with the dot notation... Anybody have any clues?
You may wonder why I want to use the dot notation when calling the method explicitly gives me what I want, but in fact this is part of a DSL I'm writing so I can easily explain to people who are going to use it what is for instance
current.processDate
but it's hard to explain they have to do
current[0].processDate ?: current[1].processDate
or even
current.getAt("processDate")
Thanks in advance.
UPDATE
I now think think it is impossible to do so. I stepped thru all the code I could, the piece of code that actually get values for the maps in the list and accumulates those values is
DefaultGroovyMethods
private static List getAtIterable(Iterable coll, String property, List<Object> answer)
and I can't override it like this
DefaultGroovyMethods.metaClass.static.getAtIterable = {
coll, property, answer ->
def find = coll.find { it != null }
return find
}
I also tried to override the very first method called in the dot notation
AbstractCallSite
public Object callGetProperty(Object receiver) throws Throwable {
return this.acceptGetProperty(receiver).getProperty(receiver);
}
like this:
AbstractCallSite.metaClass.callGetProperty = {
Object receiver ->
if ( !(receiver instanceof ArrayList)){
return delegate.callGetProperty(receiver)
}
return "SOMETHING"
}
So maybe it's time to call it quits?

Groovy: What's the difference between defining a variable without "def" versus using anchoring?

I'm learning Groovy now and I bumped into something that I don't understand and I hope you'd be able to shed some light.
In regard to the following example:
import groovy.transform.Field
#Field List awe = [1, 2, 3]
def awesum() { awe.sum() }
assert awesum() == 6
I understand that this anchoring allows me to change the scope of the awe variable from being run at the method level of the script to the class level of the script.
But then I think about the difference between defining a variables with def or without, example:
def var = "foo"
and
var = "foo"
As far as I understand the difference between the two examples is a difference of scope.
When I assign a value to a variable without a "def" or other type, in a Groovy script, it's added to the "binding", the global variables for the script.
Which means it can be accessed from all functions within the script.
So taking into consideration both "#Field" and defining a variable without using "def" and following that line of thought I've changed the example code to this:
import groovy.transform.Field
awe = [1, 2, 3]
def awesum() { awe.sum() }
assert awesum() == 6
And it works.
So my question is why use anchoring? if you can achieve the same goal by defining a variable without the "def"?
You do not achieve the same goal - see the difference below
import groovy.transform.Field
awe = [1, 2, 3]
def awesum() { awe.sum() }
assert awesum() == 6
awe = 1
work fine as the variable is dynamically typed.
On contrary this fails
import groovy.transform.Field
#Field List awe = [1, 2, 3]
def awesum() { awe.sum() }
assert awesum() == 6
awe = 1
As the variable is strong typed (java.util.ArrayList)
Caught: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '1' with class 'java.lang.Integer' to class 'java.util.List'
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '1' with class 'java.lang.Integer' to class 'java.util.List'
at FieldTest1.run(FieldTest1.groovy:5)
#Field is younger than scripts and the intended use is to give open blocks the ability to have additional state. If you are happy with the binding there is not really a big reason for doing it different. If you need the values in the binding of course, then #Field is no alternative. On the other hand, if the binding must contain only certain variables, then #Field can become a must
Example for intended usage:
def cl = {
Field x = 1
x++
}
In this example the open block cl would have a field x, the script would not have x in the binding, nor is there a local variable x. But the assignment x=1 is done only once when the open block is created. But you can still change the value by operations on that field. That way each call cl() will produce a new value, starting with 1.
Defining a variable in a class or method without "def" gives syntax errors. Like this:
class Cat {
def name = "Amy"
nickname = "Lisa" // Error
def greet() {
tmp = "" // Error
println "I am $name"
}
}
Defining a variable in a Groovy script without "def" makes it a global one to some extent. Like this:
name = "Amy" // Global variable, giving errors if "def" is added
def greet() {
println "I am $name"
}
greet()

Is there a way to refer to an operator as a two-argument closure?

Sometimes I need to pass an operator as a closure, like this:
do.some.thing() { x,y -> x+y }
I'm wondering if there is any shorthand "operator pointer" syntax, analogous to the "method pointer" syntax, that would give me the operator already wrapped into a two-argument closure.
I see that most arithmetic operators are available as methods on Number and related classes:
public Number plus(Number right)
Add two numbers and return the result.
but they are instance methods and I can't figure out if I can use the method pointer operator .& to turn them into a two-argument closure.
You can do this sort of thing as well...
Not sure uncurry is the right term, but it's almost right ;-)
import org.codehaus.groovy.runtime.MethodClosure
def uncurry(MethodClosure c) {
{a, ...b -> a."$c.method"(*b) }
}
Then, to make a 2 arg closure from Number.plus, you can do:
def plus = uncurry(Number.&plus)
And then:
assert plus(1, 2) == 3
Which also works with other method handles as well:
def collate = uncurry(List.&collate)
assert collate([1, 2, 3, 4, 5], 2, true) == [[1, 2], [3, 4], [5]]
No, there's no such operator.
The method pointer operator won't work because the MethodClosure it creates basically has an object, in this case the Number class, and a method name. So if you do...
def c = Number.&plus
Then calling c will attempt to call plus() on the Number class, which of course won't work.
The only shortcut I can think of is to declare your operator closures once and simply reuse them as needed.

What is closure and why to use it?

What is closure in groovy?
Why we use this closure?
Are you asking about Closure annotation parameters?
[...
An interesting feature of annotations in Groovy is that you can use a closure as an annotation value. Therefore annotations may be used with a wide variety of expressions and still have IDE support. For example, imagine a framework where you want to execute some methods based on environmental constraints like the JDK version or the OS. One could write the following code:
class Tasks {
Set result = []
void alwaysExecuted() {
result << 1
}
#OnlyIf({ jdk>=6 })
void supportedOnlyInJDK6() {
result << 'JDK 6'
}
#OnlyIf({ jdk>=7 && windows })
void requiresJDK7AndWindows() {
result << 'JDK 7 Windows'
}
}
...]
Source:http://docs.groovy-lang.org/
Closures are a powerful concept with which you can implement a variety of things and which enable specifying DSLs. They are sort of like Java ( lambdas, but more powerful and versatile. You dont need to use closures, but they can make many things easier.
Since you didnt really specify a concrete question, I'll just point you to the startegy pattern example in the groovy docs:
http://docs.groovy-lang.org/latest/html/documentation/#_strategy_pattern
Think of the closure as an executable unit on its own, like a method or function, except that you can pass it around like a variable, but can do a lot of things that you would normally do with a class, for example.
An example: You have a list of numbers and you either want to add +1 to each number, or you want to double each number, so you say
def nums = [1,2,3,4,5]
def plusone = { item ->
item + 1
}
def doubler = { item ->
item * 2
}
println nums.collect(plusone)
println nums.collect(doubler)
This will print out
[2, 3, 4, 5, 6]
[2, 4, 6, 8, 10]
So what you achieved is that you separated the function, the 'what to do' from the object that you did it on. Your closures separate an action that can be passed around and used by other methods, that are compatible with the closure's input and output.
What we did in the example is that we had a list of numbers and we passed each of them to a closure that did something with it. Either added +1 or doubled the value, and collected them into another list.
And this logic opens up a whole lot of possibilities to solve problems smarter, cleaner, and write code that represents the problem better.

EachWithIndex groovy statement

I am new to groovy and I've been facing some issues understanding the each{} and eachwithindex{} statements in groovy.
Are each and eachWithIndex actually methods? If so what are the arguments that they take?
In the groovy documentation there is this certain example:
def numbers = [ 5, 7, 9, 12 ]
numbers.eachWithIndex{ num, idx -> println "$idx: $num" } //prints each index and number
Well, I see that numbers is an array. What are num and idx in the above statement? What does the -> operator do?
I do know that $idx and $num prints the value, but how is it that idx and num are automatically being associated with the index and contents of the array? What is the logic behind this? Please help.
These are plain methods but they follow quite a specific pattern - they take a Closure as their last argument. A Closure is a piece of functionality that you can pass around and call when applicable.
For example, method eachWithIndex might look like this (roughly):
void eachWithIndex(Closure operation) {
for (int i = 0; this.hasNext(); i++) {
operation(this.next(), i); // Here closure passed as parameter is being called
}
}
This approach allows one to build generic algorithms (like iteration over items) and change the concrete processing logic at runtime by passing different closures.
Regarding the parameters part, as you see in the example above we call the closure (operation) with two parameters - the current element and current index. This means that the eachWithIndex method expects to receive not just any closure but one which would accept these two parameters. From a syntax prospective one defines the parameters during closure definition like this:
{ elem, index ->
// logic
}
So -> is used to separate arguments part of closure definition from its logic. When a closure takes only one argument, its parameter definition can be omitted and then the parameter will be accessible within the closure's scope with the name it (implicit name for the first argument). For example:
[1,2,3].each {
println it
}
It could be rewritten like this:
[1,2,3].each({ elem ->
println elem
})
As you see the Groovy language adds some syntax sugar to make such constructions look prettier.
each and eachWithIndex are, amongst many others, taking so called Closure as an argument. The closure is just a piece of Groovy code wrapped in {} braces. In the code with array:
def numbers = [ 5, 7, 9, 12 ]
numbers.eachWithIndex{ num, idx -> println "$idx: $num" }
there is only one argument (closure, or more precisely: function), please note that in Groovy () braces are sometime optional. num and idx are just an optional aliases for closure (function) arguments, when we need just one argument, this is equivalent (it is implicit name of the first closure argument, very convenient):
def numbers = [ 5, 7, 9, 12 ]
numbers.each {println "$it" }
References:
http://groovy.codehaus.org/Closures
http://en.wikipedia.org/wiki/First-class_function
Normally, if you are using a functional programing language such as Groovy, you would want to avoid using each and eachWithIndex since they encourage you to modify state within the closure or do things that have side effects.
If possible, you may want to do your operations using other groovy collection methods such as .collect or .inject or findResult etc.
However, to use these for your problem, i.e print the list elements with their index, you will need to use the withIndex method on the original collection which will transform the collection to a collection of pairs of [element, index]
For example,
println(['a', 'b', 'c'].withIndex())
EachWithIndex can be used as follows:
package json
import groovy.json.*
import com.eviware.soapui.support.XmlHolder
def project = testRunner.testCase.testSuite.project
def testCase = testRunner.testCase;
def strArray = new String[200]
//Response for a step you want the json from
def response = context.expand('${Offers#Response#$[\'Data\']}').toString()
def json = new JsonSlurper().parseText(response)
//Value you want to compare with in your array
def offername = project.getPropertyValue("Offername")
log.info(offername)
Boolean flagpresent = false
Boolean flagnotpresent = false
strArray = json.Name
def id = 0;
//To find the offername in the array of offers displayed
strArray.eachWithIndex
{
name, index ->
if("${name}" != offername)
{
flagnotpresent= false;
}
else
{
id = "${index}";
flagpresent = true;
log.info("${index}.${name}")
log.info(id)
}
}

Resources