The Groovy Way

  • 1,166 views
Uploaded on

Groovy tech talk held at my company

Groovy tech talk held at my company

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,166
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
32
Comments
0
Likes
3

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. The Way by Dogaru Gabriel
  • 2. Agenda • What is Groovy ? • Candies • Closures • Dynamic Groovy • Groovy builders • Integrating java and groovy • More Groovy Cool Stuff
  • 3. #!/usr/bin/ruby class Person def initialize(lname, fname) @lname = lname @fname = fname end attr_reader :lname, :fname attr_writer :lname, :fname end 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"
  • 4. > +++++++++[<+++++++>-]<++++.---------.>> ++++++++++[<+++++++++>-]<++.<++++., >>>++++++++++.>>+++++++++[<+++++++> -]<+++.>>+++++++++++[<+++++++++>-]<-- .+++.>>++++++[<+++++>-]<++.>>++++++++ +++[<+++++++++>-]<.>>+++++++++++[<++ ++++++++>-]<+.--..>>+++++++++++[<+++++ ++++>-]<--.>>+++++++++++[<++++++++++>-] <.>>+++++++++++[<+++++++++>-]<+.>>++++ ++[<+++++>-]<++.>>+++++++++++[<+++++++ +++>-]<+.+++.>>++++++[<+++++>-]<++.>>++ +++++++++[<+++++++++>-]<+++.>>+++++++ ++++++++[<+++++++>-]<.+++.-------.>>+++++ +[<+++++>-]<++.>>+++++++++++[<+++++++ +++>-]<.>>+++++++++++[<+++++++++>-]<-- .>>+++++++++++[<++++++++++>-]<-.>>++++ +++++++++++[<+++++++>-]<----.>>++++++++ ++. 6
  • 5. 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
  • 6. Other 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
  • 7. J ava G roovy G roovy import java.util.List; import java.util.List; class Speaker { import java.util.ArrayList; import java.util.ArrayList; def age String name public class Speaker { public class Speaker { private Integer age; String toString() { private Integer age; private String name; private String name; return "${name} - $age" } public String toString() { public String toString() { } return name + " - " + age; return name + " - " + age; } } def speakers = [ public Integer getAge() { public Integer getAge() { new Speaker(name: "john", age: 15) , return age; return age; new Speaker (name: "ionel", age: 29) } } ] public void setAge(Integer age) { public void setAge(Integer age) { this.age = age; def upper = {it.toString().toUpperCase()} this.age = age; } } speakers.findAll{s -> s.age >20} public String getName() { public String getName() { .collect(upper).each{println it} return name; return name; } } public void setName(String name) { public void setName(String name) { this.name = name; this.name = name; } } public static void main(String[] args) { public static void main(String[] args) { List<Speaker> speakers = new List<Speaker> speakers = new ArrayList<Speaker>(); ArrayList<Speaker>(); Speaker ion = new Speaker(); Speaker ion = new Speaker(); ion.setName("Ion"); ion.setName("Ion"); ion.setAge(15); ion.setAge(15); Speaker john = new Speaker(); Speaker john = new Speaker(); john.setName("John"); john.setName("John"); john.setAge(25); john.setAge(25); speakers.add(ion); speakers.add(ion); speakers.add(john); speakers.add(john); for(Speaker s: speakers){ for(Speaker s: speakers){ if (s.getAge()>20) if (s.getAge()>20) System.out.println(s.toString().toUpperCase()); } System.out.println(s.toString().toUpperCase()); } } } } }
  • 8. Productivity graph AfterThought planning results
  • 9. “Good Programmers Are Lazy and Dumb” Philipp Lenssen http://blogoscoped.com/archive/2005-08-24-n14.html
  • 10. Candies 1 • Automatic Imports 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.*; • Everything is an object 3.times{print 'la'} --->lalala 3.minus(2) == 3-2 "lol".equals("lol")
  • 11. Candies 2 •Optional Semicolons msg ="Hello" msg +=" World" ; msg += "!"; println msg; ===> "Hello World!" def pizza = new Pizza() def deliver = pizza.&deliver() deliver • Optional Parentheses println("Hello World!") println"Hello World!" ===> "Hello World!"
  • 12. Candies 3 • Optional Datatype Declaration (Duck Typing) w ="Hello" String x ="Hello" println w.class ===> java.lang.String println w.class == x.class ===> true • Optional Exception Handling s?.doSomething()
  • 13. Candies 4 • Optional Return Statements String getFullName(){ return "${firstName} ${lastName}" } //equivalent code String getFullName(){ "${firstName} ${lastName}" } add(x,y){ x + y}
  • 14. Operator Overloading a+b a.plus(b) a-b a.minus(b) a*b a.multiply(b) a ** b a.power(b) a/b a.div(b) a %b a.mod(b) a|b a.or(b) a&b a.and(b) a^b a.xor(b) a++ or ++a a.next() a-- or --a a.previous() a[b] a.getAt(b) a[b] = c a.putAt(b, c) a << b a.leftS hift(b) a >> b a.rightS hift(b) switch(a) { case(b) : } b.isCase(a) ~a a.bitwiseNegate() -a a.negative() +a a.positive() a == b a.equals(b) or a.compareTo(b) == 0 ** a != b ! a.equals(b) a <=> b a.compareTo(b) a>b a.compareTo(b) > 0 a >= b a.compareTo(b) >= 0 a<b a.compareTo(b) < 0 a <= b a.compareTo(b) <= 0
  • 15. 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]}."
  • 16. Closures • 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}”
  • 17. Lists def languages = ["Java","Groovy","JRuby"] languages <<"Jython" languages.each{lang ->println lang} languages.each{lang ->println lang} def others = ["Jython","JavaScript"] languages += others languages.findAll{ it.startsWith("G") } println languages*.toUpperCase() languages.pop() def scores = [80, 90, 70] println scores.max()
  • 18. Maps def family = [dad:"John", mom:"Jane"] family.get("dad") == family.dad family.put("kid","Timmy") == family.kid2 ="Susie" family.containsValue("John") def kids = [kid:"Timmy", kid2:"Susie"] family += kids
  • 19. Ranges (1..3).each{println "lla "} for(i in 1..3){ println "Attempt ${i}" } def twentiethCentury=1900..<2000 // Range literal def reversedTen=10..1 // Reversed Range twentiethCentury.size() // 100 twentiethCentury.get(0) // 1900 twentiethCentury.getFrom() // 1900 twentiethCentury.getTo() // 1999 twentiethCentury.contains(2000) // false twentiethCentury.subList(0, 5) // 1900..1904 reversedTen[2] // 8 reversedTen.isReverse() // true
  • 20. Files new 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 Worldn") 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()
  • 21. Dynamic 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)
  • 22. Why 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”
  • 23. What Groovy offers • invokeMethod and getProperty def invokeMethod(String name, args) def getProperty(String name) void setProperty(String name, value) • methodMissing & propertyMissing class GORM { def methodMissing(String name, args) { ….} } • ExpandoMetaClass def gstr = "hello $test" def emc = new ExpandoMetaClass( gstr.class, false ) emc.test = { println "test" } emc.initialize() gstr.metaClass = emc gstr.test()
  • 24. What Groovy offers 2 class Pouncer { static pounces(Integer self) { (0..<self).inject("") {s, n -> s += "boing! " } } } use(Pouncer) { assert 3.pounces() == "boing! boing! boing! " }
  • 25. 1+1= 2!!!! Really ??? String.metaClass.plus={d-> if (delegate=="maria" && d == "ion") return "ghita" delegate.concat d } println "maria"+"ion" println "Tom"+"&"+"Jerry"
  • 26. 1+1= ? 4.meters + 4.kilo.meters 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.kilo println 4.meters println 4.meters + 4.kilo.meters
  • 27. Testing and Mocks def service = [retrieveRate:{ new ExchangeRate(1.45, 0.57) }] as ExchangeRateService def sterlingConverter = new SterlingCurrencyConverter(service) service = { new ExchangeRate(1.55, 0.56) } as ExchangeRateService sterlingConverter = new SterlingCurrencyConverter(service) mockContext1 = new MockFor(ExchangeRateService) mockContext1.demand.retrieveRate { new ExchangeRate(1.75, 0.54) } def dummyService1 = mockContext1.proxyInstance()
  • 28. Reading 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()}” }
  • 29. Reading XML 2 person = new person = new XmlSlurper() XmlParser().parse(file) .parse(file) println person.attribute("id") println person.@id println person["@id"] println person["@id"] println person println person.text()
  • 30. XML builders •MarkupBuilder import groovy.xml.MarkupBuilder def mB = new MarkupBuilder() mB.book(format:'pdf') { author('Ken Barcla') title('Groovy') publisher('Elsevier') } <book format='pdf'> <author>Ken Barcla</author> <title>Groovy</title> <publisher>Elsevier</publisher> </book>
  • 31. XML builders 2 def 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>
  • 32. SwingBuilder import groovy.swing.SwingBuilder def 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()
  • 33. AntBuilder import 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’)
  • 34. Groovy sql import 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}
  • 35. Integrating java and groovy • Groovy Shell • GroovyScriptEngine • GroovyClassLoader
  • 36. Groovy Shell GroovyShell 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 ''')
  • 37. GroovyScriptEngine def engine = new GroovyScriptEngine(".") def value = engine.run("test/MyScript.groovy", new Binding())
  • 38. GroovyClassLoader gcl = new GroovyClassLoader() Class greetingClass = gcl.parseClass(new File("Hello.groovy"))
  • 39. Spring 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> ...
  • 40. Spring 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> ...
  • 41. More Groovy Cool Stuff • Gant • Scriptom • GMaven • GraphicsBuilder • JideBuilder • GSQL • Griffon • Grails
  • 42. http://groovy.codehaus.org/
  • 43. Questions