Upload
gabriel-dogaru
View
1.217
Download
2
Embed Size (px)
DESCRIPTION
Groovy tech talk held at my company
Citation preview
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
Productivity graph
AfterThought planning results
“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