1 / 28

A Tour of Groovy

A Tour of Groovy. Chris Wong cwong@makanasolutions.com. Your code in Java …. enum PeriodType { WEEKLY, MONTHLY, QUARTERLY, ANNUALLY } @Entity class Invoice { @Id int id; @OneToMany List<Item> items; PeriodType periodType; public List<Item> getFunnyItems() {

easter
Download Presentation

A Tour of Groovy

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. A Tour of Groovy Chris Wong cwong@makanasolutions.com

  2. Your code in Java … enum PeriodType { WEEKLY, MONTHLY, QUARTERLY, ANNUALLY } @Entity class Invoice { @Id int id; @OneToMany List<Item> items; PeriodType periodType; public List<Item> getFunnyItems() { List<Item> funnyItems = new ArrayList<Item>(); for (Iterator<Item> i = items.iterator(); i.hasNext(); ) { Item item = i.next(); if (item.isFunny()) funnyItems.add(item); } return items; } }

  3. Your code in Groovy! enum PeriodType { WEEKLY, MONTHLY, QUARTERLY, ANNUALLY } @Entity class Invoice { @Id int id; @OneToMany List<Item> items; PeriodType periodType; public List<Item> getFunnyItems() { List<Item> funnyItems = new ArrayList<Item>(); for (Iterator<Item> i = items.iterator(); i.hasNext(); ) { Item item = i.next(); if (item.isFunny()) funnyItems.add(item); } return items; } }

  4. Hello, world Legal code, but can omit plumbing class Foo { public static void main(String[] args) { System.out.println("Hello, world"); } }

  5. Hello, world Groovy also provides some shortcuts … System.out.println("Hello, world");

  6. Hello, world Unnecessary punctuation just adds clutter … System.out.println("Hello, world");

  7. Hello, world System.out.println('Hello, world');

  8. Why Groovy? The power of a dynamic language plus … • JSR 241: Java standard • Two-way contract: • a Groovy class is a Java class: it’s all bytecodes. Groovy and Java can extend each other’s classes. • Seamless integration with Java: annotations, generics, enums, familiar syntax. • The Groovy platform is the Java platform: • the J2SE library, debugging, profiling etc. • Spring, Hibernate, web services, TestNG

  9. Some Groovy language features • Dynamically typed • Closures • Everything is an object. No primitives. • == means equals. Really. • Native syntax for lists, maps, regex • Operator overriding • Compact, expressive, readable

  10. Strings greeting = 'Hello' println "$greeting, world" println """ Today's date is ${new Date().toGMTString()} Nice day, isn't it? """ greeting = "Hello, world" greeting[7] == 'w' greeting[2..4] == 'llo'

  11. Closures • Behavior as objects • Default argument is “it”, optional. def squareIt = { return it * it } assert squareIt(5) == 25 10.times { println “I will not talk in class” } • Captures variables in the lexical scope int x = 10 Closure addToX = { addThis -> x += addThis } addToX(2) assert x == 12

  12. Lists and maps mylist = [1, 2, 3, 4, 5] // an ArrayList assert mylist[0] == 1 mylist[2..3] = [] // deleted 3, 4 [2,3,4].collect { it * 2 } == [4, 6, 8] [1,2,3].find { it > 1 } == 2 [1,2,3,[1,[2,3]]].flatten().unique() == [1, 2, 3] mylist.each { doSomethingWith(it) } mymap = [a:1, b:2, c:3] // a HashMap mymap['a'] == mymap.a // == mymap.get("a") mymap['c'] = 5 // mymap.put("c", 5)

  13. Ranges and regex • Ranges • (1..10).each { it -> println it } • switch (age) { case 15..30: … } • for (i in 1..10) { … } • 'Hello, world'[2..4] == 'llo' • Regex if ('rain' =~ /\b\w*ain\b/) println '"rain" does rhyme with "Spain"!'

  14. Operator overriding Override operators by overriding methods: • a + b a.plus(b) • a[b] a.getAt(b) • a << b a.leftShift(b) • switch (a) { case b: ... } b.isCase(a) • a == b a.equals(b) • a < b a.compareTo(b) < 0

  15. Groovy convenience operators • ?: elvis Java: name = name != null ? name : "default" Groovy: name = name ?: "default" • ?. safe dereference. No worry about nulls. street = user?.address?.street • *. spread dot. Invoke on all items, return list. List result = invoice.lineItems*.total()

  16. // Groovy class MyBean { String item } MyBean b = new MyBean(item:‘foo’) String val = b.item b.item = ‘bar’ b[‘item’] = ‘bar’ // Java class MyBean { private String item; public String getItem() {…} public void setItem(…) {…} } MyBean b = new MyBean(); b.setItem(“foo”); String val = b.getItem(); b.setItem(“bar”) GroovyBeans and JavaBeans

  17. Why brevity matters: Quicksort function sort(array) // pseudocode from Wikipedia var list less, greater if length(array) ≤ 1 return array select a pivot value pivot from array for each x in array if x < pivot then append x to less if x > pivot then append x to greater return concatenate(sort(less), pivot, sort(greater)) -------------------------------------------------------- def sort(list) { // Groovy implementation if (list.size() <= 1) return list def pivot = list[0] def less = list.findAll {it < pivot} def same = list.findAll {it == pivot} def greater = list.findAll {it > pivot} sort(less) + same + sort(greater) }

  18. Quicksort in Java public static void qsort(Comparable[] c,int start,int end){ if(end <= start) return; Comparable comp = c[start]; int i = start,j = end + 1; for(;;){ do i++; while(i<end && c[i].compareTo(comp)<0); do j--; while(j>start && c[j].compareTo(comp)>0); if(j <= i) break; Comparable tmp = c[i]; c[i] = c[j]; c[j] = tmp; } c[start] = c[j]; c[j] = comp; qsort(c,start,j-1); qsort(c,j+1,end); } public static void qsort(Comparable[] c){ qsort(c,0,c.length-1); }

  19. Object graph navigation: GPaths class Invoice { List items; … } class Item { Product product; int total() {…} … } class Product { String name; … } List<Invoice> invoices = …; // get all product names where item total > 7000 List result = invoices.items.grep{it.total() > 7000}.product.name // Java version: List result = new ArrayList(); for (Iterator<Invoice> i = invoices.iterator(); i.hasNext(); ) { List items = i.next().getItems(); for (Iterator j = items.iterator(); j.hasNext(); ) { Item item = (Item) j.next(); if (item.total() > 7000) result.add(item.getProduct().getName()); } }

  20. Dynamic Groovy: multimethods class Equalizer { boolean equals(Equalizer e) {...} boolean equals(Object o) {...} } Object obj = new Equalizer() obj.equals(new Equalizer())

  21. Dynamic Groovy: categories // Dynamically add methods to any class class PersistenceCategory { static void save(Object o) { // save object } } use (PersistenceCategory) { // all objects now have save() method new MyBean().save() }

  22. Dynamic Groovy: meta programming • Change class/object behavior at runtime • Meta-Object Protocol (MOP) • You can intercept method calls and property accesses • invokeMethod(...) • getProperty(...) • setProperty(...) • etc

  23. MarkupBuilder builder = new groovy.xml.MarkupBuilder() builder.numbersAndSquares { description 'Numbers and squares' (3..6).each { number (value: it, square: it*it) } } <numbersAndSquares> <description>Numbers and squares</description> <number value='3' square='9' /> <number value='4' square='16' /> <number value='5' square='25' /> <number value='6' square='36' /> </numbersAndSquares>

  24. SwingBuilder swing = new SwingBuilder() frame = swing.frame(title: 'Hello, world') { panel(layout: new BorderLayout()) { label(text: 'Hello, world', constraints: BorderLayout.CENTER) button(text: 'Exit', constraints: BorderLayout.SOUTH, actionPerformed: { System.exit(0) }) } } frame.pack() frame.show()

  25. Domain-specific languages (DSL) • A DSL “is a mini-language aiming at representing constructs for a given domain” • Groovy features for DSLs: add new methods/properties to classes, override operators. • E.g. unit manipulation: • println 30.km/h + 2.m/s * 2 • println 3 * 3.mg/L • println 1/2.s - 2.Hz

  26. Grails ORM (GORM) class Book { String title String author Date releaseDate } book = Book.get(id) // let's change the title book.title = 'War and Peace' book.save() Book.listOrderByTitle() Book.findByReleaseDateBetween(startDate, endDate)

  27. Groovy warts • SLOW • Write critical areas in Java • Groovy performance rapidly improving • Poor IDE support • IntelliJ IDEA's JetGroovy coming along nicely • Stack dumps are a pain

  28. Questions/discussion Thanks for listening! cwong@makanasolutions.com

More Related