groovy unleashed

Post on 23-Jan-2018

242 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Welcome To… Groovy!

– The Catalyst Language for Programmers

Presentation By-Isuru Samaraweera

Agenda

• Introduction to Groovy• Key Features• Closures• Operator Overloading• Array Slicing and looping

• Collections

• Dynamic Methods/Mixins and Properties• Regular Expressions• File IO• Database Operations

What is Groovy?• Java-like scripting language for the JVM• Dynamic Language• Inspired by Ruby,Python,SmallTalk and Perl • Open Source language

– Apache2.0 license– dev@groovy.apache.org – users@groovy.apache.org

• Seamless integration with Java – Follow the mantra…Java is Groovy,Groovy is Java

• Web Application Development– Groovelets,GSP,Grapplet

• Sole alternative dynamic language for the JVM fully supporting frameworks like Spring, Hibernate– Grails– Coding by Convention

• Mobile Application Support • Official web site http://www.groovy-lang.org/

Installation and Configuration

• Prerequisites– JDK1.4 or higher installed and system path should point to %JAVA_HOME%/bin

• Download Groovy distribution from http://www.groovy-lang.org/download.html • Unzip the groovy archive

– Set the GROOVY_HOME environment variables.– Add %GROOVY_HOME%\bin to your system path – Try opening groovyConsole.bat

• Eclipse Plug-in– https://github.com/groovy/groovy-eclipse/wiki

• IntelliJ Idea Plug-in-Community edition– http://www.jetbrains.net

Key Language Features

• Pure Object Oriented 3.times { println "hello" } • Dynamic Typing/Duck typing• Closures• Currying• Operator Overloading• Array Slicing• Dynamic Methods• Expandos• Static imports• Annotations• Covariant return types• POGO support• Mixins

Java Vs. Groovy No of line Comparison

• Java Codefor (String item : new String [] {"Rod", "Carlos", "Chris"})

{

if (item.length() <= 4)

{

System.out.println(item);

}

}

• Groovy Code

["Rod", "Carlos", "Chris"].findAll{it.size() <= 4}.each{println it}

/*A Typical Groovy Class*/

class Customer{ // properties Integer id String name Date dob

// sample code static void main(args)

{ def customer = new Customer(id:1, name:"Gromit", dob:new Date()) println("Hello ${customer.getName()}")customer.setName(“James”)println("Hello ${customer.getName()}")

} }

Java Vs. Groovy No of line Comparison

Closures• A block of code that can access variables in the scope where it is declared or

outside

• Higher order functions

• A closure will have a default parameter named it if you do not define one

def x = { println it }

• And here's how you call it (two options):

x('Hello, world!')

x.call('Hello, world')

Closure Arguments(Typed or Untyped)• Untyped Arguments

def isList = { i -> i instanceof List } if (isList([]))

{println "This is a List“

}

• Typed Arguments

def prefix = { String s -> while (s.length() < 17)

{ s = "0$s" } s // return keyword is not required } def id = prefix "1234" // parentheses are not required

Closures as arguments and Recursion• Closures can be passed as arguments

• Consider the each() method on java.util.Map: System.properties.each { println it.key }

• Recursion• lambda is annonymous

def fac =

{

int i -> i == 1 ? 1 : i * call(i - 1)

}

println fac(10)

Currying• Currying is a programming technique that transforms a function into

another while fixing one or more input values

def multiply = { x, y -> return x * y } // closuredef triple = multiply.curry(3) // triple = { y -> return 3 * y }def quadruple = multiply.curry(4) // quadruple = { y -> return 4 * y }def p = triple.call(4) // explicit calldef q = quadruple(5) // implicit callprintln "p: ${p}" // p is 12println "q: ${q}" // q is 20

Currying contd..

def lSubtract = { x, y -> return x - y }def rSubtract = { y, x -> return x - y }def dec = rSubtract.curry(1) // dec = { x -> return x - 1 }def cent = lSubtract.curry(100) // cent = { y -> return 100 - y }def p = dec.call(5) // explicit calldef q = cent(25) // implicit callprintln "p: ${p}" // p is 4println "q: ${q}" // q is 75

Variable Arguments int sum(int... someInts)

{

//ellipsis notation

def total = 0

for (int i = 0; i < someInts.size(); i++)total += someInts[i]

return total

}

assert sum(1) == 1

assert sum(1, 2) == 3

Operator Overloading ! - 1it does it by following a naming convention for methods.

Operation Method

a+b a.Plus(b)

a-b a.minus(b)

a*b a.multiply(b)

a**b a.power(b)

a/b a.div(b)

a % b a.mod(b)

a | b a.or(b)

a & b a.and(b)

Operator Overloading ! - 2

a ^ b a.xor(b)

a++ or ++a a.next()

a-- or --a a.previous()

a[b] a.getAt(b)

a[b] = c a.putAt(b, c)

a << b a.leftShift(b)

a >> b a.rightShift(b)

switch(a) { case(b) : } b.isCase(a)

~a a.bitwiseNegate()

-a a.negative()

+a a.positive()

Operator Overloading ! - 3text = "Programing" - "ing" + "er" assert "Programer" == text list = [1,2,3] list += [4,5,6] assert [1,2,3,4,5,6] == list

list << 7 // list.leftShift(7) -> list.add(7)assert [1,2,3,4,5,6,7] == list

s = "A" * 5 assert s == "AAAAA“s = "ABCDE" assert "BC" == s[1..2] s.getAt([1..2]); ranged operation assert "C" == s[2] // s.getAt(2) -> s.charAt(2)

Looping• General for loop and while loop

• Classical for loop def x = 0 for ( i in 0..9 ) //RANGE { x += i } assert x == 45 // iterate over a list

• Iterate over a list

x = 0 for ( i in [0, 1, 2, 3, 4] ) //LIST { x += i } assert x == 10

def a = [1,2,3,4,5]

a[1..-1]

OUTPUT : [2, 3, 4, 5]

def a = [1,2,3,4,5]

a[1..<-1]

OUTPUT: [2, 1]

Array Slicing

Elvis Operator• Elvis Operator alternative to ternary operator

//traditional ternary operatorString name = “Sam";String displayName = name != null ? name : "Unknown";

//elvis operatorString name = “Sam"String displayName = name ? name : "Unknown"

//eliminate DRY String name = “Sam" String displayName = name ?: "Unknown"

Agenda• Introduction to Groovy• Key Features• Closures• Operator Overloading• Array Slicing and looping

• Collections

• Dynamic Methods and Properties• Regular Expressions• File IO• Database Operations• Unified Field and Programming Languages

Collections in Groovy

– Lists

– Ranges

– Maps

– Expandos (Dynamic Objects)

Lists• Lists have been implemented in Groovy as ArrayLists which store elements of type Object.• Create a list def myList = [1,2,3.6,-9.01,“hello”,“a string”, new Date()]• Create an empty list myList = [ ]• Size of a list myList.size()• Accessing an element of list myList.get( 1 ) or myList[ 1 ] are same.• Add elements to a list myList << 0 << -1 << ‘hello’• Add a list to a list myList << [1,2] << someOtherList• New ways of adding elements to a list myList += 3; myList += [3,5]• Flattening a list of lists

[ 1, [2,3,[4,5],6], 7, [8,9] ].flatten() == [1, 2, 3, 4, 5, 6, 7, 8, 9]

• Nulls are inserted if required.list = ['a', 'b', 'z', 'e', 'u', 'v', 'g']list[8] = 'x'list == ['a', 'b', 'z', 'e', 'u', 'v', 'g', null, 'x']

Lists contd..• Closures as a way to do common updates

myList = myList.collect { it * 2 }

• Closures as a way of operations[1, 2, 3].find{ it > 1 } == 2[1, 2, 3].findAll{ it > 1 } == [2, 3]

Similar keywords are every and any.• To add all elements in a list [1,2,3,4,5,6].sum() == 21• Other operations available on a list :

– Find max. and min. elements– Use –(minus) sign to remove elements from a list.– Stack operations (push, pop) can be done on a list.– Count method gives the number of elements equal to the one passed in method call.– Sort method will sort a list in ascending order.Reverse will reverse a list.

Range• Ranges allow you to create a list of sequential values.• Ranges defined with the .. notation are inclusive, that is they contain both values.• def myRange = 5..8 This will make a range 5,6,7,8• A range can be in both orders, increasing, as well as decreasing.• They are accessed same as Lists.

example: myRange += 4..-3 makes myRange as 5,6,7,8,4,3,2,1,0,-1,-2,-3• Even characters can be added to a range. myRange += ‘a’..’d’• And same strings with different last characters can be added myRange += ‘AAB’..’AAD’. • They find their usage in loops. Example for(count in start..end)• They can be used in switch statements too. Example

switch(value){case 1..10: --------;case 11..25: -------;default: -------;}

• They can be used to create Lists[ 1, *3..5, 7, *9..<12 ] == [1,3,4,5,7,9,10,11]

Maps• Maps have been implemented in Groovy as LinkedhashMap which store elements of type

key:value. By default, Groovy takes key as a String.• Example: def myMap = [name:“Alan", likes:“bread", id:1234]• Empty map is defined as myMap = [ : ]• Values in a map are accessed using key, as usually.• Maps also act like beans so you can use the property notation to get/set items inside the

Map provided that the keys are Strings which are valid Groovy identifiers. Ex:

def map = [name:"Gromit", likes:"cheese", id:1234]

assert map.name == "Gromit"

assert map.id == 1234• Similar operations as that on Lists can be performed on Maps too.

Expandos (The Dynamic Object)• An Expando is like a Map in Groovy or an object in Javascript that do not have to have their

properties in advance. • It allows you to create dynamic objects by making use of Groovy's closure mechanisms.• An Expando is different from a map in that you can provide synthetic methods that you can

call on the object.• Example:

def player = new Expando()

player.name = "Dierk"

player.greeting = { "Hello, my name is $name" }

println player.greeting()

player.name = "Jochen"

println player.greeting()

Note: The closure has access to the properties assigned to the Expando, even though these values may change over time.

Agenda• Introduction to Groovy• Key Features• Closures• Operator Overloading• Array Slicing and looping

• Collections

• Dynamic Methods/Mixins and Properties• Regular Expressions• File IO• Database Operations• Unified Field and Programming Languages

Groovy Way of Handling…

– Dynamic Methods and Properties

– Regular Expressions

– File I/O

– Database Connectivity

Dynamic Method Invocation

• You can invoke a method even if you don't know the method name until it is invoked:class Dog

{ def bark() { println "woof!" }

def sit() { println "(sitting)" }

def jump() { println "boing!" }

}

def doAction( animal, action ){

animal."$action"() //action name is passed at invocation}

def rex = new Dog()

doAction( rex, "bark" ) //prints 'woof!‘

doAction( rex, "jump" ) //prints 'boing!'

Dynamic Methods/mixins

george = new Wombat()george.mixin("say") { something-> println something }george.say("Hello, world!")

george = new Wombat().mixin(FighterType)

william = new Wombat()

georage.getFighter() // returns william.getFighter()//error

Dynamic Properties

• You can also override property access using the getProperty and setProperty property access hooks, Dynamically

class Expandable

{

def storage = [:] //Empty MAP

def getProperty(String name) { storage[name] } //AUTO RETURN

void setProperty(String name, value) { storage[name] = value }

}

def e = new Expandable()

e.foo = "bar"

println e.foo //OUTPUT: bar

Regular Expressions• Groovy supports regular expressions natively using the ~"pattern" expression, • Which compiles a Java Pattern object from the given pattern string.• Groovy also supports the =~ (create Matcher) and ==~ (matches regex) operators.• Packages that are used in Groovy for RegEx

– import java.util.regex.Matcher– import java.util.regex.Pattern

• Regular expression support is imported from Java.

def pattern = ~/foo/

assert pattern instanceof Pattern

assert pattern.matcher("foo").matches()

def matcher = "cheesecheese" =~ /cheese/

assert matcher instanceof Matcher

answer = matcher.replaceAll("edam")

def cheese = ("cheesecheese" =~ /cheese/).replaceFirst("nice") assert cheese == "nicecheese"

Works with standard Java Reader/Writer , InputStream/OutputStream ,File and URL classes

Message Passing … Using Closures

new File("foo.txt").eachLine { line -> println(line) }

Don’t Bother about Resource Closing Mechanism Groovy Methods will handle it.

def fields = ["a":"1", "b":"2", "c":"3"]new File("Foo.txt").withWriter { out -> fields.each() { key, value ->

out.writeLine("${key}=${value}") }}

- No Reader / Writer Object HandlingHandle the resource for you via a closure - which will automatically close down any resource if an exception occurs

- No Data Piping (Stream Management)

- No Exception HandlingThe eachLine() method ensures that the file resource is correctly closed. Similarly if an exception occurs while reading, the resource will be closed too.

File Input / Output

Executing External Processes

Groovy provides a simple way to execute command line processes.def process = "ls -l".execute()process.in.eachLine { line -> println line }

====================

Process p = "cmd /c dir".execute()println "${p.text}“

====================

def initialSize = 4096def outStream = new ByteArrayOutputStream(initialSize) //STREAMSdef errStream = new ByteArrayOutputStream(initialSize) def proc = "ls.exe".execute() proc.consumeProcessOutput(outStream, errStream) proc.waitFor() println 'out:\n' + outStream println 'err:\n' + errStream

SQL can be more Groovy - 1• You can perform queries and SQL statements, passing in variables easily with

proper handling of statements, connections and exception handling.

import groovy.sql.Sql

def foo = 'cake‘

def database = Sql.newInstance( "jdbc:mysql://localhost:3306/mydb", "user",

"pswd",

"com.mysql.jdbc.Driver")

database.eachRow("select * from FOOD where type=${foo}“)

{ println "Smith likes ${it.name}" }

Thanks to closures.

SQL can be more Groovy - 2• You can perform queries and SQL statements, passing in variables easily with

proper handling of statements, connections and exception handling.

import groovy.sql.Sql

def foo = 'cheese‘

def database = Sql.newInstance( "jdbc:mysql://localhost:3306/mydb", "user",

"pswd",

"com.mysql.jdbc.Driver")

def answer = 0

sql.eachRow("select count(*) from FOOD where type=${foo}")

{ row -> answer = row[0] }

Println (“Our menu has $answer dishes to choose from!)

Thanks to closures.

SQL can be more Groovy - 3• You can perform queries and SQL statements, passing in variables easily with

proper handling of statements, connections and exception handling.

import groovy.sql.Sql

def foo = 'cheese‘

def database = Sql.newInstance( "jdbc:mysql://localhost:3306/mydb", "user",

"pswd",

"com.mysql.jdbc.Driver")

def food = database.dataSet('FOOD')

def cheese = food.findAll { it.type == 'cheese' }

cheese.each { println “${it.name} will be delicious" }

Thanks to closures.

Why to Thank Closures ?A typical JDBC Program should have these Steps 1. Loading a database driver2. Creating a oracle JDBC Connection3. Creating a JDBC Statement object4. Executing a SQL statement with the Statement object, and returning a jdbc resultSet.

try {

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");//or any other driver } catch(Exception x){

System.out.println( "Unable to load the driver class!" ); }try {

Connection con = DriverManager.getConnection(url, userid, password);} catch(SQLException ex) {

System.err.println("SQLException: " + ex.getMessage()); }String createString="create table Employees(“+"Employee_ID INTEGER,”+"Name VARCHAR(30))";try {

stmt = con.createStatement(); stmt.executeUpdate(createString);

stmt.close();con.close();

} catch(SQLException ex) {System.err.println("SQLException: " + ex.getMessage());

}

Reduced code noise in Groovy -Simple code is beautiful code

Groovy Will Handle all those common tasks for you, - including Exception Handling, Connection - ResultSet Closing, etc..

import groovy.sql.Sql class GroovySqlExample1{

static void main(args){ database = Sql.newInstance("jdbc:mysql://localhost:3306/words",

"words", "words", "org.gjt.mm.mysql.Driver") database.eachRow("select * from word")

{ row | println row.word_id + " " + row.spelling } //CLOSURE

wid = 999spelling = "Nefarious" pospeech = "Adjective" database.execute("insert into word (word_id, spelling, part_of_speech)

values (${wid}, ${spelling}, ${pospeech})")val = database.execute("select * from word where word_id = ?", [5])//Negetive Indexing sql.eachRow("select * from word"){ grs | println "-1 = " + grs.getAt(-1) //prints part_of_speech println "2 = " + grs.getAt(2) //prints part_of_speech } }

}

top related