I have a Closure defined in a groovy file that load with the shell.evaluate() method.
I need to call this closure in by calling program using the shell."$closurename".call(arguments) call.
However to formulate the closure parameters ( argument above) I'd need to now what are the arguments and arguments names that the closure $Closurename accepts. Is there a way of dynamically knowing this in Groovy? I checked in the metaClass.method property but this does not work in my example below.
Below is the example code.
def arguments;
shell.evaluate(new File("/tmp/myGroovyClosureFile.groovy"))
testBlock = "myClosureName"
//Code here to find the parameters for myClosureName and create
//the arguments variable
shell."$testBlock".call(arguments)
As Jeff mentioned, it seems like groovy when generating code for closures anonymizes somehow the parameter names. However, you can still use reflection to get as much information as you can:
def cl = { int a, String b ->
println(a)
println(b)
}
def callMethod = cl.class.methods.find {
it.name == "call"
}
println callMethod.parameterTypes
println callMethod.parameters.name
and outputs:
[int, class java.lang.String]
[arg0, arg1]
Is there a way of dynamically knowing this in Groovy?
You can't really do it dynamically at runtime.
Related
I am new to Groovy so I am a bit confused by the run time binding, typed and not typed attributes of the language. Personally I prefer types to be declared.
However, I have a question.
I have a small method that takes some variable from maps, input, whatever, that I know are numbers. Let's say that I don't know what the initial type was (it's somewhere deep in the code or comes from an external source), other that it was a number. Now I have a method that takes two of these arguments and I have to do a modulo operation on them. Because they might be decimal or not, I wrote a small method using the remainder of BigDecimal so to enforce the type I used the type BigDecimal on the method signature.
def callerMethod(Map map) {
...
map.each{
calledMethod(it.val1, it.val2)
...
}
...
}
def calledMethod(BigDecimal val1, BigDecimal val2) {
...
vl1.remainder(val2)
...
}
Is this correct? If the incoming argument is Integer (most of the time the primitives are boxed if I understand it correctly), will it be implicitly cast or turned into a BigDecimal?
How does this work in Groovy.
I still think that since I have the option to use types, I want to use them rather than declaring everything def. It also makes it easier to read code or see what something is if you reading already existing code
The problem in this methods are not the type of variables, is the each of your map
In a groovy Map, the each have two signatures.
One receive a Map.Entry of parameter and other receive key and value
Ex.:
Map map = [key1:'value1',key2:'value2']
map.each{ Map.Entry entryMap ->
println "The value of key: ${entryMap.key} is ${entryMap.value}"
}
The result of this each will be:
The value of key: key1 is value1
The value of key: key2 is value2
Or could be like this
Map map = [key1:'value1',key2:'value2']
map.each{ def key, def value ->
println "The value of key: ${key} is ${value}"
}
And the result of this second will be the same of the first.
If you want to pass two specific arguments to you calledMethod, pass both outside of the each like this:
def callerMethod(Map map) {
calledMethod(map.val1, map.val2)
}
I don't understand perfectly what you want.. I hope that's help you to do you code.
What is the command in groovy to ensure a class variable is unaffected by a closure? As we know a closure captures the environment that its wrapped in. So, if I have a closure that increments an integer class variable for example, then that variable is changed for the class. What I want is for a closure to have its own copy of a variable so it does not affect the class variable. Is it possible? In Objective C for example we would use the __Block command and that would make the block be able to change the value of a captured variable. Now, I am asking for the opposite of __Block in my case as closures are already changing the variables they are scoped in.
Lets take a look at a clear example of what I want:
def class myCoolClass {
def x=1
def myMethodThatReturnsClosure(){
//lets return a closure who's scope will include the x=1
myClosure
}
def showMeXFromMyCoolClass(){
println "this is x from myCoolClass:$x"
}
def myClosure={
println "im printing x:$x"
//lets change x now from within closure
x++
}
}
def x = new myCoolClass();
def c=x.myMethodThatReturnsClosure();
c(); //we are changing x ...x = 1
c(); //we are changing x again ...x = 2
c(); //we are changing x again ...x = 3
x.showMeXFromMyCoolClass(); //...x = 4
//i dont want x to be 4 in the last call, i want x to be 1.
//i want it unchanged. how to tell closure to take its own copy
I realize in groovy a closure knows about its environment. It "closes out" around the function that its wrapped in. Is there lambda in groovy then? I think lambda would not know about its environment right? But lets say I want only want variable to not know about its environment and others should, then lambda would not be good.
Your example code is not valid Groovy syntax. You may want to debug it and update the example with the fixes. Nevertheless, you got your point across.
One way of making the closure use a copy of the class variable is to make a copy of the variable and use it instead of x in the closure.:
def myMethodThatReturnsClosure() {
def myX = x
{
println "im printing x:$myX"
myX++
}
}
This assumes the variable is a primitive, which grooy handles differently so that a copy is made. Otherwise the new variable would just be a reference to the original. In the latter case, you'd have to clone the object to get a copy.
Groovy supports both default, and named arguments. I just dont see them working together.
I need some classes to support construction using simple non named arguments, and using named arguments like below:
def a1 = new A(2)
def a2 = new A(a: 200, b: "non default")
class A extends SomeBase {
def props
A(a=1, b="str") {
_init(a, b)
}
A(args) {
// use the values in the args map:
_init(args.a, args.b)
props = args
}
private _init(a, b) {
}
}
Is it generally good practice to support both at the same time? Is the above code the only way to it?
The given code will cause some problems. In particular, it'll generate two constructors with a single Object parameter. The first constructor generates bytecode equivalent to:
A() // a,b both default
A(Object) // a set, b default
A(Object, Object) // pass in both
The second generates this:
A(Object) // accepts any object
You can get around this problem by adding some types. Even though groovy has dynamic typing, the type declarations in methods and constructors still matter. For example:
A(int a = 1, String b = "str") { ... }
A(Map args) { ... }
As for good practices, I'd simply use one of the groovy.transform.Canonical or groovy.transform.TupleConstructor annotations. They will provide correct property map and positional parameter constructors automatically. TupleConstructor provides the constructors only, Canonical applies some other best practices with regards to equals, hashCode, and toString.
I read use keyword in Groovy. But could not come out with, for what it has been exactly been used. And i also come with category classes, under this topic,what is that too? And from, Groovy In Action
class StringCalculationCategory {
static def plus(String self, String operand) {
try {
return self.toInteger() + operand.toInteger()
} catch (NumberFormatException fallback) {
return (self << operand).toString()
}
}
}
use (StringCalculationCategory) {
assert 1 == '1' + '0'
assert 2 == '1' + '1'
assert 'x1' == 'x' + '1'
}
With the above code, can anyone say what is the use of use keyword in groovy? And also what the above code does?
See the Pimp My Library Pattern for what use does.
In your case it overloads the String.add(something) operator. If both Strings can be used as integers (toInteger() doesn't throw an exception), it returns the sum of those two numbers, otherwise it returns the concatenation of the Strings.
use is useful if you have a class you don't have the source code for (eg in a library) and you want to add new methods to that class.
By the way, this post in Dustin Marx's blog Inspired by Actual Events states:
The use "keyword" is actually NOT a keyword, but is a method on
Groovy's GDK extension of the Object class and is provided via
Object.use(Category, Closure). There are numerous other methods
provided on the Groovy GDK Object that provide convenient access to
functionality and might appear like language keywords or functions
because they don't need an object's name to proceed them. I tend not
to use variables in my Groovy scripts with these names (such as is,
println, and sleep) to avoid potential readability issues.
There are other similar "keywords" that are actually methods of the Object class, such as with. The Groovy JDK documentation has a list of such methods.
A very good illustration is groovy.time.TimeCategory. When used together with use() it allows for a very clean and readable date/time declarations.
Example:
use (TimeCategory) {
final now = new Date()
final threeMonthsAgo = now - 3.months
final nextWeek = now + 1.week
}
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)
}
}