Download greeting = "Hello, world"

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
A Tour of Groovy
Chris Wong
[email protected]
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;
}
}
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;
}
}
Hello, world
Legal code, but can omit plumbing
class Foo {
public static void main(String[] args) {
System.out.println("Hello, world");
}
}
Hello, world
Groovy also provides some shortcuts …
System.out.println("Hello, world");
Hello, world
Unnecessary punctuation just adds clutter …
System.out.println("Hello, world");
Hello, world
System.out.println('Hello, world');
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
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
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'
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
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)
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"!'
Operator overriding
Override operators by overriding methods:






a+b
a[b]
a << b
switch (a) { case b: ... }
a == b
a<b
a.plus(b)
a.getAt(b)
a.leftShift(b)
b.isCase(a)
a.equals(b)
a.compareTo(b) < 0
Groovy convenience operators

?: elvis
Java:
Groovy:

name = name != null ? name : "default"
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()
GroovyBeans and JavaBeans
// Groovy
class MyBean {
String item
}
// Java
class MyBean {
private String item;
public String getItem() {…}
public void setItem(…) {…}
}
MyBean b =
new MyBean(item:‘foo’)
MyBean b = new MyBean();
b.setItem(“foo”);
String val = b.item
String val = b.getItem();
b.item = ‘bar’
b[‘item’] = ‘bar’
b.setItem(“bar”)
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)
}
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);
}
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());
}
}
Dynamic Groovy: multimethods
class Equalizer {
boolean equals(Equalizer e) {...}
boolean equals(Object o) {...}
}
Object obj = new Equalizer()
obj.equals(new Equalizer())
Dynamic Groovy: categories
// Dynamically add methods to any class
class PersistenceCategory
static void save(Object
// save object
}
}
use (PersistenceCategory)
// all objects now have
new MyBean().save()
}
{
o) {
{
save() method
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
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>
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()
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
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)
Groovy warts

SLOW



Poor IDE support


Write critical areas in Java
Groovy performance rapidly improving
IntelliJ IDEA's JetGroovy coming along nicely
Stack dumps are a pain
Questions/discussion
Thanks for listening!
[email protected]
Related documents