46
The Way by Dogaru Gabriel

The Groovy Way

Embed Size (px)

DESCRIPTION

Groovy tech talk held at my company

Citation preview

Page 1: The Groovy Way

The Way

by Dogaru Gabriel

Page 2: The Groovy Way
Page 3: The Groovy Way
Page 4: The Groovy Way

AgendaAgenda• What is Groovy ?• Candies• Closures• Dynamic Groovy• Groovy builders• Integrating java and groovy• More Groovy Cool Stuff

Page 5: The Groovy Way

#!/usr/bin/rubyclass Persondef initialize(lname, fname)@lname = lname@fname = fnameend

attr_reader :lname, :fnameattr_writer :lname, :fnameend

steve = Person.new("Litt", "Stove")print "My name is ", steve.fname, " ", steve.lname, ".\n"steve.fname = "Steve"print "My name is ", steve.fname, " ", steve.lname, ".\n"

Page 6: The Groovy Way

6

>+++++++++[<+++++++>-]<++++.---------.>>++++++++++[<+++++++++>-]<++.<++++.,>>>++++++++++.>>+++++++++[<+++++++>-]<+++.>>+++++++++++[<+++++++++>-]<--.+++.>>++++++[<+++++>-]<++.>>+++++++++++[<+++++++++>-]<.>>+++++++++++[<++++++++++>-]<+.--..>>+++++++++++[<+++++++++>-]<--.>>+++++++++++[<++++++++++>-]<.>>+++++++++++[<+++++++++>-]<+.>>++++++[<+++++>-]<++.>>+++++++++++[<++++++++++>-]<+.+++.>>++++++[<+++++>-]<++.>>+++++++++++[<+++++++++>-]<+++.>>+++++++++++++++[<+++++++>-]<.+++.-------.>>++++++[<+++++>-]<++.>>+++++++++++[<++++++++++>-]<.>>+++++++++++[<+++++++++>-]<--.>>+++++++++++[<++++++++++>-]<-.>>+++++++++++++++[<+++++++>-]<----.>>++++++++++.

Page 7: The Groovy Way

What is Groovy ?What is Groovy ?• “Groovy is what Java would look like had it been written

in the 21st century.”• an agile and dynamic language for the JVM• inspired by languages like Python, Ruby and Smalltalk • compiles straight to Java bytecode, integrates natively

with java• compiled or interpreted• supports Domain-Specific Languages and other compact

syntax

Page 8: The Groovy Way

Other Cool FeaturesOther Cool Features● expressive java-like syntax● same oo and libs and java properties ● suports strong/weak typing● operator overloading● Gstrings● Closures● Almost 0 learning curve for java developers

Page 9: The Groovy Way

import java.util.List;import java.util.ArrayList;

public class Speaker {

private Integer age; private String name;

public String toString() { return name + " - " + age; }

public Integer getAge() { return age; }

public void setAge(Integer age) { this.age = age; }

public String getName() { return name; }

public void setName(String name) { this.name = name; }

public static void main(String[] args) { List<Speaker> speakers = new

ArrayList<Speaker>(); Speaker ion = new Speaker(); ion.setName("Ion"); ion.setAge(15); Speaker john = new Speaker(); john.setName("John"); john.setAge(25);

speakers.add(ion); speakers.add(john);

for(Speaker s: speakers){ if (s.getAge()>20)

System.out.println(s.toString().toUpperCase()); } }}

Javaclass Speaker { def age String name

String toString() { return "${name} - $age" }}

def speakers = [ new Speaker(name: "john", age: 15) , new Speaker (name: "ionel", age: 29)]

def upper = {it.toString().toUpperCase()}

speakers.findAll{s -> s.age >20} .collect(upper).each{println it}

Groovyimport java.util.List;import java.util.ArrayList;

public class Speaker {

private Integer age; private String name;

public String toString() { return name + " - " + age; }

public Integer getAge() { return age; }

public void setAge(Integer age) { this.age = age; }

public String getName() { return name; }

public void setName(String name) { this.name = name; }

public static void main(String[] args) { List<Speaker> speakers = new ArrayList<Speaker>(); Speaker ion = new Speaker(); ion.setName("Ion"); ion.setAge(15); Speaker john = new Speaker(); john.setName("John"); john.setAge(25);

speakers.add(ion); speakers.add(john);

for(Speaker s: speakers){ if (s.getAge()>20) System.out.println(s.toString().toUpperCase()); } }}

Groovy

Page 11: The Groovy Way

“Good Programmers Are Lazy and Dumb”Philipp Lenssen

http://blogoscoped.com/archive/2005-08-24-n14.html

Page 12: The Groovy Way

Candies 1

• Everything is an object3.times{print 'la'} --->lalala3.minus(2) == 3-2"lol".equals("lol")

import java.lang.*;import java.util.*;import java.net.*;import java.io.*;import java.math.BigInteger;import java.math.BigDecimal;import groovy.lang.*;import groovy.util.*;

• Automatic Imports

Page 13: The Groovy Way

Candies 2 •Optional Semicolons

• Optional Parenthesesprintln("Hello World!")println"Hello World!"===>"Hello World!"

def pizza = new Pizza()def deliver = pizza.&deliver()deliver

msg ="Hello"msg +=" World" ; msg += "!";println msg;===>"Hello World!"

Page 14: The Groovy Way

Candies 3Candies 3• Optional Datatype Declaration (Duck Typing)

• Optional Exception Handling

w ="Hello"String x ="Hello"println w.class ===> java.lang.Stringprintln w.class == x.class ===> true

s?.doSomething()

Page 15: The Groovy Way

Candies 4Candies 4

String getFullName(){ return "${firstName} ${lastName}"}//equivalent codeString getFullName(){ "${firstName} ${lastName}"}

• Optional Return Statements

add(x,y){ x + y}

Page 16: The Groovy Way

Operator OverloadingOperator Overloadinga + b a - b a * b a ** b a / b a % b a | b a & b a ^ b a++ or ++a a-- or --a a[b] a[b] = c a << b a >> b switch(a) { case(b) : } ~a -a +a a == b a != b a <=> b a > b a >= b a < b a <= b

a.plus(b) a.minus(b) a.multiply(b) a.power(b) a.div(b) a.mod(b) a.or(b) a.and(b) a.xor(b) a.next() a.previous() a.getAt(b) a.putAt(b, c) a.leftShift(b) a.rightShift(b) b.isCase(a) a.bitwiseNegate() a.negative() a.positive() a.equals(b) or a.compareTo(b) == 0 ** ! a.equals(b) a.compareTo(b) a.compareTo(b) > 0 a.compareTo(b) >= 0 a.compareTo(b) < 0 a.compareTo(b) <= 0

Page 17: The Groovy Way

GStrings GStrings 'Hello World'“Hello $world”/Hello $world/

if (text =~ pattern)println "match"if (text ==~ pattern) println "match"matcher ='Groovy is groovy'=~ /(G|g)roovy/print "Size of matcher is ${matcher.size()} "println "with elements ${matcher[0]} and ${matcher[1]}."

Page 18: The Groovy Way

ClosuresClosures• A Groovy closure is like a "code block" or a method pointer. It is a

piece of code that is defined and then executed at a later point.

def clos={param -> println "Hello ${param}"}clos.call(1)clos('1')1.upto(10) {p -> println p}1.upto 10,clos

[1, 2, 3, 4].each {println it}def isEven={x -> return (x % 2==0)}def isOdd={x -> return ! isEven(x)}def filter(list, predicate) {return list.findAll(predicate)}def odds=filter(table, isOdd)println “odds: ${odds}”

Page 19: The Groovy Way

ListsListsdef languages = ["Java","Groovy","JRuby"]languages <<"Jython"languages.each{lang ->println lang}languages.each{lang ->println lang}def others = ["Jython","JavaScript"]languages += otherslanguages.findAll{ it.startsWith("G") }println languages*.toUpperCase()languages.pop()

def scores = [80, 90, 70]println scores.max()

Page 20: The Groovy Way

MapsMaps

def family = [dad:"John", mom:"Jane"]family.get("dad") == family.dadfamily.put("kid","Timmy") == family.kid2 ="Susie"family.containsValue("John")def kids = [kid:"Timmy", kid2:"Susie"]family += kids

Page 21: The Groovy Way

RangesRanges(1..3).each{println "lla "}for(i in 1..3){ println "Attempt ${i}"}def twentiethCentury=1900..<2000 // Range literaldef reversedTen=10..1 // Reversed RangetwentiethCentury.size() // 100twentiethCentury.get(0) // 1900twentiethCentury.getFrom() // 1900twentiethCentury.getTo() // 1999twentiethCentury.contains(2000) // falsetwentiethCentury.subList(0, 5) // 1900..1904reversedTen[2] // 8reversedTen.isReverse() // true

Page 22: The Groovy Way

FilesFilesnew File(".").eachFile{file ->println file}new File(".").eachFileMatch(~/.*\.jsp/){file ->println file}new File("x.txt").eachLine{line->println line}file.splitEachLine(" "){words ->println words.size() ; wordCount += words.size() }

File file = new File("hello.txt")file.write("Hello World\n")

File src = new File("src.jpg")new File("dest.jpg").withOutputStream{ out ->out.write src.readBytes()}"cp ${src.name}${dest.name}".execute()new File("src.txt").delete()

Page 23: The Groovy Way

Dynamic GroovyDynamic Groovy• “A domain-specific language, unlike a general-purpose

language, is designed to be useful for a specific task in a fixed problem domain .”(MSDN)

Page 24: The Groovy Way

Why GroovyWhy Groovy• The compiler doesn’t know much about behavior• Behaviour completely dynamic at runtime• Everything’s routed through the Meta Object

Protocol– Method calls, property access, operators…– That’s why Groovy is a “dynamic language”

Page 25: The Groovy Way

What Groovy offers• invokeMethod and getProperty

def invokeMethod(String name, args) def getProperty(String name)void setProperty(String name, value)

• methodMissing & propertyMissingclass GORM { def methodMissing(String name, args) { ….}}

• ExpandoMetaClassdef gstr = "hello $test" def emc = new ExpandoMetaClass( gstr.class, false ) emc.test = { println "test" } emc.initialize() gstr.metaClass = emc gstr.test()

Page 26: The Groovy Way

What Groovy offers 2What Groovy offers 2class Pouncer { static pounces(Integer self) { (0..<self).inject("") {s, n -> s += "boing! " } } }use(Pouncer) { assert 3.pounces() == "boing! boing! boing! "}

Page 27: The Groovy Way

1+1= 2!!!! Really ???1+1= 2!!!! Really ???

String.metaClass.plus={d-> if (delegate=="maria" && d == "ion") return "ghita" delegate.concat d }println "maria"+"ion"println "Tom"+"&"+"Jerry"

Page 28: The Groovy Way

1+1= ?1+1= ?class Distance { static METER = 'meter' def dist, type Distance(a, b) {dist = a; type = b} String toString() {"$dist $type"} def plus(b) { if (b.type == type) { return new Distance(dist + b.dist, type) }}}Integer.metaClass.getMeters = {-> new Distance(delegate, Distance.METER)}Integer.metaClass.getKilo = {-> delegate * 1000}println 4.kiloprintln 4.metersprintln 4.meters + 4.kilo.meters

4.meters + 4.kilo.meters

Page 29: The Groovy Way

Testing and MocksTesting and Mocks

def service = [retrieveRate:{ new ExchangeRate(1.45, 0.57) }] as ExchangeRateServicedef sterlingConverter = new SterlingCurrencyConverter(service)service = { new ExchangeRate(1.55, 0.56) } as ExchangeRateServicesterlingConverter = new SterlingCurrencyConverter(service)

mockContext1 = new MockFor(ExchangeRateService)mockContext1.demand.retrieveRate { new ExchangeRate(1.75, 0.54) }def dummyService1 = mockContext1.proxyInstance()

Page 30: The Groovy Way

Reading XMLReading XML

• XmlParser/ XmlSlurper

import groovy.util.*def parser = new XmlParser()def doc = parser.parse(‘library.xml’)println “${doc.book[0].title[0].text()}”doc.book.title.each { title -> println “${title.text()}”}

Page 31: The Groovy Way

Reading XML 2Reading XML 2person = new

XmlParser().parse(file)println person.attribute("id")println person["@id"]println person.text()

person = new XmlSlurper() .parse(file)

println person.@idprintln person["@id"]println person

Page 32: The Groovy Way

XML builders XML builders

import groovy.xml.MarkupBuilderdef mB = new MarkupBuilder()mB.book(format:'pdf') { author('Ken Barcla') title('Groovy') publisher('Elsevier')}

•MarkupBuilder

<book format='pdf'> <author>Ken Barcla</author> <title>Groovy</title> <publisher>Elsevier</publisher></book>

Page 33: The Groovy Way

XML builders 2XML builders 2def builder = new groovy.xml.StreamingMarkupBuilder()def person = {

person(id:99){firstname("John")lastname("Smith")

}}println builder.bind(person)

<person id='99'><firstname>John</firstname><lastname>Smith</lastname></person>

Page 34: The Groovy Way

SwingBuilderSwingBuilderimport groovy.swing.SwingBuilderdef swing = new SwingBuilder()def frame = swing.frame(title:'Printer') { panel { textField(id:'message', columns:10) button(text:'Print', actionPerformed: { println swing.message.text }) } }frame.pack() frame.show()

Page 35: The Groovy Way

AntBuilderAntBuilderimport groovy.util.*def aB = new AntBuilder()aB.echo(message : ‘Start’)def demoDir = ‘demo’aB.mkdir(dir : demoDir)aB.copy(todir : demoDir) {

aB.fileSet(dir : ‘.’) {aB.include(name : ‘*.groovy’)

}}aB.echo(message : ‘End’)

Page 36: The Groovy Way

Groovy sqlGroovy sqlimport groovy.sql.*def DB = 'jdbc: derby: accountDB'def DRIVER = 'org.apache.derby.jdbc.EmbeddedDriver'sql = Sql.newInstance(DB, "user","passwd", DRIVER)def displayAccounts(banner, sql) { sql.eachRow(' select * from accounts') {acc -> println "Account: $ {acc.number} $ {acc.balance}" }} sql.query('SELECT firstname, lastname FROM Athlete') {resultSet -> if (resultSet.next()) { print resultSet.getString(1) print ' ' println resultSet.getString('lastname') }}sql.execute "DELETE FROM Athlete WHERE firstname = $firstname;"def stmt = "UPDATE $tablename SET $field = ? $whereId"sql.executeUpdate stmt, [newValue, id]

dataSet = sql.dataSet('weather')citiesBelowFreezing = dataSet.findAll { it.temperature < 32 }println"Cities below freezing:"citiesBelowFreezing.each {println it.city}

Page 37: The Groovy Way

Integrating java and groovyIntegrating java and groovy

• Groovy Shell• GroovyScriptEngine• GroovyClassLoaderGroovyClassLoader

Page 38: The Groovy Way

Groovy ShellGroovy ShellGroovyShell shell = new GroovyShell(); Object result = shell.evaluate("12 + 23"); System.out.println(result);

def binding = new Binding() binding.mass = 22.3 binding.velocity = 10.6 def shell = new GroovyShell(binding) def expression = "mass * velocity ** 2 / 2”assert shell.evaluate(expression) == 1426.972

def shell = new GroovyShell()def clazz = shell.evaluate(''' class MyClass { def method() { "value" } } return MyClass ''')

Page 39: The Groovy Way

GroovyScriptEngineGroovyScriptEngine

def engine = new GroovyScriptEngine(".")def value = engine.run("test/MyScript.groovy", new Binding())

Page 40: The Groovy Way

GroovyClassLoaderGroovyClassLoader

gcl = new GroovyClassLoader()Class greetingClass = gcl.parseClass(new File("Hello.groovy"))

Page 41: The Groovy Way

Spring IntegrationSpring Integration

... <bean id="country1" class="spring.Australia"> <property name="capital" value="Canberra"/> <property name="population" value="20264082"/></bean> ...

... <lang:groovy id="country3" script-source="classpath:spring/NewZealand.groovy">

<lang:property name="capital" value="Wellington" /> <lang:property name="population" value="4076140" />

</lang:groovy> ...

Page 42: The Groovy Way

Spring Integration 2Spring Integration 2

... <lang:groovy id="sorter"> <lang:inline-script><![CDATA[ package spring class CountrySorter implements Sorter { String order List sort(Country[] items) { List result = items.toList().sort{ p1, p2 -> p1.population <=> p2.population } if (order == "reverse") return result.reverse() else return result } } ]]></lang:inline-script> <lang:property name="order" value="forward" /> </lang:groovy> ...

Page 43: The Groovy Way

More Groovy Cool StuffMore Groovy Cool Stuff

• Gant • Scriptom • GMaven• GraphicsBuilder• JideBuilder• GSQL • Griffon• Grails

Page 44: The Groovy Way

http://groovy.codehaus.org/

Page 45: The Groovy Way

Questions

Page 46: The Groovy Way