This assumes that you have setup groovy as per Setting up Groovy.
#1: Running groovysh
1 | c:\TOOLS\groovy-2.4.3\bin>groovysh |
1 2 3 4 5 | Groovy Shell (2.4.3, JVM: 1.6.0_45) Type ':help' or ':h' for help. -------------------------------------- groovy:000> |
You can now type your expressions on the “groovy:000>” prompt like
1 2 3 4 5 | groovy:000> println "Hello Groovy" Hello Groovy ===> null groovy:000> |
Q1. What is the “====> null” after printing “Hello Groovy”?
A1. because println is a void method. It does not return anything.
Q2. Now, how do you exit “groovy:000>“?
A2. type “:exit” or “:quit“. To learn more, type “:help”
#2: Groovy is dynamically typed & supports operator overloading
1 2 3 4 | groovy:000> def a =2; def b = 3; a+b ===> 5 groovy:000> |
if you say “a=2”, groovy puts it in the global script scope. So, “def a = 2″, means local scope. Now, a and b are strings.
1 2 3 4 | groovy:000> def a = "Groovy is"; def b = " a cool language"; a + b ===> Groovy is a cool language groovy:000> |
So, the variables a and b can dynamically take any argument types. This is known as the “dynamically typed” language in the same vein as other dynamically typed languages like Ruby, Python, etc.
You can also see “operator overloading” in action as it sums it for int values giving “5” and concatenating it for the strings. Two more examples where int + string = string, and double + int = double.
1 2 3 4 5 6 | groovy:000> def a = 2; b = " two"; a + b ===> 2 two groovy:000> def a = 2.5; b = 3; a + b ===> 5.5 groovy:000> |
#3 Groovy supports closure
Closure is like method where a block of code between two curly brackets like {println it}.
Q3. So, what is the difference between a closure and a method?
A3. A closure is a real first-class object, which can be assigned to a variable and passed around like a variable from one function to another. In the example below, {println it} is assigned to a variable fn, and then invoked via that variable as fn(“test”) or fn.call(“test”).
Q4. How are we able to invoke fn.call(…)?
A4. The {println it} returns a groovy.lang.Closure object, which has the call() methods as shown below.
1 2 3 4 5 6 | groovy:000> def fn = {println it}; fn.call("test");fn("test2") test test2 ===> null groovy:000> |
Note: “null” is printed as println is a void method.
A method is defined as shown below, internally the shell creates a closure to encapsulate the function and then binds the closure to a variable. The variables and functions share the same namespace.
1 2 3 4 5 6 7 8 9 | groovy:000> def hello(name) { groovy:001> println("Hello $name") groovy:002> } ===> true groovy:000> hello("Peter") Hello Peter ===> null groovy:000> |
Q5. How do you pass parameters to a closure?
A5. Apart from the major difference between a method and closure is that later being an object that can be passed around, the next difference is how the parameters are passed. In Groovy closure the parameters are passed as
{[parameters] -> statements }
For example:
1 2 3 4 | groovy:000> def closureWithParameters = { parameter1, parameter2 -> println "Hello $parameter1 and $parameter2"}; closureWithParameters("Sam", "Peter") Hello Sam and Peter ===> null groovy:000> |
Q6. If closure is a first class object in Groovy, can it be passed as parameters?
A6. Yes. In the example below the closure {print it} is passed as a parameter to the method “printMethod(closureAsParam)”
1 2 3 4 5 6 7 | groovy:000> def printMethod(closureAsParam) { groovy:001> closureAsParam("Hello") groovy:002> } ===> true groovy:000> printMethod({print it}) ; Hello===> null groovy:000> |
Method Vs Closure
Both methods and closures give behavior. How they are defined makes a difference.
Method:
1 2 3 | def printMethod(){ println("Hello $name") } |
Closure:
1 | def closure = {name -> println("Hello $name")} |
The closure property can be passed around as a parameter.