Apache Groovy - Apache Groovy

Sensationnel
Groovy-logo.svg
Logo Groovy
Paradigme Orienté objet , impératif , scripting
Conçu par James Strachan
Développeur Guillaume Laforge (président PMC)
Jochen Theodorou (chef technique)
Paul King
Cédric Champeau
Première apparition 2003 ; il y a 18 ans ( 2003 )
Version stable 3.0.8 (16 avril 2021 ; il y a 5 mois ) [±] ( 2021-04-16 )
Version préliminaire
4.0.0-beta-1 / 6 septembre 2021 ; il y a 34 jours ( 2021-09-06 )
Discipline de frappe Dynamique , statique , fort , canard
Plate-forme Java SE
Licence Licence Apache 2.0
Extensions de nom de fichier .groovy, .gvy, .gy, .gsh
Site Internet groovy-lang .org Modifiez ceci sur Wikidata
Les principales mises en œuvre
Gradle , Graals
Influencé par
Java , Python , Ruby , Smalltalk
Influencé
Kotlin

Apache Groovy est un langage de programmation orienté objet compatible avec la syntaxe Java pour la plate-forme Java . C'est à la fois un langage statique et dynamique avec des fonctionnalités similaires à celles de Python , Ruby et Smalltalk . Il peut être utilisé à la fois comme langage de programmation et comme langage de script pour la plate-forme Java, est compilé en bytecode de machine virtuelle Java (JVM) et interagit de manière transparente avec d'autres codes et bibliothèques Java . Groovy utilise une syntaxe d'accolades similaire à celle de Java. Groovy prend en charge les fermetures , les chaînes multilignes et les expressions intégrées dans les chaînes . Une grande partie de la puissance de Groovy réside dans ses transformations AST , déclenchées par des annotations.

Groovy 1.0 est sorti le 2 janvier 2007 et Groovy 2.0 en juillet 2012. Depuis la version 2, Groovy peut être compilé de manière statique , offrant une inférence de type et des performances proches de celles de Java. Groovy 2.4 était la dernière version majeure sous le parrainage de Pivotal Software qui a pris fin en mars 2015. Groovy a depuis changé sa structure de gouvernance en un comité de gestion de projet au sein de l'Apache Software Foundation .

Histoire

James Strachan a parlé pour la première fois du développement de Groovy sur son blog en août 2003. En mars 2004, Groovy a été soumis au JCP en tant que JSR 241 et accepté par scrutin. Plusieurs versions ont été publiées entre 2004 et 2006. Après le début de l'effort de normalisation Java Community Process (JCP), la numérotation des versions a changé et une version appelée "1.0" a été publiée le 2 janvier 2007. Après diverses versions bêta et candidates numérotées 1.1, le 7 décembre 2007, Groovy 1.1 Final a été publié et immédiatement renuméroté Groovy 1.5 pour refléter les nombreux changements apportés.

En 2007, Groovy a remporté le premier prix au prix de l'innovation JAX 2007. En 2008, Grails , un framework web Groovy , a remporté le deuxième prix du JAX 2008 Innovation Award.

En novembre 2008, SpringSource a acquis la société Groovy and Grails (G2One). En août 2009, VMware a acquis SpringSource.

En avril 2012, après huit ans d'inactivité, le Spec Lead a changé le statut de JSR 241 en dormant.

Strachan avait quitté le projet en silence un an avant la sortie de Groovy 1.0 en 2007. En octobre 2016, Strachan a déclaré : « J'aime toujours le groovy (les pipelines jenkins sont tellement groovy !), Java, go, tapuscrit et kotlin ».

Le 2 juillet 2012, Groovy 2.0 a été publié, qui, entre autres nouvelles fonctionnalités, a ajouté la compilation statique et la vérification de type statique .

Lorsque la coentreprise Pivotal Software a été scindée par EMC Corporation (EMC) et VMware en avril 2013, Groovy et Grails faisaient partie de son portefeuille de produits. Pivotal a cessé de parrainer Groovy et Grails à partir d'avril 2015. Le même mois, Groovy a modifié sa structure de gouvernance, passant d'un référentiel Codehaus à un comité de gestion de projet (PMC) au sein de l' Apache Software Foundation via son incubateur. Groovy est diplômé de l'incubateur Apache et est devenu un projet de haut niveau en novembre 2015.

Caractéristiques

La plupart des fichiers Java valides sont également des fichiers Groovy valides. Bien que les deux langages soient similaires, le code Groovy peut être plus compact, car il n'a pas besoin de tous les éléments dont Java a besoin. Cela permet aux programmeurs Java d'apprendre Groovy progressivement en commençant par la syntaxe Java familière avant d'acquérir plus d' idiomes de programmation Groovy .

Les fonctionnalités Groovy non disponibles dans Java incluent à la fois le typage statique et dynamique (avec le mot-clé def), la surcharge d'opérateurs , la syntaxe native pour les listes et les tableaux associatifs (maps), la prise en charge native des expressions régulières , l'itération polymorphe, l' interpolation de chaîne , les méthodes d'assistance ajoutées et le opérateur de navigation sécurisée ?. pour rechercher automatiquement les pointeurs nuls (par exemple, variable?.method(), ou variable?.field).

Depuis la version 2, Groovy prend également en charge la modularité (pouvant n'expédier que les pots nécessaires en fonction des besoins du projet, réduisant ainsi la taille de la bibliothèque de Groovy), la vérification de type, la compilation statique, les améliorations de la syntaxe de Project Coin, les blocs multicatch et les améliorations continues des performances à l'aide du invokedynamicinstruction introduite dans Java 7 .

Groovy fournit une prise en charge native de divers langages de balisage tels que XML et HTML , réalisé via une syntaxe DOM ( Document Object Model ) en ligne. Cette fonctionnalité permet la définition et la manipulation de nombreux types d'actifs de données hétérogènes avec une syntaxe et une méthodologie de programmation uniformes et concises.

Contrairement à Java, un fichier de code source Groovy peut être exécuté en tant que script (non compilé) , s'il contient du code en dehors de toute définition de classe, s'il s'agit d'une classe avec une méthode principale , ou s'il s'agit d'un Runnable ou d'un GroovyTestCase . Un script Groovy est entièrement analysé, compilé et généré avant d'être exécuté (similaire à Python et Ruby). Cela se produit sous le capot et la version compilée n'est pas enregistrée en tant qu'artefact du processus.

GroovyBeans, propriétés

GroovyBeans est la version Groovy de JavaBeans . Groovy génère implicitement des getters et des setters. Dans le code suivant, setColor(String color)et getColor()sont générés implicitement. Les deux dernières lignes, qui semblent accéder directement à la couleur, appellent en fait les méthodes générées implicitement.

class AGroovyBean {
  String color
}

def myGroovyBean = new AGroovyBean()

myGroovyBean.setColor('baby blue')
assert myGroovyBean.getColor() == 'baby blue'

myGroovyBean.color = 'pewter'
assert myGroovyBean.color == 'pewter'

Groovy propose une syntaxe simple et cohérente pour la gestion des listes et des cartes , rappelant la syntaxe des tableaux de Java .

def movieList = ['Dersu Uzala', 'Ran', 'Seven Samurai']  // Looks like an array, but is a list
assert movieList[2] == 'Seven Samurai'
movieList[3] = 'Casablanca'  // Adds an element to the list
assert movieList.size() == 4

def monthMap = [ 'January' : 31, 'February' : 28, 'March' : 31 ]  // Declares a map
assert monthMap['March'] == 31  // Accesses an entry
monthMap['April'] = 30  // Adds an entry to the map
assert monthMap.size() == 4

Extension de prototype

Offres Groovy soutien pour l' extension prototype par ExpandoMetaClass, les modules d' extension (uniquement dans Groovy 2), C comme objectif Catégories et DelegatingMetaClass.

ExpandoMetaClasspropose un langage spécifique au domaine (DSL) pour exprimer facilement les changements dans la classe, similaire au concept de classe ouverte de Ruby :

Number.metaClass {
  sqrt = { Math.sqrt(delegate) }
}

assert 9.sqrt() == 3
assert 4.sqrt() == 2

Les modifications de code de Groovy via le prototypage ne sont pas visibles dans Java, car chaque appel d'attribut/méthode dans Groovy passe par le registre de la métaclasse. Le code modifié n'est accessible qu'à partir de Java en accédant au registre de la métaclasse.

Groovy permet également de surcharger des méthodes comme getProperty(), propertyMissing()entre autres, permettant au développeur d'intercepter les appels à un objet et de spécifier une action pour eux, d'une manière simplifiée orientée aspect . Le code suivant permet à la classe java.lang.Stringde répondre à la hexpropriété :

enum Color {
  BLACK('#000000'), WHITE('#FFFFFF'), RED('#FF0000'), BLUE('#0000FF')
  String hex
  Color(String hex) { 
    this.hex = hex 
  }
}

String.metaClass.getProperty = { String property ->
  def stringColor = delegate
  if (property == 'hex') {
    Color.values().find { it.name().equalsIgnoreCase stringColor }?.hex
  }
}

assert "WHITE".hex == "#FFFFFF"
assert "BLUE".hex == "#0000FF"
assert "BLACK".hex == "#000000"
assert "GREEN".hex == null

Le framework Grails utilise largement la métaprogrammation pour activer les chercheurs dynamiques GORM , comme User.findByName('Josh')et autres.

Point et parenthèses

La syntaxe de Groovy permet d'omettre les parenthèses et les points dans certaines situations. Le code groovy suivant

take(coffee).with(sugar, milk).and(liquor)

peut être écrit comme

take coffee with sugar, milk and liquor

permettant le développement de langages spécifiques à un domaine (DSL) qui ressemblent à un anglais simple.

Programmation fonctionnelle

Bien que Groovy soit principalement un langage orienté objet, il offre également des fonctionnalités de programmation fonctionnelles.

Fermetures

Selon la documentation de Groovy : "Les fermetures dans Groovy fonctionnent de manière similaire à un" pointeur de méthode ", permettant au code d'être écrit et exécuté à un moment ultérieur". Les fermetures de Groovy prennent en charge les variables libres, c'est-à-dire les variables qui ne lui ont pas été explicitement passées en paramètre, mais existent dans son contexte de déclaration, d'application partielle (qu'il appelle ' currying '), de délégation, de paramètres implicites, typés et non typés.

Lorsqu'on travaille sur des Collections d'un type déterminé, la fermeture passée à une opération sur la collection peut être déduite :

list = [1, 2, 3, 4, 5, 6, 7, 8, 9]

/* 
 * Non-zero numbers are coerced to true, so when it % 2 == 0 (even), it is false.
 * The type of the implicit "it" parameter can be inferred as an Integer by the IDE.
 * It could also be written as:
 * list.findAll { Integer i -> i % 2 }
 * list.findAll { i -> i % 2 }
 */
def odds = list.findAll { it % 2 }

assert odds == [1, 3, 5, 7, 9]

Un groupe d'expressions peut être écrit dans un bloc de fermeture sans référence à une implémentation et l'objet répondant peut être affecté ultérieurement à l'aide de la délégation :

// This block of code contains expressions without reference to an implementation
def operations = {
  declare 5
  sum 4
  divide 3
  print
}
/* 
 * This class will handle the operations that can be used in the closure above. Another class
 * could be declared having the same methods, but using, for example, webservice operations
 * in the calculations.
 */
class Expression {
  BigDecimal value

  /* 
   * Though an Integer is passed as a parameter, it is coerced into a BigDecimal, as was 
   * defined. If the class had a 'declare(Integer value)' method, it would be used instead.
   */
  def declare(BigDecimal value) {
    this.value = value
  }
  
  def sum(BigDecimal valueToAdd) {
    this.value += valueToAdd
  }
  
  def divide(BigDecimal divisor) {
    this.value /= divisor
  }
  
  def propertyMissing(String property) {
    if (property == "print") println value
  }
}
// Here is defined who is going to respond the expressions in the block of code above.
operations.delegate = new Expression()
operations()

Curry

Généralement appelée application partielle , cette fonctionnalité Groovy permet de définir les paramètres des fermetures sur un paramètre par défaut dans n'importe lequel de leurs arguments, créant une nouvelle fermeture avec la valeur liée. Fournir un argument à la curry()méthode corrigera l'argument un. Fournir N arguments corrigera les arguments 1 .. N.

def joinTwoWordsWithSymbol = { symbol, first, second -> first + symbol + second }
assert joinTwoWordsWithSymbol('#', 'Hello', 'World') == 'Hello#World'

def concatWords = joinTwoWordsWithSymbol.curry(' ')
assert concatWords('Hello', 'World') == 'Hello World'

def prependHello = concatWords.curry('Hello')
//def prependHello = joinTwoWordsWithSymbol.curry(' ', 'Hello')
assert prependHello('World') == 'Hello World'

Le curry peut également être utilisé dans le sens inverse (en fixant les N derniers arguments) à l'aide de rcurry().

def power = { BigDecimal value, BigDecimal power ->
  value**power
}

def square = power.rcurry(2)
def cube = power.rcurry(3)

assert power(2, 2) == 4
assert square(4) == 16
assert cube(3) == 27

Groovy prend également en charge l' évaluation paresseuse , les réductions/plis , les structures infinies et l' immutabilité , entre autres.

Traitement JSON et XML

Sur le traitement JavaScript Object Notation ( JSON ) et XML, Groovy utilise le modèle Builder , ce qui rend la production de la structure de données moins détaillée. Par exemple, le XML suivant :

<languages>
  <language year="1995">
    <name>Java</name>
    <paradigm>object oriented</paradigm>
    <typing>static</typing>
  </language>
  <language year="1995">
    <name>Ruby</name>
    <paradigm>functional, object oriented</paradigm>
    <typing>duck typing, dynamic</typing>
  </language>
  <language year="2003">
    <name>Groovy</name>
    <paradigm>functional, object oriented</paradigm>
    <typing>duck typing, dynamic, static</typing>
  </language>
</languages>

peut être généré via le code Groovy suivant :

def writer = new StringWriter()
def builder = new groovy.xml.MarkupBuilder(writer)
builder.languages {
  language(year: 1995) {
    name "Java"
    paradigm "object oriented"
    typing "static"
  }
  language (year: 1995) {
    name "Ruby"
    paradigm "functional, object oriented"
    typing "duck typing, dynamic"
  }
  language (year: 2003) {
    name "Groovy"
    paradigm "functional, object oriented"
    typing "duck typing, dynamic, static"
  }
}

et peut également être traité en streaming via StreamingMarkupBuilder. Pour modifier l'implémentation en JSON, le MarkupBuilderpeut être remplacé par JsonBuilder.

Pour l'analyser et rechercher un langage fonctionnel, la findAllméthode de Groovy peut servir :

def languages = new XmlSlurper().parseText writer.toString()

// Here is employed Groovy's regex syntax for a matcher (=~) that will be coerced to a 
// boolean value: either true, if the value contains our string, or false otherwise.
def functional = languages.language.findAll { it.paradigm =~ "functional" }
assert functional.collect { it.name } == ["Groovy", "Ruby"]

Interpolation de chaîne

Dans Groovy, les chaînes peuvent être interpolées avec des variables et des expressions en utilisant GStrings :

BigDecimal account = 10.0
def text = "The account shows currently a balance of $account"
assert text == "The account shows currently a balance of 10.0"

Les GStrings contenant des variables et des expressions doivent être déclarées à l'aide de guillemets doubles.

Une expression complexe doit être placée entre accolades. Cela empêche que des parties de celui-ci soient interprétées comme appartenant à la chaîne environnante au lieu de l'expression :

BigDecimal minus = 4.0
text = "The account shows currently a balance of ${account - minus}"
assert text == "The account shows currently a balance of 6.0"

// Without the brackets to isolate the expression, this would result:
text = "The account shows currently a balance of $account - minus"
assert text == "The account shows currently a balance of 10.0 - minus"

L'évaluation de l'expression peut être différée en utilisant la syntaxe de la flèche :

BigDecimal tax = 0.15
text = "The account shows currently a balance of ${->account - account*tax}"
tax = 0.10

// The tax value was changed AFTER declaration of the GString. The expression 
// variables are bound only when the expression must actually be evaluated:
assert text == "The account shows currently a balance of 9.000"

Transformation d'arbre de syntaxe abstraite

Selon la propre documentation de Groovy, "Lorsque le compilateur Groovy compile des scripts et des classes Groovy, à un moment donné du processus, le code source finira par être représenté en mémoire sous la forme d'un arbre de syntaxe concret, puis transformé en un arbre de syntaxe abstrait Le but des transformations AST est de permettre aux développeurs de se connecter au processus de compilation pour pouvoir modifier l'AST avant qu'il ne soit transformé en bytecode qui sera exécuté par la JVM. Les transformations AST fournissent à Groovy des capacités de métaprogrammation améliorées au moment de la compilation permettant une grande flexibilité au niveau de la langue, sans pénaliser les performances d'exécution."

Voici des exemples d'AST dans Groovy :

  • Catégorie et transformation Mixin
  • Macro AST immuable
  • Nouvelle transformation
  • Transformation singleton

entre autres.

Traits

Selon la documentation de Groovy, « Les traits sont une construction structurelle du langage qui permet : la composition de comportements, l'implémentation d'interfaces à l'exécution, le remplacement de comportement et la compatibilité avec la vérification/compilation de type statique.

Les traits peuvent être considérés comme des interfaces portant à la fois des implémentations par défaut et un état. Un trait est défini à l'aide du mot-clé trait :

trait FlyingAbility { /* declaration of a trait */
  String fly() { "I'm flying!" } /* declaration of a method inside a trait */
}

Ensuite, il peut être utilisé comme une interface normale en utilisant le mot-clé implements:

class Bird implements FlyingAbility {} /* Adds the trait FlyingAbility to the Bird class capabilities */
def bird = new Bird() /* instantiate a new Bird */
assert bird.fly() == "I'm flying!" /* the Bird class automatically gets the behavior of the FlyingAbility trait */

Les traits permettent un large éventail de capacités, de la simple composition aux tests.

Adoption

Voici des exemples notables d'adoption de Groovy :

  • Adaptavist ScriptRunner, intègre une implémentation Groovy pour automatiser et étendre les outils Atlassian , utilisé par plus de 20 000 organisations à travers le monde.
  • Apache OFBiz , le système de planification des ressources d'entreprise (ERP) open source , utilise Groovy.
  • Eucalyptus , un système de gestion du cloud, utilise une quantité importante de Groovy.
  • Gradle est un outil d'automatisation de construction populaire utilisant Groovy.
  • LinkedIn utilise Groovy et Grails pour certains de leurs sous-systèmes.
  • LogicMonitor, une plate-forme de surveillance basée sur le cloud, utilise Groovy dans des sources de données basées sur des scripts.
  • Jenkins , une plateforme d' intégration continue . Avec la version 2, Jenkins inclut un plugin Pipeline qui permet d'écrire des instructions de construction dans Groovy.
  • Liferay, utilise groovy dans son flux de travail Kaleo
  • Sky.com utilise Groovy et Grails pour diffuser un contenu multimédia en ligne massif.
  • SmartThings , une plate-forme ouverte pour les maisons intelligentes et l' Internet des objets grand public , utilise un sous-ensemble de Groovy axé sur la sécurité
  • SoapUI fournit Groovy comme langage pour le développement de tests de services Web.
  • Survata , une startup d'études de marché, utilise Groovy et Grails.
  • L'Office européen des brevets (OEB) a développé un langage de programmation de flux de données dans Groovy "pour tirer parti des similitudes dans les processus de communication avec l'office des brevets de chaque pays et les transformer en un processus unique et universel".
  • Bien que Groovy puisse être intégré dans n'importe quel environnement JVM, le framework JBoss Seam fournit Groovy, en plus de Java, en tant que langage de développement, prêt à l'emploi.
  • vCalc.com utilise Groovy pour toutes les mathématiques définies par l'utilisateur dans son moteur de crowdsourcing mathématique.
  • Wired.com utilise Groovy et Grails pour la section autonome Product Reviews du site Web.
  • XWiki SAS utilise Groovy comme langage de script dans son produit collaboratif open source.

Prise en charge de l'IDE

De nombreux environnements de développement intégrés (IDE) et éditeurs de texte prennent en charge Groovy :

Dialectes

Il existe une implémentation alternative de Groovy :

  • Grooscript convertit le code Groovy en code JavaScript . Bien que Grooscript présente certaines limitations par rapport à Apache Groovy, il peut utiliser des classes de domaine à la fois sur le serveur et le client. La prise en charge des plugins pour Grails version 3.0 est fournie, ainsi que les conversions de code en ligne.

Voir également

Les références

Citations

Sources

Liens externes