The Groovy Way

Post on 09-May-2015

1.217 views 2 download

description

Groovy tech talk held at my company

Transcript of The Groovy Way

The Way

by Dogaru Gabriel

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

#!/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"

6

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

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

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

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

“Good Programmers Are Lazy and Dumb”Philipp Lenssen

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

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

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!"

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()

Candies 4Candies 4

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

• Optional Return Statements

add(x,y){ x + y}

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

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]}."

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}”

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()

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

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

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()

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)

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”

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()

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! "}

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"

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

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()

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()}”}

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

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>

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>

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()

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’)

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}

Integrating java and groovyIntegrating java and groovy

• Groovy Shell• GroovyScriptEngine• GroovyClassLoaderGroovyClassLoader

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 ''')

GroovyScriptEngineGroovyScriptEngine

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

GroovyClassLoaderGroovyClassLoader

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

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> ...

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> ...

More Groovy Cool StuffMore Groovy Cool Stuff

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

http://groovy.codehaus.org/

Questions