Groovy Tutorial

100 %
0 %
Information about Groovy Tutorial
Technology

Published on July 2, 2009

Author: paulk_asert

Source: slideshare.net

Description

Paul King's latest Groovy Tutorial. Feel free to use it for non-commercial use at your Groovy User Group or within your company.

© ASERT 2006-2010 Groovy Tutorial Scripting on the JVM Dr Paul King paulk@asert.com.au @paulk_asert ASERT, Australia

Topics  Introduction • Simple Data Types • Collective Data Types • Control Structures • Closures and Builders © ASERT 2006-2010 • OO • GDK methods • XML • Database interaction • Testing • Metaprogramming ESDC 2010 - 2

What is Groovy? • “Groovy is like a super version of Java. It can leverage Java's enterprise capabilities but also has cool productivity features like closures, DSL support, builders and dynamic typing.” © ASERT 2006-2010 Groovy = Java – boiler plate code + mostly dynamic typing + closures + domain specific languages + builders + metaprogramming + GDK library ESDC 2010 - 3

Groovy Goodies Overview • Fully object oriented • Closures: reusable and assignable pieces of code • Operators can be • GPath: efficient overloaded © ASERT 2006-2010 object navigation • Multimethods • GroovyBeans • Literal declaration for • grep and switch lists (arrays), maps, ranges and regular • Templates, builder, expressions swing, Ant, markup, XML, SQL, XML-RPC, Scriptom, Grails, tests, Mocks ESDC 2010 - 4

Growing Acceptance … A slow and steady start but now gaining in momentum, maturity and mindshare Now free

… Growing Acceptance … © ASERT 2006-2010 ESDC 2010 - 6

… Growing Acceptance … © ASERT 2006-2010 Groovy and Grails downloads: 70-90K per month and growing ESDC 2010 - 7

… Growing Acceptance … © ASERT 2006-2010 Source: http://www.micropoll.com/akira/mpresult/501697-116746 Source: http://www.grailspodcast.com/ ESDC 2010 - 8

… Growing Acceptance … © ASERT 2006-2010 http://www.jroller.com/scolebourne/entry/devoxx_2008_whiteboard_votes http://www.java.net ESDC 2010 - 9

… Growing Acceptance … What alternative JVM language are you using or intending to use © ASERT 2006-2010 http://www.leonardoborges.com/writings ESDC 2010 - 10

… Growing Acceptance … © ASERT 2006-2010 http://it-republik.de/jaxenter/quickvote/results/1/poll/44 (translated using http://babelfish.yahoo.com) ESDC 2010 - 11

… Growing Acceptance … © ASERT 2006-2010 http://pollpigeon.com/jsf-grails-wicket/r/25665/ ESDC 2010 - 12

… Growing Acceptance © ASERT 2006-2010 ESDC 2010 - 13

The Landscape of JVM Languages mostly dynamic typing © ASERT 2006-2010 Dynamic features call for dynamic types Java bytecode calls for static types The terms “Java Virtual Machine” and “JVM” mean a Virtual Machine for the Java™ platform. ESDC 2010 - 14

Groovy Starter System.out.println("Hello, World!"); // optional semicolon, println 'Hello, World!' // System.out, brackets, // main() method, class defn def name = 'Guillaume' // dynamic typing println "$name, I'll get the car." // GString String longer = """${name}, the car is in the next row.""" // multi-line string © ASERT 2006-2010 // with static typing assert 0.5 == 1/2 // BigDecimal equals() def printSize(obj) { // optional duck typing print obj?.size() // safe dereferencing } def pets = ['ant', 'bee', 'cat'] // native list syntax pets.each { pet -> // closure support assert pet < 'dog' // overloading '<' on String } // or: for (pet in pets)... ESDC 2010 - 15

A Better Java... import java.util.List; import java.util.ArrayList; class Erase { private List removeLongerThan(List strings, int length) { This code List result = new ArrayList(); for (int i = 0; i < strings.size(); i++) { is valid String s = (String) strings.get(i); Java and if (s.length() <= length) { result.add(s); valid Groovy } } © ASERT 2006-2010 return result; } public static void main(String[] args) { List names = new ArrayList(); names.add("Ted"); names.add("Fred"); names.add("Jed"); names.add("Ned"); System.out.println(names); Based on an Erase e = new Erase(); example by List shortNames = e.removeLongerThan(names, 3); Jim Weirich System.out.println(shortNames.size()); for (int i = 0; i < shortNames.size(); i++) { & Ted Leung String s = (String) shortNames.get(i); System.out.println(s); } } } ESDC 2010 - 16

...A Better Java... import java.util.List; import java.util.ArrayList; class Erase { private List removeLongerThan(List strings, int length) { Do the List result = new ArrayList(); for (int i = 0; i < strings.size(); i++) { semicolons String s = (String) strings.get(i); add anything? if (s.length() <= length) { result.add(s); And shouldn‟t } } we us more © ASERT 2006-2010 } return result; modern list public static void main(String[] args) { notation? List names = new ArrayList(); names.add("Ted"); names.add("Fred"); Why not names.add("Jed"); names.add("Ned"); System.out.println(names); import common Erase e = new Erase(); libraries? List shortNames = e.removeLongerThan(names, 3); System.out.println(shortNames.size()); for (int i = 0; i < shortNames.size(); i++) { String s = (String) shortNames.get(i); System.out.println(s); } } } ESDC 2010 - 17

...A Better Java... class Erase { private List removeLongerThan(List strings, int length) { List result = new ArrayList() for (String s in strings) { if (s.length() <= length) { result.add(s) } } return result } public static void main(String[] args) { © ASERT 2006-2010 List names = new ArrayList() names.add("Ted"); names.add("Fred") names.add("Jed"); names.add("Ned") System.out.println(names) Erase e = new Erase() List shortNames = e.removeLongerThan(names, 3) System.out.println(shortNames.size()) for (String s in shortNames) { System.out.println(s) } } } ESDC 2010 - 18

...A Better Java... class Erase { private List removeLongerThan(List strings, int length) { List result = new ArrayList() for (String s in strings) { if (s.length() <= length) { result.add(s) Do we need } the static types? } return result Must we always } have a main public static void main(String[] args) { method and © ASERT 2006-2010 List names = new ArrayList() names.add("Ted"); names.add("Fred") class definition? names.add("Jed"); names.add("Ned") System.out.println(names) How about Erase e = new Erase() List shortNames = e.removeLongerThan(names, 3) improved System.out.println(shortNames.size()) consistency? for (String s in shortNames) { System.out.println(s) } } } ESDC 2010 - 19

...A Better Java... def removeLongerThan(strings, length) { def result = new ArrayList() for (s in strings) { if (s.size() <= length) { result.add(s) } } return result } © ASERT 2006-2010 names = new ArrayList() names.add("Ted") names.add("Fred") names.add("Jed") names.add("Ned") System.out.println(names) shortNames = removeLongerThan(names, 3) System.out.println(shortNames.size()) for (s in shortNames) { System.out.println(s) } ESDC 2010 - 20

...A Better Java... def removeLongerThan(strings, length) { def result = new ArrayList() for (s in strings) { if (s.size() <= length) { result.add(s) Shouldn‟t we } } have special return result notation for lists? } And special © ASERT 2006-2010 names = new ArrayList() facilities for names.add("Ted") names.add("Fred") list processing? names.add("Jed") Is „return‟ names.add("Ned") System.out.println(names) needed at end? shortNames = removeLongerThan(names, 3) System.out.println(shortNames.size()) for (s in shortNames) { System.out.println(s) } ESDC 2010 - 21

...A Better Java... def removeLongerThan(strings, length) { strings.findAll{ it.size() <= length } } names = ["Ted", "Fred", "Jed", "Ned"] System.out.println(names) shortNames = removeLongerThan(names, 3) System.out.println(shortNames.size()) shortNames.each{ System.out.println(s) } © ASERT 2006-2010 ESDC 2010 - 22

...A Better Java... def removeLongerThan(strings, length) { strings.findAll{ it.size() <= length } } Is the method names = ["Ted", "Fred", "Jed", "Ned"] now needed? System.out.println(names) shortNames = removeLongerThan(names, 3) Easier ways to System.out.println(shortNames.size()) use common shortNames.each{ System.out.println(s) } methods? © ASERT 2006-2010 Are brackets required here? ESDC 2010 - 23

...A Better Java... names = ["Ted", "Fred", "Jed", "Ned"] println names shortNames = names.findAll{ it.size() <= 3 } println shortNames.size() shortNames.each{ println it } © ASERT 2006-2010 ESDC 2010 - 24

...A Better Java names = ["Ted", "Fred", "Jed", "Ned"] println names shortNames = names.findAll{ it.size() <= 3 } println shortNames.size() shortNames.each{ println it } © ASERT 2006-2010 [Ted, Fred, Jed, Ned] 3 Ted Jed Ned ESDC 2010 - 25

Better JavaBeans... import java.math.BigDecimal; ... public class BikeJavaBean { public void setModel(String model) { private String manufacturer; this.model = model; private String model; } private int frame; private String serialNo; public int getFrame() { private double weight; return frame; private String status; } private BigDecimal cost; public String getSerialNo() { public BikeJavaBean(String manufacturer, String model, return serialNo; int frame, String serialNo, } double weight, String status) { this.manufacturer = manufacturer; public void setSerialNo(String serialNo) { this.model = model; this.serialNo = serialNo; this.frame = frame; } this.serialNo = serialNo; © ASERT 2006-2010 this.weight = weight; public double getWeight() { this.status = status; return weight; } } public String toString() { public void setWeight(double weight) { return "Bike:“ + this.weight = weight; “n manufacturer -- " + manufacturer + } "n model -- " + model + "n frame -- " + frame + public String getStatus() { "n serialNo -- " + serialNo + return status; "n"; } } public void setStatus(String status) { public String getManufacturer() { this.status = status; return manufacturer; } } public BigDecimal getCost() { public void setManufacturer(String manufacturer) { return cost; this.manufacturer = manufacturer; } } public void setCost(BigDecimal cost) { public String getModel() { this.cost = cost.setScale(3, BigDecimal.ROUND_HALF_UP); return model; } } } ... Modified example from: http://www.ibm.com/developerworks/library/j-pg09196.html ESDC 2010 - 26

...Better JavaBeans... import java.math.BigDecimal; ... public class BikeJavaBean { public void setModel(String model) { Auto private String manufacturer; this.model = model; private String model; private int frame; } getters? private String serialNo; private double weight; private String status; public int getFrame() { } return frame; Auto private BigDecimal cost; public String getSerialNo() { setters? public BikeJavaBean(String manufacturer, String model, return serialNo; int frame, String serialNo, double weight, String status) { } Auto this.manufacturer = manufacturer; this.model = model; this.frame = frame; } this.serialNo = serialNo; construction? public void setSerialNo(String serialNo) { this.serialNo = serialNo; © ASERT 2006-2010 this.weight = weight; public double getWeight() { this.status = status; return weight; } } public String toString() { public void setWeight(double weight) { return "Bike:“ + this.weight = weight; “n manufacturer -- " + manufacturer + } "n model -- " + model + "n frame -- " + frame + public String getStatus() { "n serialNo -- " + serialNo + return status; "n"; } } public void setStatus(String status) { public String getManufacturer() { this.status = status; return manufacturer; } } public BigDecimal getCost() { public void setManufacturer(String manufacturer) { return cost; this.manufacturer = manufacturer; } } public void setCost(BigDecimal cost) { public String getModel() { this.cost = cost.setScale(3, BigDecimal.ROUND_HALF_UP); return model; } } } ... ESDC 2010 - 27

... Better JavaBeans ... class BikeGroovyBean { String manufacturer, model, serialNo, status final Integer frame Double weight BigDecimal cost public void setCost(BigDecimal newCost) { cost = newCost.setScale(3, BigDecimal.ROUND_HALF_UP) © ASERT 2006-2010 } public String toString() { return """Bike: manufacturer -- $manufacturer model -- $model More complicated than frame -- $frame normal because we want: serialNo -- $serialNo * Read only frame """ * Custom setter for cost } * Custom toString() } ESDC 2010 - 28

... Better JavaBeans class BikeGroovyBean { String manufacturer, model, serialNo, status Integer frame Double weight BigDecimal cost } © ASERT 2006-2010 In more typical cases it is often as simple as this. ESDC 2010 - 29

Topics • Introduction  Simple Data Types  Numbers, Other 'Primitives', Strings, Regexs, Dates & Times • Collective Data Types • Control Structures • © ASERT 2006-2010 Closures and Builders • OO • GDK methods • XML • Database interaction • Testing • Metaprogramming ESDC 2010 - 30

Numbers • Java numbers byte b1 = 42; Byte b2 = 42 short s1 = 20000; Short s2 = 20000 – But with primitive int i1 = 1000000000 types autoboxed to Integer i2 = 1000000000 def i3 = 42 equivalent wrapper long l1 = 1000000000000000000 types Long l2 = 1000000000000000000 def l3 = 42L – Sizes supported: © ASERT 2006-2010 Byte, Short, float f1 = 3.5f; Float f2 = 3.5 Integer, Long, def f3 = 3.5f double d1 = 3.5e40; Double d2 = 3.5e40 Float, Double, def d3 = 3.5d BigInteger, BigInteger bi = 30g BigDecimal BigDecimal bd1 = 3.5g def bd2 = 3.5 – Some special treatment when assert 2 instanceof Integer assert !2.equals(4) handling arrays assert 3.5 instanceof BigDecimal and in Interfaces assert (7/2) instanceof BigDecimal ESDC 2010 - 31

Parsing Strings to Numbers def string = "300" assert string.isNumber() // check if string appears to be a number // OK, now convert to number in different ways def i4 = string.toInteger() def i5 = string as int def i6 = string as Integer def i7 = new Integer(string) def i8 = Integer.parseInt(string) def i9 = (int) java.text.NumberFormat.instance.parse(string) // Long © ASERT 2006-2010 string = "300.5" def n1 = java.text.NumberFormat.instance.parse(string) // Double def n2 = string.toFloat() def n3 = string.toDouble() def n4 = string.toBigDecimal() integerPattern = /^[+-]?d+$/ // regex notation assert '-36' ==~ integerPattern // explained later assert !('abc' =~ integerPattern) decimalPattern = /^-?(?:d+(?:.d*)?|.d+)$/ assert '37.5' ==~ decimalPattern ESDC 2010 - 32

Other 'primitive' types • boolean and char – Again replaced by wrapper counterparts automatically – We'll see a little bit more about chars under Strings – There is a notion called 'Groovy Truth' whereby any expression can be used where Java would require a © ASERT 2006-2010 boolean and the expression will be evaluated • The numbers 0 and 0.0 and null objects return false • Empty Strings, Lists, Maps, Matchers, ... return false • Other objects return true Found 4 vowels: def vowels = 'aeiou' [e, i, o, u] def sentences = ['The quick brown fox', 'Flyby'] Nothing found sentences.each { sentence -> def found = sentence.toList().intersect(vowels.toList()) if (found) println "Found ${found.size()} vowels: $found" else println 'Nothing found' } ESDC 2010 - 33

Strings... • Several forms // normal strings def firstname = 'Kate' – Single quotes for assert firstname instanceof String simple strings def surname = "Bush" assert firstname * 2 == 'KateKate' – Double quotes for def fullname = GStrings which firstname + ' ' + surname assert fullname == 'Kate Bush' support variable © ASERT 2006-2010 expansion // GString fullname = "$firstname $surname" – Slashy strings assert fullname instanceof GString behave like assert fullname == 'Kate Bush' GStrings but assert fullname - firstname == ' Bush' assert fullname.padLeft(10) == preserve ' Kate Bush' backslashes (great for regex and // indexing (including ranges) assert fullname[0..3] == firstname directory names) assert fullname[-4..-1] == surname – Multi-line versions assert fullname[5, 3..1] == 'Beta' ESDC 2010 - 34

…Strings… // Multi-line strings def tt = ''' def lines = tt.split('n') She sells, sea shells assert lines.size() == 2 By the sea shore''' lines = address.readLines() assert lines.size() == 3 assert tt instanceof String assert lines[-1] == 'New York' assert tt.startsWith('She') assert tt.endsWith('shore') // slashy string: (almost) no escaping assert tt.contains('n') def path = /C:WindowsSystem32/ © ASERT 2006-2010 def address = """ def plain = 'nrtbf$' $fullname assert plain.size() == 7 123 First Ave def slashy = /nrtbf$/ New York assert slashy.size() == 14 """.trim() // late binding trick with closures println """ fullname = "${-> firstname} $surname" --------------------- assert fullname == 'Kate Bush' | $fullname | firstname = 'George' | 123 First Ave | surname = 'Clooney' | New York | assert fullname == 'George Bush' --------------------- """ ESDC 2010 - 35

…Strings... // more substrings (minus removes first occurrence) string = 'hippopotamus' assert string - 'hippo' - 'mus' + 'to' == 'potato' assert string.replace('ppopotam','bisc') == 'hibiscus' // processing characters (more on collections later) def letters = 'apple'.toList() assert letters == ['a', 'p', 'p', 'l', 'e'] © ASERT 2006-2010 assert letters[0] instanceof String letters = 'apple'.toList()*.toCharacter() def expected = ['a', 'p', 'p', 'l', 'e'] as char[] assert letters == expected assert letters[0] instanceof Character assert letters instanceof List assert expected instanceof char[] string = "an apple a day" assert string.toList().unique().sort().join() == ' adelnpy' ESDC 2010 - 36

…Strings... // reversing chars/words assert 'string'.reverse() == 'gnirts' assert 'two words'.split().reverse().join(' ') == 'words two' string = 'Yoda said, "can you see this?"' revwords = string.split(' ').reverse().join(' ') assert revwords == 'this?" see you "can said, Yoda' © ASERT 2006-2010 revwords = string.replaceAll(/(w*)/) { all, match -> match.reverse() } assert revwords == 'adoY dias, "nac uoy ees siht?"' revwords = string.replaceAll(/(w*) (w*)(W*)/ * 3, '$2 $1$3$8 $7$6$5 $4$9') assert revwords == 'said Yoda, "this see you can?"' • Find out more through Javadoc, GDK doc – Can also lookup GString but usually no need ESDC 2010 - 37

…Strings... • javadoc © ASERT 2006-2010 ESDC 2010 - 38

…Strings • groovy-jdk (just the additions) © ASERT 2006-2010 ESDC 2010 - 39

Regular Expressions... assert "Hello World!" =~ /Hello/ // Find operator assert "Hello World!" ==~ /Hellob.*/ // Match operator def p = ~/Hellob.*/ // Pattern operator assert p.class.name == 'java.util.regex.Pattern' def input = "Voting is open between 01 Nov 2008 and 04 Nov 2008" def dateFormat = /dd? ... d{4}/ def matches = (input =~ dateFormat) © ASERT 2006-2010 assert matches[1] == '04 Nov 2008' 01 Nov 2008 matches.each { m -> println m } 04 Nov 2008 input.eachMatch(dateFormat) { m -> println m } assert input.findAll(dateFormat) == ['01 Nov 2008', '04 Nov 2008'] println input.replaceAll(dateFormat, '?/?/?') Voting is open between ?/?/? and ?/?/? ESDC 2010 - 40

...Regular Expressions // "Voting is open between 01 Nov 2008 and 04 Nov 2008" def dateFormatGroups = /(dd?) (...) (d{4})/ def matchingGroups = (input =~ dateFormatGroups) assert matchingGroups[1][1] == '04' matchingGroups.each { all, d, m, y -> println "$d/$m/$y" } © ASERT 2006-2010 input.eachMatch(dateFormatGroups) { all, d, m, y -> println "$d/$m/$y" } 01/Nov/2008 04/Nov/2008 assert input.findAll(dateFormatGroups) { full, d, m, y -> "$m $d of $y" } == ['Nov 01 of 2008', 'Nov 04 of 2008'] println input.replaceAll(dateFormatGroups) { full, d, m, y -> "$m $d ????" } Voting is open between Nov 01 ???? and Nov 04 ???? ESDC 2010 - 41

Abbreviated regex notation Symbol Meaning . Any character ^ Start of line (or start of document, when in single-line mode) $ End of line (or end of document, when in single-line mode) d Digit character D Any character except digits s Whitespace character S Any character except whitespace w Word character © ASERT 2006-2010 W Any character except word characters b Word boundary () Grouping (x|y) x or y as in (Groovy|Java|Ruby) x* Zero or more occurrences of x x+ One or more occurrences of x x? Zero or one occurrence of x x{m,n} At least m and at most n occurrences of x x{m} Exactly m occurrences of x [a-f] Character class containing the characters a, b, c, d, e, f [^a] Character class containing any character except a (?=regex) Positive lookahead (?<=text) Positive lookbehind ESDC 2010 - 42

Dates... • Similar to Java – Use java.util.Date, java.util.Calendar, java.sql.Date, ... – Can use static imports to help – Or 3rd party package like Joda Time • Special support for changing times: © ASERT 2006-2010 date2 = date1 + 1 // day date2 = date1 + 1.week – 3.days + 6.hours • Utility methods for date input and output – Date.parse(formatString, dateString) – date.format(formatString) – date.timeString, date.dateString, date.dateTimeString • Potentially will change with JSR 310 ESDC 2010 - 43

... Dates... import static java.util.Calendar.getInstance as now import java.util.GregorianCalendar as D import org.codehaus.groovy.runtime.TimeCategory println new D(2007,11,25).time println now().time Tue Dec 25 00:00:00 EST 2007 Thu Jun 28 10:10:34 EST 2007 def date = new Date() + 1 Fri Jun 29 10:10:35 EST 2007 © ASERT 2006-2010 println date Tue Jul 17 11:10:35 EST 2007 Date was Jun/03/1998 use(TimeCategory) { println new Date() + 1.hour + 3.weeks - 2.days } dateStr = "1998-06-03" date = Date.parse("yyyy-MM-dd", dateStr) println 'Date was ' + date.format("MMM/dd/yyyy") def holidays = boxingDay..newYearsEve ESDC 2010 - 44

... Dates import static java.util.Calendar.* def nowCal = Calendar.instance y = nowCal.get(YEAR) Date nowDate = nowCal.time def (m, d) = [nowDate[MONTH] + 1, nowDate[DATE]] println "Today is $d $m $y" nowCal.set DATE, 1 nowCal.set MONTH, FEBRUARY println "Changed to $nowCal.time" © ASERT 2006-2010 Today is 26 9 2008 Changed to Fri Feb 01 23:05:20 EST 2008 cal = Calendar.instance cal.set 1988, APRIL, 4, 0, 0, 0 date = cal.time def (doy, woy, y) = [DAY_OF_YEAR, WEEK_OF_YEAR, YEAR].collect{ date[it] } println "$date is day $doy and week $woy of year $y" Mon Apr 04 00:00:00 EST 1988 is day 95 and week 15 of year 1988 ESDC 2010 - 45

Operator Overloading... © ASERT 2006-2010 ESDC 2010 - 46

...Operator Overloading... © ASERT 2006-2010 ESDC 2010 - 47

...Operator Overloading © ASERT 2006-2010 • Can be used with your own types too shoppingCart << clickedItem ESDC 2010 - 48

Topics • Introduction • Simple Data Types  Collective Data Types • Control Structures • Closures and Builders © ASERT 2006-2010 • OO • GDK methods • XML • Database interaction • Testing • Metaprogramming ESDC 2010 - 49

Better Lists, Maps, Ranges • Lists/Collections – Special literal syntax – Additional common methods (operator overloading) def list = [3, new Date(), 'Jan'] assert list + list == list * 2 • Maps © ASERT 2006-2010 – Special literal syntax & GDK methods def map = [a: 1, b: 2] assert map['a'] == 1 && map.b == 2 • Ranges – Special syntax for various kinds of ranges def letters = 'a'..'z' def numbers = 0..<10 assert letters.size() + numbers.size() == 36 ESDC 2010 - 50

Topics • Introduction • Simple Data Types • Collective Data Types  Control Structures • Closures and Builders © ASERT 2006-2010 • OO • GDK methods • XML • Database interaction • Testing • Metaprogramming ESDC 2010 - 51

Better Control Structures: Branching/Loops • Branching and loops • Loop-like Closures for (int i = 0; i < n; i++) { } myMap.each { key, value -> for (Type item : iterable) { } println "$key : $value" for (item in iterable) { } } // if (condition) ... // each, every, collect, any, // else if (condition) ... // inject, find, findAll, // else ... // upto, downto, times, grep, © ASERT 2006-2010 // throw, try...catch...finally // reverseEach, eachMatch, // for, while // eachWithIndex, eachLine // d = a ? b : c // eachFile, eachFileMatch, // a = b ?: c // eachByte, combinations ... // d = a?.b?.c • Groovy Truth words = ['bob', 'alpha', 'ehcache', if (1) // ... 'rotator', 'omega', 'reviver'] if (object) // ... bigPalindromes = words.findAll{ w -> if (collection) // ... w == w.reverse() && w.size() > 4} if (map) // ... assert bigPalindromes == if (matcher) // ... ['ehcache', 'rotator', 'reviver'] ESDC 2010 - 52

Better Control Structures: Switch switch (10) { case 0 : assert false ; break case 0..9 : assert false ; break case [8,9,11] : assert false ; break case Float : assert false ; break case {it%3 == 0} : assert false ; break case ~/../ : assert true ; break © ASERT 2006-2010 default : assert false ; break } • Extensible – Implement your own isCase() method ESDC 2010 - 53

Topics • Introduction • Simple Data Types • Collective Data Types • Control Structures  Closures and Builders © ASERT 2006-2010 • OO • GDK methods • XML • Database interaction • Testing • Metaprogramming ESDC 2010 - 54

Using Closures... • Traditional mainstream languages – Data can be stored in variables, passed around, combined in structured ways to form more complex data; code stays put where it is defined • Languages supporting closures – Data and code can be stored in variables, passed © ASERT 2006-2010 around, combined in structured ways to form more complex algorithms and data doubleNum = { num -> num * 2 } println doubleNum(3) // => 6 processThenPrint = { num, closure -> num = closure(num); println "num is $num" } processThenPrint(3, doubleNum) // => num is 6 processThenPrint(10) { it / 2 } // => num is 5 ESDC 2010 - 55

...Using Closures... import static Math.* Algorithm piE differs by 1.0206946399193839E-11 Algorithm piF differs by 1.0070735356748628E-9 Algorithm piC differs by 2.668102068170697E-7 piA = { 22 / 7 } Algorithm piD differs by 4.813291008076703E-5 piB = { 333/106 } Algorithm piB differs by 8.321958979307098E-5 piC = { 355/113 } Algorithm piA differs by 0.001264489310206951 piD = { 0.6 * (3 + sqrt(5)) } piE = { 22/17 + 37/47 + 88/83 } piF = { sqrt(sqrt(2143/22)) } © ASERT 2006-2010 howCloseToPI = { abs(it.value() - PI) } algorithms = [piA:piA, piB:piB, piC:piC, piD:piD, piE:piE, piF:piF] findBestPI(algorithms) def findBestPI(map) { map.entrySet().sort(howCloseToPI).each { entry -> def diff = howCloseToPI(entry) println "Algorithm $entry.key differs by $diff" } } ESDC 2010 - 56

...Using Closures... • Used for many things in Groovy: • Iterators new File('/x.txt').eachLine { println it • Callbacks } • Higher-order functions • Specialized control structures • Dynamic method definition © ASERT 2006-2010 • Resource allocation 3.times { println 'Hi' } • Threads [0, 1, 2].each { number -> • Continuations println number } def houston(Closure doit) { (10..1).each { count -> [0, 1, 2].each { println it} doit(count) } def printit = { println it } } [0, 1, 2].each printit houston { println it } ESDC 2010 - 57

...Using Closures... map = ['a': 1, 'b': 2] map.each {key, value -> map[key] = value * 2} assert map == ['a': 2, 'b': 4] doubler = {key, value -> map[key] = value * 2} map.each(doubler) © ASERT 2006-2010 assert map == ['a': 4, 'b': 8] def doubleMethod(entry) { map[entry.key] = entry.value * 2 } doubler = this.&doubleMethod map.each(doubler) assert map == ['a': 8, 'b': 16] ESDC 2010 - 58

...Using Closures... assert [1, 2, 3].grep{ it < 3 } == [1, 2] assert [1, 2, 3].any{ it % 2 == 0 } assert [1, 2, 3].every{ it < 4 } assert (1..9).collect{it}.join() == '123456789' assert (1..4).collect{it * 2}.join() == '2468' def add = { x, y -> x + y } © ASERT 2006-2010 def mult = { x, y -> x * y } assert add(1, 3) == 4 assert mult(1, 3) == 3 def min = { x, y -> [x, y].min() } def max = { x, y -> [x, y].max() } def triple = mult.curry(3); assert triple(2) == 6 def atLeastTen = max.curry(10) assert atLeastTen(5) == 10 assert atLeastTen(15) == 15 ESDC 2010 - 59

...Using Closures def pairWise(list, Closure invoke) { if (list.size() < 2) return [] def next = invoke(list[0], list[1]) return [next] + pairWise(list.tail(), invoke) } © ASERT 2006-2010 // using min, max, etc. From previous slide assert pairWise(1..5, add) == [3, 5, 7, 9] assert pairWise(1..5, mult) == [2, 6, 12, 20] assert pairWise(1..5, min) == [1, 2, 3, 4] assert pairWise(1..5, max) == [2, 3, 4, 5] assert 'cbaxabc' == ['a', 'b', 'c'].inject('x') { result, item -> item + result + item } ESDC 2010 - 60

Better Design Patterns: Builder • Markup Builder <html> import groovy.xml.* <head> def page = new MarkupBuilder() <title>Hello</title> page.html { </head> head { title 'Hello' } <body> body { © ASERT 2006-2010 <ul> ul { <li>world 1</li> for (count in 1..5) { <li>world 2</li> li "world $count" <li>world 3</li> } } } } <li>world 4</li> <li>world 5</li> </ul> </body> </html> ESDC 2010 - 61

SwingBuilder import java.awt.FlowLayout builder = new groovy.swing.SwingBuilder() langs = ["Groovy", "Ruby", "Python", "Pnuts"] gui = builder.frame(size: [290, 100], title: 'Swinging with Groovy!') { panel(layout: new FlowLayout()) { panel(layout: new FlowLayout()) { for (lang in langs) { © ASERT 2006-2010 checkBox(text: lang) } } button(text: 'Groovy Button', actionPerformed: { builder.optionPane(message: 'Indubitably Groovy!'). createDialog(null, 'Zen Message').show() }) button(text: 'Groovy Quit', actionPerformed: {System.exit(0)}) } } gui.show() Source: http://www.ibm.com/developerworks/java/library/j-pg04125/ ESDC 2010 - 62

SwingXBuilder import groovy.swing.SwingXBuilder © ASERT 2006-2010 import static java.awt.Color.* import static java.lang.Math.* def swing = new SwingXBuilder() def frame = swing.frame(size: [300, 300]) { graph(plots: [ [GREEN, {value -> sin(value)}], [BLUE, {value -> cos(value)}], [RED, {value -> tan(value)}] ]) }.show() ESDC 2010 - 63

GraphicsBuilder def colors = ['red','darkOrange','blue','darkGreen'] (0..3).each { index -> star( cx: 50 + (index*110), cy: 50, or: 40, ir: 15, borderColor: 'black', count: 2+index, fill: colors[index] ) star( cx: 50 + (index*110), cy: 140, or: 40, ir: 15, borderColor: 'black‘, count: 7+index, fill: colors[index] ) } © ASERT 2006-2010 ESDC 2010 - 64

AntBuilder... def ant = new AntBuilder() ant.echo("hello") // let's just call one task // create a block of Ant using the builder pattern ant.sequential { myDir = "target/AntTest/" mkdir(dir: myDir) © ASERT 2006-2010 copy(todir: myDir) { fileset(dir: "src/test") { include(name: "**/*.groovy") } } echo("done") } // now let's do some normal Groovy again file = new File("target/test/AntTest.groovy") assert file.exists()

Add a comment

Related presentations

Related pages

The Groovy programming language - Learn

Learn. Welcome to the learning section of the Groovy website. First of all, you will need to get started by installing Groovy on your system or project.
Read more

Groovy with Eclipse - Tutorial - Eclipse, Android and Java ...

Groovy This article gives a short overview of the Groovy language including collections, loops, gstrings, MOP, closures, operator overloading, XML handing ...
Read more

Fluently Groovy - IBM - United States

This tutorial is for Java developers unfamiliar with Groovy, who want a quick and easy introduction to the basics. Get started with Groovy's simplified ...
Read more

The Groovy programming language - Install Groovy

In this download area, you will be able to download the distribution (binary and source), the Windows installer and the documentation for Groovy.
Read more

Groovy Tutorial for Java Developers – Part 1: The Basics ...

This tutorial aims for developers that are already familiar with Java. It focuses on Groovy specific features and does not explain basic programming knowledge.
Read more

Groovy Tutorials - JavaBeat

Groovy enVironment Manager (GVM) is a tool used for managing the multiple version of the software development kits in the Unix based systems. In the ...
Read more

Grails Tutorial for Beginners - Grails Cookbook

Grails Tutorial for Beginners. Grails is a web application framework that is great to use for real projects. It is also very friendly for beginners to learn.
Read more

Groovy & Grails Tutorial - Part 1 - What is Groovy - YouTube

Learn Groovy programming and the Grails platform! Groovy is part of the new generation of dynamic languages for the JVM. Watch the complete 54 ...
Read more

Grails Tutorial for Beginners - Playing with Groovy ...

Grails Tutorial for Beginners - Playing with Groovy Language. Jul 27, 2013 Beginner, Groovy, Tutorial comments Grails is a powerful framework that makes ...
Read more

Introduction to Groovy - Scripting Language

Introduction to Groovy - Scripting Language. Introduction to Groovy - Scripting Language. JavaBeat. Home; ... Groovy Tutorials; Creating JSON using Groovy;
Read more