Merci de participer ce matin à notre petite série d’exercice sur Groovy. Après un échauffement, nous allons travailler les abdos-fixtures, faire quelques moulinets de Closures, s’étirer avec des astuces sur les fichiers, bref que du bon code pour débuter. Je vous prends en main cette semaine, avec chaque jour un petit exercice simple afin de vous réhabituer à un bon langage, léger
Après avoir pris votre tapis… de souris, venez vous assoir devant moi, et écouter attentivement. Les exercices sont adaptés du livre « Groovy Recipes » par Scott Davis pour ceux qui veulent pratiquer de leur côté.
La surchage pondérale d’opérateur
Grâce à Java, je sais que ce petit problème de surcharge pondérale n’était plus trop d’actualité. Pourtant nous allons voir ensemble qu’avec Groovy, la surcharge d’opérateur est une chose très pratique. Pour cela, nous allons travailler avec la date.
Notre série d’exercices se déroulera dans une salle toute neuve hébergée sur Google App Engine (prononcez eng-i-neu) développée avec Gaelyk par Guillaume Laforge. Ouvrez donc la Groovy Web Console et débutons par quelques exercices simples pour travailler la surcharge d’opérateur. Tapez simplement le texte ci-dessous puis appuyez sur « Execute script« . Je note avec le symbole « => » le résultat de l’opération.
def today=new Date() => Mon Jan 25 07:57:43 UTC 2010
La surcharge d’opérateur est une fonction très pratique en Groovy. Imaginons que vous souhaitez connaître la data dans 7 jours. L’opérateur ‘+’ étant surchargé dans le cas d’une Date, il est alors possible d’écrire ce code:
def today=new Date() println today => Tue Jan 26 08:28:33 UTC 2010 def tomorrow=today.next() println tomorrow => Wed Jan 27 08:28:33 UTC 2010 def nextWeek=tomorrow+7 println nextWeek => Wed Feb 03 08:28:33 UTC 2010 def yesterday=today.previous() println yesterday => Mon Jan 25 08:28:33 UTC 2010
Derrière l’opérateur plus, Groovy appelle la fonction next(). Voici une liste des opérateurs et des méthodes correspondants à ces opérateurs en Groovy :
Opérateur Méthode a==b or a!=b a.equals(b) a + b a.plus(b) a - b a.minus(b) a * b a.multiply(b) a / b a.div(b) a % b a.mod(b) a++ ou ++a a.next() a-- ou --a a.previous() a & b a.and(b) a | b a.or(b)
Les opérateurs suivants sont plus communs, surtout lors de la manipulation des Listes :
Opérateur Méthode a[b] a.getAt(b) a[b]=c a.putAt(b,c) a << b a.leftShift(b) a >> b a.righShift(b) a < b ou a > b a.compareTo(b) a <= b / a >= b a.compareTo(b)
La manipulation des listes est encore plus simple en Groovy qu’en Java. Il est donc possible d’écrire par exemple ce bout de code (tiré du livre Groovy Recipes par Scott Davis).
def today=new Date() (1..7).each{ println today++ } => Mon Jan 25 09:31:41 CET 2010 Tue Jan 26 09:31:41 CET 2010 Wed Jan 27 09:31:41 CET 2010 Thu Jan 28 09:31:41 CET 2010 Fri Jan 29 09:31:41 CET 2010 Sat Jan 30 09:31:41 CET 2010 Sun Jan 31 09:31:41 CET 2010
Note: Ce code ne marchera que sur votre machine en local en utilisant groovyConsole.
Passage sur le dos, parlons des listes
Avez-vous noté la notation (1..7) dans l’exercice précèdent ? C’est ce que l’on appelle une Range en Groovy. Pratique non ?
Passons à un exercice plus intéressant, et plus proche de ce que vous allez pratiquer avec Groovy d’ici quelques semaines : la manipulation des listes, des Maps et des Sets en Groovy.
Création d’une liste
La syntaxe est simple. Une liste est créé en utilisant les crochets. C’est une ArrayList simple, ni plus, ni moins.
def touilleurThemes=["Java","Apple","Scrum","Groovy"] println touilleurThemes => [Java, Groovy, Scrum, Apple] println touilleurThemes.size() => 4 touilleurThemes << "Web 2.0" println touilleurThemes => [Java, Groovy, Scrum, Apple,Web 2.0] // Récuperer le premier élement println touilleurThemes.first() => Java println touilleurThemes[0] => Java
Itérer une liste en Groovy
Les closures sont utilisées lors de l’itération d’une liste. Voici quelques exemples d’itérations de la liste :
// Itération simple def touilleurThemes=["Java","Groovy","Scrum","Apple"] touilleurThemes.each{nom-> println nom } =>Java Groovy Scrum Apple // Verson simplifié, it est une variable implicite // Itération encore plus simple def touilleurThemes=["Java","Groovy","Scrum","Apple"] touilleurThemes.each{ println it }
Il reste possible d’itérer la liste en utilisant la syntaxe de Java 5 si vous préférez celle-ci :
def touilleurThemes=["Java","Groovy","Scrum","Apple"] for(String item : touilleurThemes) { println item } =>Java Groovy Scrum Apple
Trier, ranger, manipuler une liste
Les listes sont des objets facilement manipulables. Il est possible de les trier, de les découper, de dépiler un élément comme sur une Queue, de rechercher un pattern, bref de faire un grand nombre d’opérations très pratique. Plutôt qu’un long discours, regardez attentivement ces exemples de code. Vous me ferrez 2 séries de 10, avec une grande respiration entre chaque exercice.
// Trier une liste avec sort // Le tri est permanent, la liste originale est triée def languages=["Java","Groovy","Scala","Lisp","Clojure","Perl","Python"] languages.sort() languages.each{ println it } =>Clojure Groovy Java Lisp Perl Python Scala // Retourner une liste, cette fois-ci la liste originale // ne sera pas modifiée. def revertedList=languages.reverse() revertedList.each{ println it } => Scala Python Perl Lisp Java Groovy Clojure // 3 Dépiler le dernier élément def languages=["Java","Groovy","Scala","Lisp","Clojure","Perl","Python"] println languages.pop() => Python // 4 Concatenation def languages=["Java","Groovy","Scala","Lisp","Clojure","Perl","Python"] def newLanguages=["Ruby","Goo","Javascript"] languages+=newLanguages println languages => [Java, Groovy, Scala, Lisp, Clojure, Perl, Python, Ruby, Goo, Javascript] languages-=newLanguages println languages => [Java, Groovy, Scala, Lisp, Clojure, Perl, Python]
Il est possible aussi de joindre une liste en une seule String, ou même de spécifier un séparateur par exemple. Très pratique lorsque vous souhaitez écrire une ligne au format CSV à partir d’une liste de résultats :
def languages=["Java","Groovy","Scala","Lisp","Clojure","Perl","Python"] println languages.join() //JavaGroovyScalaLispClojurePerlPython println languages.join(",") //Java,Groovy,Scala,Lisp,Clojure,Perl,Python
Les closures peuvent aussi être utilisées pour rechercher un élément rapidement dans une liste. Imaginons que vous souhaitez retrouver l’ensemble des noms commençant par la lettre J :
def languages=["Java","Groovy","Scala","Lisp","Clojure","JRuby","Jython"] def resultList = languages.findAll {it.startsWith("J")} resultList.each{println it} =>Java JRuby Jython
Les listes de chiffres sont faciles à manipuler, il est possible d’additionner la série, de rechercher la valeur maximum ou minimum :
def ages=[23,34,45,12,46,21,42,56,18] println ages.max() => 56 println ages.min() => 12 println ages.sum() => 297 println "Moyenne: " + ages.sum()/ages.size() =>33
La méthode collect permet de créer une nouvelle liste en concaténant un Objet à chacun des éléments de la liste initiale.
def ages=[23,34,45] def resultList=ages.collect{ it += " ans"} resultList.each{println it} =>23 ans 34 ans 45 ans
L’opérateur Spread (*)
L’opérateur Spread (marqué avec une astérisque *) est un opérateur courant utilisé pour exécuter une méthode sur chacun des éléments d’une liste, ou pour aussi distribuer les éléments d’une liste à une méthode. Il y a 2 variantes. L’opérateur spread seul (*) et l’opérateur spread-dot (noté *.).
L’opérateur spread seul peut être utilisé pour passer une liste d’argument à une méthode. Il va itérer chacun des éléments et les passer un à un. C’est peu commun donc je n’en parlerai pas plus ici. L’opérateur spread-dot est plus courant. Dans l’exemple ci-dessous, le caractère *. signifie : prend chacun des éléments de la liste et effectue un appel à la méthode toUpperCase, stocke le tout dans une nouvelle liste.
def languages=["Java","Groovy","Goo"] // L'opérateur Spread dot def resultList=languages*.toUpperCase() // Affiche la nouvelle liste resultList.each{println it} => JAVA, GROOVY, GOO
Conclusion
Voilà c’est tout pour ce matin. Nous verrons la suite demain. Passez une bonne journée !
Sympa ce post ! J’imagine qu’il y aura d’autres séances de gymnastique ! Au moins, ça permettra à ceux qui ont pris comme bonne résolution 2010 de faire du sport, de la tenir !
Sinon, dans les codes, il faut faire attention. Le « <<" se transforme en "< <", ce qui n'est pas correct, of course… (peut-être un bug du syntax highlighter ?)
@Romaintaz : c’est corrigé. J’ai mis & lt; et c’est passé
Très bonne présentation de certaines particularités de Groovy ! Pour info, l’itération sur le range marche aussi sur la Groovy Web Console.
euh, et Davina elle s’est cachée derrière un intersect()?? 😉
Bonsoir,
excellente idée que cet exercice quotidien! J’aime beaucoup le style d’écriture (comme toujours ici 🙂
Une remarque cependant, pour l’affichage des résultats des commandes je trouve plus explicite d’utiliser les assert (comme sur le wiki de Groovy ou les groovy goodness. Question d’habitude certainement 🙂
Bonne continuation !
Nb : Le site de groovy n’est pas groovy.org comme l’indique les liens de l’article mais http://groovy.codehaus.org(c’est corrigé)