groovy: il linguaggio
Post on 06-Aug-2015
41 Views
Preview:
TRANSCRIPT
Obiettivi del talk
• Mostrare le peculiarità del linguaggio
• Introdurre alcuni tool legati a Groovy
• Farvi venire voglia di provarlo :)
venerdì 28 giugno 13
import java.util.List;import java.util.ArrayList;
class Filter {! static List<String> filterLongerThan(List<String> xs, int maxLen) {! ! List<String> results = new ArrayList<String>();! ! for (int i=0; i < xs.size(); i++){! ! ! String s = xs.get(i);! ! ! if (s.length() <= maxLen){! ! ! ! results.add(s);! ! ! }! ! }! ! return results;! }! public static void main(String[] args) {! ! List<String> names = new ArrayList<String>();! ! names.add("Giulio"); names.add("Laura");! ! names.add("Mario"); names.add("Anna");! ! System.out.println(names);! ! List<String> shortNames = filterLongerThan(names, 5);! ! System.out.println("After filtering: " + shortNames.size());! ! for (int i=0; i < shortNames.size(); i++) {! ! ! String s = shortNames.get(i);! ! ! System.out.println(s);! ! }! }}
venerdì 28 giugno 13
import java.util.List;import java.util.ArrayList;
class Filter {! static List<String> filterLongerThan(List<String> xs, int maxLen) {! ! List<String> results = new ArrayList<String>();! ! for (int i=0; i < xs.size(); i++){! ! ! String s = xs.get(i);! ! ! if (s.length() <= maxLen){! ! ! ! results.add(s);! ! ! }! ! }! ! return results;! }! public static void main(String[] args) {! ! List<String> names = new ArrayList<String>();! ! names.add("Giulio"); names.add("Laura");! ! names.add("Mario"); names.add("Anna");! ! System.out.println(names);! ! List<String> shortNames = filterLongerThan(names, 5);! ! System.out.println("After filtering: " + shortNames.size());! ! for (int i=0; i < shortNames.size(); i++) {! ! ! String s = shortNames.get(i);! ! ! System.out.println(s);! ! }! }}
venerdì 28 giugno 13
import java.util.List;import java.util.ArrayList;
class Filter {! static List<String> filterLongerThan(List<String> xs, int maxLen) {! ! List<String> results = new ArrayList<String>();! ! for (int i=0; i < xs.size(); i++){! ! ! String s = xs.get(i);! ! ! if (s.length() <= maxLen){! ! ! ! results.add(s);! ! ! }! ! }! ! return results;! }! public static void main(String[] args) {! ! List<String> names = new ArrayList<String>();! ! names.add("Giulio"); names.add("Laura");! ! names.add("Mario"); names.add("Anna");! ! System.out.println(names);! ! List<String> shortNames = filterLongerThan(names, 5);! ! System.out.println("After filtering: " + shortNames.size());! ! for (int i=0; i < shortNames.size(); i++) {! ! ! String s = shortNames.get(i);! ! ! System.out.println(s);! ! }! }}
venerdì 28 giugno 13
import java.util.List;import java.util.ArrayList;
class Filter {! static List<String> filterLongerThan(List<String> xs, int maxLen) {! ! List<String> results = new ArrayList<String>();! ! for (int i=0; i < xs.size(); i++){! ! ! String s = xs.get(i);! ! ! if (s.length() <= maxLen){! ! ! ! results.add(s);! ! ! }! ! }! ! return results;! }! public static void main(String[] args) {! ! List<String> names = new ArrayList<String>();! ! names.add("Giulio"); names.add("Laura");! ! names.add("Mario"); names.add("Anna");! ! System.out.println(names);! ! List<String> shortNames = filterLongerThan(names, 5);! ! System.out.println("After filtering: " + shortNames.size());! ! for (int i=0; i < shortNames.size(); i++) {! ! ! String s = shortNames.get(i);! ! ! System.out.println(s);! ! }! }}
venerdì 28 giugno 13
import java.util.List;import java.util.ArrayList;
class Filter {! static List<String> filterLongerThan(List<String> xs, int maxLen) {! ! List<String> results = new ArrayList<String>();! ! for (int i=0; i < xs.size(); i++){! ! ! String s = xs.get(i);! ! ! if (s.length() <= maxLen){! ! ! ! results.add(s);! ! ! }! ! }! ! return results;! }! public static void main(String[] args) {! ! List<String> names = new ArrayList<String>();! ! names.add("Giulio"); names.add("Laura");! ! names.add("Mario"); names.add("Anna");! ! System.out.println(names);! ! List<String> shortNames = filterLongerThan(names, 5);! ! System.out.println("After filtering: " + shortNames.size());! ! for (int i=0; i < shortNames.size(); i++) {! ! ! String s = shortNames.get(i);! ! ! System.out.println(s);! ! }! }}
venerdì 28 giugno 13
import java.util.List;import java.util.ArrayList;
class Filter {! static List<String> filterLongerThan(List<String> xs, int maxLen) {! ! List<String> results = []! ! for (int i=0; i < xs.size(); i++){! ! ! String s = xs[i]! ! ! if (s.length() <= maxLen){! ! ! ! results << s! ! ! }! ! }! ! return results;! }! public static void main(String[] args) {! ! List<String> names = ["Giulio", "Laura", "Mario", "Anna"]! ! System.out.println(names);! ! List<String> shortNames = filterLongerThan(names, 5);! ! System.out.println("After filtering: " + shortNames.size());! ! for (int i=0; i < shortNames.size(); i++) {! ! ! String s = shortNames[i]! ! ! System.out.println(s);! ! }! }}
venerdì 28 giugno 13
import java.util.List;import java.util.ArrayList;
class Filter { static List<String> filterLongerThan(List<String> xs, int maxLen) { List<String> results = [] for (int i=0; i < xs.size(); i++){ String s = xs[i] if (s.length() <= maxLen){ results << s } } return results; } public static void main(String[] args) { List<String> names = ["Giulio", "Laura", "Mario", "Anna"] System.out.println(names); List<String> shortNames = filterLongerThan(names, 5); System.out.println("After filtering: " + shortNames.size()); for (int i=0; i < shortNames.size(); i++) { String s = shortNames[i]; System.out.println(s); } }}
venerdì 28 giugno 13
import java.util.List;import java.util.ArrayList;
class Filter { static List<String> filterLongerThan(List<String> xs, int maxLen) { List<String> results = [] for (int i=0; i < xs.size(); i++){ String s = xs[i] if (s.length() <= maxLen){ results << s } } return results; } public static void main(String[] args) { List<String> names = ["Giulio", "Laura", "Mario", "Anna"] System.out.println(names); List<String> shortNames = filterLongerThan(names, 5); System.out.println("After filtering: " + shortNames.size()); for (int i=0; i < shortNames.size(); i++) { String s = shortNames[i]; System.out.println(s); } }}
venerdì 28 giugno 13
class Filter { static List<String> filterLongerThan(List<String> xs, int maxLen) { List<String> results = [] xs.each { s -> if (s.length() <= maxLen){ results << s } } return results; } public static void main(String[] args) { List<String> names = ["Giulio", "Laura", "Mario", "Anna"] println(names); List<String> shortNames = filterLongerThan(names, 5); println("After filtering: " + shortNames.size()); shortNames.each { println(it) } }}
venerdì 28 giugno 13
class Filter { static List<String> filterLongerThan(List<String> xs, int maxLen) { List<String> results = [] results = xs.findAll { s -> s.length() <= maxLen } return results; } public static void main(String[] args) { List<String> names = ["Giulio", "Laura", "Mario", "Anna"] println(names) List<String> shortNames = filterLongerThan(names, 5) println("After filtering: " + shortNames.size()) shortNames.each { println(it) } }}
venerdì 28 giugno 13
class Filter { static List<String> filterLongerThan(List<String> xs, int maxLen) { xs.findAll { s -> s.length() <= maxLen } } public static void main(String[] args) { List<String> names = ["Giulio", "Laura", "Mario", "Anna"] println(names); List<String> shortNames = filterLongerThan(names, 5); println("After filtering: " + shortNames.size()); shortNames.each { println(it) } }}
venerdì 28 giugno 13
class Filter { static List<String> filterLongerThan(List<String> xs, int maxLen) { xs.findAll { s -> s.length() <= maxLen } } public static void main(String[] args) { List<String> names = ["Giulio", "Laura", "Mario", "Anna"] println(names) List<String> shortNames = filterLongerThan(names, 5) println("After filtering: " + shortNames.size()) shortNames.each { println(it) } }}
venerdì 28 giugno 13
class Filter { static List<String> filterLongerThan(List<String> xs, int maxLen) { xs.findAll { s -> s.length() <= maxLen } } public static void main(String[] args) { List<String> names = ["Giulio", "Laura", "Mario", "Anna"] println(names) List<String> shortNames = filterLongerThan(names, 5) println("After filtering: ${shortNames.size()}") shortNames.each { println(it) } }}
venerdì 28 giugno 13
class Filter { public static void main(String[] args) { List<String> names = ["Giulio", "Laura", "Mario", "Anna"] int maxLen = 5 println(names) List<String> shortNames = names.findAll { s -> s.length() <= maxLen } println("After filtering: ${shortNames.size()}") shortNames.each { println(it) } }}
-70%
venerdì 28 giugno 13
class Filter { public static void main(String[] args) { List<String> names = ["Giulio", "Laura", "Mario", "Anna"] int maxLen = 5 println(names) List<String> shortNames = names.findAll { s -> s.length() <= maxLen } println("After filtering: ${shortNames.size()}") shortNames.each { println(it) } }}
venerdì 28 giugno 13
Dinamico
• Aggiunta a compile-time di funzionalità: metodi, propietà, costruttori
• Runtime mixins ed invocazione di metodi il cui nome risiede in una variabile
venerdì 28 giugno 13
Dinamico - ExpandoMetaClass
Aggiunta funzionalità a
compile-time anche se final
venerdì 28 giugno 13
Dinamico - Mixin di metodi@Category(Vehicle) class FlyingAbility { def fly() { "${name}: fly!" }}
@Category(Vehicle) class DivingAbility { def dive() { "${name}: dive!" }}
interface Vehicle { String getName()}
@Mixin(FlyingAbility)class Plane implements Vehicle { String getName() { "Concorde" }}
@Mixin([DivingAbility, FlyingAbility])class JamesBondVehicle implements Vehicle { String getName() { "James Bond's vehicle" }}
assert new Plane().fly() == "Concorde: fly!"assert new JamesBondVehicle().fly() == "James Bond's vehicle: fly!"assert new JamesBondVehicle().dive() == "James Bond's vehicle: dive!"
venerdì 28 giugno 13
Dinamico - Via annotation• Iniezione funzionalità via annotation
• @Immutable (@Canonical)
• @Bindable
• @Delegate
• @Newify
• @Lazy
• @Log
• etc.
venerdì 28 giugno 13
Funzionale
• Funzioni come first class citizens (Closure)
• associabili ad una variabile
• usate come parametri di altre funzioni
• componibili
• zucchero sintattico
venerdì 28 giugno 13
La Groovy “verità”
• Regole per la coercizione in boolean
• Collezioni: true se NON vuote
• Stringhe: true se NON vuote o nulle
• Oggetti: true se NON nulli
• Regexp Pattern: true se MATCH
venerdì 28 giugno 13
Groovy truth - Esempi
Usa gli operatori ?. e ?: in
combinazione per evitare NPE
venerdì 28 giugno 13
Slurper<?xml version="1.0" ?><customers> <customer name="Mario Rossi" /> <customer name="Giovanni Bianchi" /></customers>
import java.io.*;import javax.xml.parsers.*;import org.w3c.dom.*;
public class XMLReader { public static void main(String argv[]) throws Exception { File file = new File("customers.xml"); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(file); doc.getDocumentElement().normalize(); NodeList nodeLst = doc.getElementsByTagName("customer"); for (int s = 0; s < nodeLst.getLength(); s++) { Element item = (Element) nodeLst.item(s); System.out.println(item.getAttribute("name")); } }}
venerdì 28 giugno 13
Slurper<?xml version="1.0" ?><customers> <customer name="Mario Rossi" /> <customer name="Giovanni Bianchi" /></customers>
def xmlFile = new File('customers.xml')def xml = new XmlSlurper().parse(xmlFile)
xml.customer.each { println it.'@name'.text()}
Anche per JSON, Config, ...
venerdì 28 giugno 13
Performance
• Dinamico implica overhead
• spesso diversi punti %
• Molti miglioramenti da Groovy 2.0
• primitiva invokeDynamic (Java 7)
• @CompileStatic
• Valutare trade-off produttività VS velocità
venerdì 28 giugno 13
Performance...@Grab('com.googlecode.gbench:gbench:0.4.2-groovy-2.1') import gbench.BenchmarkBuilder import groovy.transform.CompileStatic int fib(int n) { if (n < 2) return n return fib(n - 1) + fib(n - 2) } @CompileStatic int fib2(int n) { if (n < 2) return n return fib2(n - 1) + fib2(n - 2) } new BenchmarkBuilder().run { int n = 20 "Normal Version" { fib n } "@CompileStatic Version" { fib2 n } }.prettyPrint()
venerdì 28 giugno 13
Performance...@Grab('com.googlecode.gbench:gbench:0.4.2-groovy-2.1') import gbench.BenchmarkBuilder import groovy.transform.CompileStatic int fib(int n) { if (n < 2) return n return fib(n - 1) + fib(n - 2) } @CompileStatic int fib2(int n) { if (n < 2) return n return fib2(n - 1) + fib2(n - 2) } new BenchmarkBuilder().run { int n = 20 "Normal Version" { fib n } "@CompileStatic Version" { fib2 n } }.prettyPrint()
* JVM: Java HotSpot(TM) 64-Bit Server VM (23.6-b04...* JRE: 1.7.0_10* Total Memory: 81.1875 MB* Maximum Memory: 1123.5625 MB* OS: Mac OS X (10.7.5, x86_64)
Options=======* Warm Up: Auto * CPU Time Measurement: On
user system cpu real
Normal Version 92622 7 92630 92626 @CompileStatic Version 39974 3 39977 39976
venerdì 28 giugno 13
Ecosistema
Geb, Spock, WSLite...
Nella seconda parte
approfondiremo il discorso
su queste tecnologie!
venerdì 28 giugno 13
Riferimenti• Groovy User Guide - http://groovy.codehaus.org/User+Guide
• Bob Brown - The future is Gr8 - http://wordpress.transentia.com.au/wordpress/2013/05/07/disaster/
• Sergey Dolgopolov - Testing the performance of new Groovy 2.0 release with GBench - http://www.sergeydolgopolov.me/2012/07/groovy-20-has-been-released-testing-new.html
• Guillame Laforge - Groovy Ecosystem - http://www.slideshare.net/glaforge/groovy-ecosystem-jfokus-2011-guillaume-laforge
• Hubert Klein Ikkink (aka mrhaki) - Groovy goodness blog - http://mrhaki.blogspot.it/
• Geb Samples - http://www.gebish.org
• GPars Samples for Dataflow and Actors - http://gpars.codehaus.org
• Spock Samples - http://code.google.com/p/spock/
• Tim Myer - http://timezra.blogspot.it/2011/11/trampoline-and-memoize.html
venerdì 28 giugno 13
Web: http://rolandfg.net Twitter: @flerro
venerdì 28 giugno 13
top related