SlideShare a Scribd company logo
1 of 35
Groovy Zdenek Urban 20. ledna 2010
Groovykindof love  excellent, fashionable, or amazing
Groovy ,[object Object]
Lists and Maps
Regex and Ranges
Operators
Closures
Groovy Beans
Operator overloading
DSL – Domain Specific Language
Metaprogramming
Builders
Files
Database,[object Object]
Scripting dynamic langs (JVM)
Hello, world Legální java code, ale co vše je nadbytečné class Foo { 	public static void main(String[] args) { 		System.out.println("Hello, world"); 	} }
Hello, world Nadbytečné declarace obecných objektů Závorky, ukončení věty… System.out.println("Hello, world");
Hello, world println'Hello, world'
CLI Command Line Interface def cli = new CliBuilder(usage: 'showdate.groovy -[chflms] [date] [prefix]') cli.with {// Create the list of options.     h 	longOpt: 'help', 'Show usage information'     c 	longOpt: 'format-custom', args: 1, argName: 'format', 'Format date with custom format defined by "format"'     f 	longOpt: 'format-full',   'Use DateFormat#FULL format'     l 	longOpt: 'format-long',   'Use DateFormat#LONG format'     m 	longOpt: 'format-medium', 'Use DateFormat#MEDIUM format (default)'     s 	longOpt: 'format-short',  'Use DateFormat#SHORT format' } cli.p(argName:'heslo', longOpt:'password', args:1, required:true, type:GString, 'fill up the hic') def options = cli.parse(args) if (!options) return if ( options.h) {     cli.usage() // usage: showdate.groovy -[chflms] [date] [prefix]     //  -c,--format-custom <format>   	Format date with custom format defined by "format"     //  -f,--format-full              	Use DateFormat#FULL format        //  -h,--help                     		Show usage information        //  -l,--format-long              	Use DateFormat#LONG format        //  -m,--format-medium            	Use DateFormat#MEDIUM format        //  -s,--format-short             	Use DateFormat#SHORT format        return } GOP Groovy Option Parser Alternativa
PročGroovy? Dynamický skriptovací jazyk plus … JSR 241: Java standard Two-way contract:  Groovy class je Java class: bytecode identita. Groovy and Java dědičnost tříd. Integrace s Java: annotations, generics, enums, familiar syntax. Groovy platforma je Java platforma:  JSE library, debugging, ... 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 “my darling”' println "$greeting, world is ‘easy’“ println """ Today's “date” is ‘${new Date().toGMTString()’} Multiline string, isn't it? """ greeting = "Hello, world“;greeting[7] == 'w‘;greeting[2..4] == 'llo‘ "#{'}{quot;}/“ == '#{apos;}${"}/‘ == /{'}${'$'}{"}/ def capitalize(s) { s[0].toUpperCase() + s[1..-1].toLowerCase() } caps = "man OF stEEL".replaceAll(/+/) { w -> capitalize(w) } println "cmd /c dir|grep cli".execute().text.split('')
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' =~ /*ain/)    println '"rain" does rhyme with "Spain"!'
Regex  str = 'groovy.codehaus.org  and www.aboutgroovy.com ‘ reNoWhiteSpace = /((?:(?![-_][-])+)+[A-Za-z][-]+)/ reWhiteSpace = /(?x)( (?: (?! [-_]) [-]+   )+ [A-Za-z] [-]+ ) / re = '''(?x)          # to enable whitespace and comments       (               # capture the hostname in $1         (?:           # these parens for grouping only           (?! [-_] )  # lookahead for neither underscore nor dash           [w-] +    # hostname component .         # and the domain dot         ) +           # now repeat that whole thing a bunch of times         [A-Za-z]      # next must be a letter         [w-] +      # now trailing domain part       )               # end of $1 capture ''' finder = str =~ re out = str (0..<finder.count).each{     adr = finder[it][0]     out = out.replaceAll(adr, "$adr [${InetAddress.getByName(adr).hostAddress}]") } println out // => groovy.codehaus.org [63.246.7.187] and www.aboutgroovy.com [63.246.7.76]
Closures	 Metoda jako objekt Default argument “it” je volitelný.  def squareIt = { return it * it } assert squareIt(5) == 25 10.times { println “I will not talk in class” } Variables visibility int x = 10 Closure addToX = { addThis -> x += addThis } addToX(2) assert x == 12
ClosuresStrategy pattern def multiplicationStrategies = [     { n, m -> n * m },     { n, m -> def result = 0; n.times{ result += m }; result } ] def sampleData = [     [3, 4, 12],     [5, -5, -25] ] sampleData.each{ data ->     multiplicationStrategies.each{ calc ->         assert data[2] == calc(data[0], data[1])     } }
Operator overloading Override operators by overriding methods: a + b 				a.plus(b) a[b] 				a.getAt(b) a << b 				a.leftShift(b) switch (a) { case b: ... } 	b.isCase(a) a == b 				a.equals(b) a < b 				a.compareTo(b) < 0
Smart switch switch (x) {case 'James':	println "yes it is me"	breakcase 18..65:	println "ok you are old"	breakcase ~/Gw?+e/:	println "your name starts with G and ends in e!"	breakcase Date:	println 'got a Date instance'	breakcase ['John', 'Ringo', 'Paul', 'George']:	println "Got one of the Beatles"breakdefault:	println "Don't know $x“ }
Groovy convenience operators =~		regex find brandMatch = (line =~ /lt;bgt;([a-zA-Z]*)lt;brgt;/)        if(brandMatch)  brandName = brandMatch[0][1] ==~	regex match  <=>	spaceship, compareTo method of the Comparable interface ?:elvis	ternary operator Java: 	name = name != null ? name : "default" 	Groovy: 	name = name ?: "default" ?. 	safe dereference. No worry about nulls. 	street = user?.address?.street * (spread) – “explode” the contents of a list or arraydef  list = ['Groovy', 'Java‘];	assert ['Groovy', 'Java', 'Scala'] == [*list, 'Scala'] *.	spread dot. Invoke on all items, return list. 	List result = invoice.lineItems*.total() 	parent*.action //equivalent to: parent.collect{ child -> child?.action }assert ['cat', 'elephant']*.size() == [3, 8]
GroovyBeans and JavaBeans // Groovy class MyBean { 	String item } MyBean b =      new MyBean(item:‘foo’) String val = b.item b.item = ‘bar’ b[‘item’] = ‘bar’ // Java class MyBean { 	private String item; 	public String getItem() {…} 	public void setItem(…) {…} } MyBean b = new MyBean(); b.setItem(“foo”); String val = b.getItem(); 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())

More Related Content

What's hot

Building fast interpreters in Rust
Building fast interpreters in RustBuilding fast interpreters in Rust
Building fast interpreters in RustIngvar Stepanyan
 
Dynamic C++ ACCU 2013
Dynamic C++ ACCU 2013Dynamic C++ ACCU 2013
Dynamic C++ ACCU 2013aleks-f
 
Basic C++ 11/14 for Python Programmers
Basic C++ 11/14 for Python ProgrammersBasic C++ 11/14 for Python Programmers
Basic C++ 11/14 for Python ProgrammersAppier
 
Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! aleks-f
 
Dynamic C++ Silicon Valley Code Camp 2012
Dynamic C++ Silicon Valley Code Camp 2012Dynamic C++ Silicon Valley Code Camp 2012
Dynamic C++ Silicon Valley Code Camp 2012aleks-f
 
The Rust Programming Language: an Overview
The Rust Programming Language: an OverviewThe Rust Programming Language: an Overview
The Rust Programming Language: an OverviewRoberto Casadei
 
NativeBoost
NativeBoostNativeBoost
NativeBoostESUG
 
JavaScript Survival Guide
JavaScript Survival GuideJavaScript Survival Guide
JavaScript Survival GuideGiordano Scalzo
 
The Macronomicon
The MacronomiconThe Macronomicon
The MacronomiconMike Fogus
 
Node.js System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The LandingHaci Murat Yaman
 
Clojure 1.1 And Beyond
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And BeyondMike Fogus
 
ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation JavascriptRamesh Nair
 
Rust Mozlando Tutorial
Rust Mozlando TutorialRust Mozlando Tutorial
Rust Mozlando Tutorialnikomatsakis
 

What's hot (20)

Building fast interpreters in Rust
Building fast interpreters in RustBuilding fast interpreters in Rust
Building fast interpreters in Rust
 
Dynamic C++ ACCU 2013
Dynamic C++ ACCU 2013Dynamic C++ ACCU 2013
Dynamic C++ ACCU 2013
 
Basic C++ 11/14 for Python Programmers
Basic C++ 11/14 for Python ProgrammersBasic C++ 11/14 for Python Programmers
Basic C++ 11/14 for Python Programmers
 
EcmaScript 6
EcmaScript 6 EcmaScript 6
EcmaScript 6
 
Academy PRO: ES2015
Academy PRO: ES2015Academy PRO: ES2015
Academy PRO: ES2015
 
Rust-lang
Rust-langRust-lang
Rust-lang
 
ES6 in Real Life
ES6 in Real LifeES6 in Real Life
ES6 in Real Life
 
Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! 
 
Dynamic C++ Silicon Valley Code Camp 2012
Dynamic C++ Silicon Valley Code Camp 2012Dynamic C++ Silicon Valley Code Camp 2012
Dynamic C++ Silicon Valley Code Camp 2012
 
ECMAScript 6
ECMAScript 6ECMAScript 6
ECMAScript 6
 
The Rust Programming Language: an Overview
The Rust Programming Language: an OverviewThe Rust Programming Language: an Overview
The Rust Programming Language: an Overview
 
NativeBoost
NativeBoostNativeBoost
NativeBoost
 
JavaScript Survival Guide
JavaScript Survival GuideJavaScript Survival Guide
JavaScript Survival Guide
 
The Macronomicon
The MacronomiconThe Macronomicon
The Macronomicon
 
Node.js System: The Landing
Node.js System: The LandingNode.js System: The Landing
Node.js System: The Landing
 
Clojure 1.1 And Beyond
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And Beyond
 
Rust言語紹介
Rust言語紹介Rust言語紹介
Rust言語紹介
 
Why rust?
Why rust?Why rust?
Why rust?
 
ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation Javascript
 
Rust Mozlando Tutorial
Rust Mozlando TutorialRust Mozlando Tutorial
Rust Mozlando Tutorial
 

Viewers also liked

Revista Mundo Contact Noviembre 2013
Revista Mundo Contact Noviembre 2013Revista Mundo Contact Noviembre 2013
Revista Mundo Contact Noviembre 2013Mundo Contact
 
Revista Mundo Contact Diciembre 2010
Revista Mundo Contact Diciembre 2010Revista Mundo Contact Diciembre 2010
Revista Mundo Contact Diciembre 2010Mundo Contact
 
Revista Mundo Contact Diciembre 2012
Revista Mundo Contact Diciembre 2012Revista Mundo Contact Diciembre 2012
Revista Mundo Contact Diciembre 2012Mundo Contact
 
Revista Mundo Contact Diciembre 2011
Revista Mundo Contact Diciembre 2011Revista Mundo Contact Diciembre 2011
Revista Mundo Contact Diciembre 2011Mundo Contact
 
Revista Mundo Contact Julio 2016
Revista Mundo Contact Julio 2016Revista Mundo Contact Julio 2016
Revista Mundo Contact Julio 2016Mundo Contact
 

Viewers also liked (9)

Kucing persia
Kucing persiaKucing persia
Kucing persia
 
Dianita
DianitaDianita
Dianita
 
Revista Mundo Contact Noviembre 2013
Revista Mundo Contact Noviembre 2013Revista Mundo Contact Noviembre 2013
Revista Mundo Contact Noviembre 2013
 
Revista Mundo Contact Diciembre 2010
Revista Mundo Contact Diciembre 2010Revista Mundo Contact Diciembre 2010
Revista Mundo Contact Diciembre 2010
 
Madalina
MadalinaMadalina
Madalina
 
Revista Mundo Contact Diciembre 2012
Revista Mundo Contact Diciembre 2012Revista Mundo Contact Diciembre 2012
Revista Mundo Contact Diciembre 2012
 
Maribel
MaribelMaribel
Maribel
 
Revista Mundo Contact Diciembre 2011
Revista Mundo Contact Diciembre 2011Revista Mundo Contact Diciembre 2011
Revista Mundo Contact Diciembre 2011
 
Revista Mundo Contact Julio 2016
Revista Mundo Contact Julio 2016Revista Mundo Contact Julio 2016
Revista Mundo Contact Julio 2016
 

Similar to Groovy

Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Wsloffenauer
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005Tugdual Grall
 
Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....Raffi Krikorian
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Guillaume Laforge
 
From Javascript To Haskell
From Javascript To HaskellFrom Javascript To Haskell
From Javascript To Haskellujihisa
 
MiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScriptMiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScriptCaridy Patino
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs偉格 高
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2rubyMarc Chung
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Jonathan Felch
 
Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Phil Calçado
 
Groovy Api Tutorial
Groovy Api  TutorialGroovy Api  Tutorial
Groovy Api Tutorialguligala
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Introzhang tao
 

Similar to Groovy (20)

Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws
 
Groovy
GroovyGroovy
Groovy
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4
 
Clojure And Swing
Clojure And SwingClojure And Swing
Clojure And Swing
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
 
Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008
 
From Javascript To Haskell
From Javascript To HaskellFrom Javascript To Haskell
From Javascript To Haskell
 
MiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScriptMiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScript
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2ruby
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)
 
Eta
EtaEta
Eta
 
Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)
 
Groovy.pptx
Groovy.pptxGroovy.pptx
Groovy.pptx
 
Groovy Api Tutorial
Groovy Api  TutorialGroovy Api  Tutorial
Groovy Api Tutorial
 
Ruby on Rails Intro
Ruby on Rails IntroRuby on Rails Intro
Ruby on Rails Intro
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
 

Groovy

  • 1. Groovy Zdenek Urban 20. ledna 2010
  • 2. Groovykindof love  excellent, fashionable, or amazing
  • 3.
  • 10. DSL – Domain Specific Language
  • 13. Files
  • 14.
  • 16. Hello, world Legální java code, ale co vše je nadbytečné class Foo { public static void main(String[] args) { System.out.println("Hello, world"); } }
  • 17. Hello, world Nadbytečné declarace obecných objektů Závorky, ukončení věty… System.out.println("Hello, world");
  • 19. CLI Command Line Interface def cli = new CliBuilder(usage: 'showdate.groovy -[chflms] [date] [prefix]') cli.with {// Create the list of options. h longOpt: 'help', 'Show usage information' c longOpt: 'format-custom', args: 1, argName: 'format', 'Format date with custom format defined by "format"' f longOpt: 'format-full', 'Use DateFormat#FULL format' l longOpt: 'format-long', 'Use DateFormat#LONG format' m longOpt: 'format-medium', 'Use DateFormat#MEDIUM format (default)' s longOpt: 'format-short', 'Use DateFormat#SHORT format' } cli.p(argName:'heslo', longOpt:'password', args:1, required:true, type:GString, 'fill up the hic') def options = cli.parse(args) if (!options) return if ( options.h) { cli.usage() // usage: showdate.groovy -[chflms] [date] [prefix] // -c,--format-custom <format> Format date with custom format defined by "format" // -f,--format-full Use DateFormat#FULL format // -h,--help Show usage information // -l,--format-long Use DateFormat#LONG format // -m,--format-medium Use DateFormat#MEDIUM format // -s,--format-short Use DateFormat#SHORT format return } GOP Groovy Option Parser Alternativa
  • 20. PročGroovy? Dynamický skriptovací jazyk plus … JSR 241: Java standard Two-way contract: Groovy class je Java class: bytecode identita. Groovy and Java dědičnost tříd. Integrace s Java: annotations, generics, enums, familiar syntax. Groovy platforma je Java platforma: JSE library, debugging, ... Spring, Hibernate, web services, TestNG
  • 21. 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
  • 22. Strings greeting = 'Hello “my darling”' println "$greeting, world is ‘easy’“ println """ Today's “date” is ‘${new Date().toGMTString()’} Multiline string, isn't it? """ greeting = "Hello, world“;greeting[7] == 'w‘;greeting[2..4] == 'llo‘ "#{'}{quot;}/“ == '#{apos;}${"}/‘ == /{'}${'$'}{"}/ def capitalize(s) { s[0].toUpperCase() + s[1..-1].toLowerCase() } caps = "man OF stEEL".replaceAll(/+/) { w -> capitalize(w) } println "cmd /c dir|grep cli".execute().text.split('')
  • 23. 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)
  • 24. 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' =~ /*ain/) println '"rain" does rhyme with "Spain"!'
  • 25. Regex str = 'groovy.codehaus.org and www.aboutgroovy.com ‘ reNoWhiteSpace = /((?:(?![-_][-])+)+[A-Za-z][-]+)/ reWhiteSpace = /(?x)( (?: (?! [-_]) [-]+ )+ [A-Za-z] [-]+ ) / re = '''(?x) # to enable whitespace and comments ( # capture the hostname in $1 (?: # these parens for grouping only (?! [-_] ) # lookahead for neither underscore nor dash [w-] + # hostname component . # and the domain dot ) + # now repeat that whole thing a bunch of times [A-Za-z] # next must be a letter [w-] + # now trailing domain part ) # end of $1 capture ''' finder = str =~ re out = str (0..<finder.count).each{ adr = finder[it][0] out = out.replaceAll(adr, "$adr [${InetAddress.getByName(adr).hostAddress}]") } println out // => groovy.codehaus.org [63.246.7.187] and www.aboutgroovy.com [63.246.7.76]
  • 26. Closures Metoda jako objekt Default argument “it” je volitelný. def squareIt = { return it * it } assert squareIt(5) == 25 10.times { println “I will not talk in class” } Variables visibility int x = 10 Closure addToX = { addThis -> x += addThis } addToX(2) assert x == 12
  • 27. ClosuresStrategy pattern def multiplicationStrategies = [ { n, m -> n * m }, { n, m -> def result = 0; n.times{ result += m }; result } ] def sampleData = [ [3, 4, 12], [5, -5, -25] ] sampleData.each{ data -> multiplicationStrategies.each{ calc -> assert data[2] == calc(data[0], data[1]) } }
  • 28. Operator overloading Override operators by overriding methods: a + b a.plus(b) a[b] a.getAt(b) a << b a.leftShift(b) switch (a) { case b: ... } b.isCase(a) a == b a.equals(b) a < b a.compareTo(b) < 0
  • 29. Smart switch switch (x) {case 'James': println "yes it is me" breakcase 18..65: println "ok you are old" breakcase ~/Gw?+e/: println "your name starts with G and ends in e!" breakcase Date: println 'got a Date instance' breakcase ['John', 'Ringo', 'Paul', 'George']: println "Got one of the Beatles"breakdefault: println "Don't know $x“ }
  • 30. Groovy convenience operators =~ regex find brandMatch = (line =~ /lt;bgt;([a-zA-Z]*)lt;brgt;/) if(brandMatch) brandName = brandMatch[0][1] ==~ regex match <=> spaceship, compareTo method of the Comparable interface ?:elvis ternary operator Java: name = name != null ? name : "default" Groovy: name = name ?: "default" ?. safe dereference. No worry about nulls. street = user?.address?.street * (spread) – “explode” the contents of a list or arraydef  list = ['Groovy', 'Java‘]; assert ['Groovy', 'Java', 'Scala'] == [*list, 'Scala'] *. spread dot. Invoke on all items, return list. List result = invoice.lineItems*.total() parent*.action //equivalent to: parent.collect{ child -> child?.action }assert ['cat', 'elephant']*.size() == [3, 8]
  • 31. GroovyBeans and JavaBeans // Groovy class MyBean { String item } MyBean b = new MyBean(item:‘foo’) String val = b.item b.item = ‘bar’ b[‘item’] = ‘bar’ // Java class MyBean { private String item; public String getItem() {…} public void setItem(…) {…} } MyBean b = new MyBean(); b.setItem(“foo”); String val = b.getItem(); b.setItem(“bar”)
  • 32. 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) }
  • 33. 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); }
  • 34. 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()); } }
  • 35. Dynamic Groovy: multimethods class Equalizer { boolean equals(Equalizer e) {...} boolean equals(Object o) {...} } Object obj = new Equalizer() obj.equals(new Equalizer())
  • 36. Dynamic Groovy: categories // Dynamically add methods to any class class PersistenceCategory { static void save(Object o) { // save object } } use (PersistenceCategory) { // all objects now have save() method new MyBean().save() }
  • 37. 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 String.metaClass.groovy << { Integer number -> delegate * number } << { String s -> delegate + s } << { -> delegate + ' Groovy rocks.' } assert 'GroovyGroovy' == 'Groovy'.groovy(2) assert 'Hello world from Groovy' == 'Hello world'.groovy(' from Groovy') assert 'It is true. Groovy rocks.' == 'It is true.'.groovy()
  • 38. 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>
  • 39.
  • 40. Terse notation for JavaBeans architecture properties and events
  • 44.
  • 45. 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)
  • 46. Files def file1 = new File('groovy1.txt') file1 << 'See how easy it is to add text to a file.‚ file1.withWriter('UTF-8') { writer -> writer.write('We can also use writers to add contents.‘)} sw = new StringWriter() file1.filterLine(sw) { it =~ /Groovy/ } assert 'Working with files the Groovy way is easy.' == sw.toString() files = [] new File('.').eachFileMatch(~/^groovy.*txt$/) { files << it.name } assert ['groovy1.txt', 'groovy2.txt', 'groovy3.txt'] == files files.each { new File(it).delete() }
  • 47. Database def c = new ConfigSlurper().parse(new File('config.groovy').toURL()) def sql = groovy.sql.Sql.newInstance(c.db.schema, c.db.user, c.db.pwd, c.db.driver) sql.execute("CREATE TABLE tbl(oid integer,nam char(5))") def ds = sql.dataSet("tbl") new File(‘file.csv').splitEachLine(';') {ds.add(oid: it[0], name: it[1])} ds.each { println it} sql.eachRow("""select oid, name from tbl”””) {println “${it.name}} db{ config.groovy driver=denormalize("com.mysql.jdbc.Driver“) schema="jdbc:mysql://localhost/test" user="zen" pwd=“p" date = new Date() active = true } app{ //assert new Integer(20).equals(app.get("servers.setting2")); [1, 2, 3].each {this."setting${it}" = it * 10} } def normalize(s){return s.toUpperCase()}
  • 48. Proč Groovy? Java is Groovy, Groovy is Java Standardizace Společný jazyk Architektura – Pseudocode Testování Automatizace Instalační a konfigurační skripty Builders, DSL Java Domain Grails, Spring, Seam
  • 49. Otázky, diskuze Ain’t-cha got no rhymes for me? Doot’n doo-doo feelin’ groovy.

Editor's Notes

  1. The Strategy Pattern allows you to abstract away particular algorithms from their usage. This allows you to easily swap the algorithm being used without having to change the calling code.