Apache Groovy - Apache Groovy

Groovy
Groovy-logo.svg
Logotipo Groovy
Paradigma Orientado a objetos , imperativo , script
Projetado por James Strachan
Desenvolvedor Guillaume Laforge (presidente do PMC)
Jochen Theodorou (líder de tecnologia)
Paul King
Cedric Champeau
Apareceu pela primeira vez 2003 ; 18 anos atras ( 2003 )
Versão estável 3.0.8 (16 de abril de 2021 ; 5 meses atrás ) [±] ( 2021-04-16 )
Versão de visualização
4.0.0-beta-1/6 de setembro de 2021 ; 34 dias atrás ( 2021-09-06 )
Disciplina de digitação Dinâmico , estático , forte , pato
Plataforma Java SE
Licença Licença Apache 2.0
Extensões de nome de arquivo .groovy, .gvy, .gy, .gsh
Local na rede Internet groovy-lang .org Edite isso no Wikidata
Implementações principais
Gradle , Grails
Influenciado por
Java , Python , Ruby , Smalltalk
Influenciado
Kotlin

Apache Groovy é uma linguagem de programação orientada a objetos compatível com a sintaxe Java para a plataforma Java . É uma linguagem estática e dinâmica com recursos semelhantes aos do Python , Ruby e Smalltalk . Ele pode ser usado como uma linguagem de programação e uma linguagem de script para a plataforma Java, é compilado para o bytecode da máquina virtual Java (JVM) e interopera perfeitamente com outros códigos e bibliotecas Java . O Groovy usa uma sintaxe de colchetes semelhante à do Java. Groovy oferece suporte a encerramentos , strings de várias linhas e expressões incorporadas em strings . Muito do poder do Groovy está em suas transformações AST , acionadas por meio de anotações.

O Groovy 1.0 foi lançado em 2 de janeiro de 2007 e o Groovy 2.0 em julho de 2012. Desde a versão 2, o Groovy pode ser compilado estaticamente , oferecendo inferência de tipo e desempenho próximo ao do Java. Groovy 2.4 foi o último grande lançamento sob o patrocínio da Pivotal Software , que terminou em março de 2015. Desde então, o Groovy mudou sua estrutura de governança para um Comitê de Gerenciamento de Projetos na Apache Software Foundation .

História

James Strachan falou pela primeira vez sobre o desenvolvimento do Groovy em seu blog em agosto de 2003. Em março de 2004, Groovy foi submetido ao JCP como JSR 241 e aceito por votação. Várias versões foram lançadas entre 2004 e 2006. Depois que o esforço de padronização do Java Community Process (JCP) começou, a numeração da versão mudou e uma versão chamada "1.0" foi lançada em 2 de janeiro de 2007. Após vários betas e candidatos a lançamento numerados 1.1, em 7 de dezembro de 2007, Groovy 1.1 Final foi lançado e imediatamente renumerado como Groovy 1.5 para refletir as muitas alterações feitas.

Em 2007, Groovy ganhou o primeiro prêmio no prêmio de inovação JAX 2007. Em 2008, Grails , uma estrutura da web Groovy , ganhou o segundo prêmio no prêmio de inovação JAX 2008.

Em novembro de 2008, a SpringSource adquiriu a empresa Groovy and Grails (G2One). Em agosto de 2009, a VMware adquiriu a SpringSource.

Em abril de 2012, após oito anos de inatividade, o Spec Lead alterou o status do JSR 241 para inativo.

Strachan deixou o projeto silenciosamente um ano antes do lançamento do Groovy 1.0 em 2007. Em outubro de 2016, Strachan declarou "Eu ainda amo o groovy (os pipelines jenkins são tão legais!), Java, go, typescript e kotlin".

Em 2 de julho de 2012, Groovy 2.0 foi lançado, o qual, entre outros novos recursos, adicionou compilação estática e verificação de tipo estática .

Quando a joint venture Pivotal Software foi desmembrada pela EMC Corporation (EMC) e VMware em abril de 2013, Groovy e Grails formavam parte de seu portfólio de produtos. A Pivotal deixou de patrocinar Groovy e Grails em abril de 2015. Nesse mesmo mês, Groovy mudou sua estrutura de governança de um repositório Codehaus para um Comitê de Gerenciamento de Projetos (PMC) na Apache Software Foundation por meio de sua incubadora. Groovy se formou na incubadora da Apache e se tornou um projeto de nível superior em novembro de 2015.

Recursos

A maioria dos arquivos Java válidos também são arquivos Groovy válidos. Embora as duas linguagens sejam semelhantes, o código Groovy pode ser mais compacto, porque não precisa de todos os elementos de que o Java precisa. Isso possibilita que os programadores Java aprendam Groovy gradualmente, começando com a sintaxe Java familiar antes de adquirir mais idiomas de programação Groovy .

Os recursos do Groovy não disponíveis em Java incluem tipagem estática e dinâmica (com a palavra-chave def), sobrecarga de operador , sintaxe nativa para listas e matrizes associativas (mapas), suporte nativo para expressões regulares , iteração polimórfica, interpolação de string , métodos auxiliares adicionados e o operador de navegação segura ?. para verificar automaticamente se há ponteiros nulos (por exemplo ,,variable?.method() ou variable?.field).

Desde a versão 2, o Groovy também suporta modularidade (sendo capaz de enviar apenas os jars necessários de acordo com as necessidades do projeto, reduzindo assim o tamanho da biblioteca do Groovy), verificação de tipo, compilação estática, aprimoramentos de sintaxe da moeda do projeto, blocos multicatch e aprimoramentos contínuos de desempenho usando o invokedynamicinstrução introduzida em Java 7 .

O Groovy fornece suporte nativo para várias linguagens de marcação , como XML e HTML , realizado por meio de uma sintaxe de Document Object Model (DOM) embutida . Esse recurso permite a definição e manipulação de muitos tipos de ativos de dados heterogêneos com uma sintaxe uniforme e concisa e metodologia de programação.

Ao contrário do Java, um arquivo de código-fonte do Groovy pode ser executado como um script (não compilado) , se contiver código fora de qualquer definição de classe, se for uma classe com um método principal ou se for um Runnable ou GroovyTestCase . Um script Groovy é totalmente analisado, compilado e gerado antes de ser executado (semelhante a Python e Ruby). Isso ocorre nos bastidores e a versão compilada não é salva como um artefato do processo.

GroovyBeans, propriedades

GroovyBeans é a versão do Groovy de JavaBeans . O Groovy gera implicitamente getters e setters. No código a seguir, setColor(String color)e getColor()são gerados implicitamente. As duas últimas linhas, que parecem acessar as cores diretamente, estão na verdade chamando os métodos gerados implicitamente.

class AGroovyBean {
  String color
}

def myGroovyBean = new AGroovyBean()

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

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

O Groovy oferece uma sintaxe simples e consistente para lidar com listas e mapas , uma reminiscência da sintaxe de array do 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

Extensão de protótipo

Groovy oferece suporte para extensão de protótipo por meio de ExpandoMetaClassMódulos de Extensão (somente no Groovy 2), Categorias Objective-C-like e DelegatingMetaClass.

ExpandoMetaClassoferece uma linguagem específica de domínio (DSL) para expressar as mudanças na classe facilmente, semelhante ao conceito de classe aberta de Ruby :

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

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

As alterações do Groovy no código por meio da prototipagem não são visíveis em Java, uma vez que cada invocação de atributo / método no Groovy passa pelo registro da metaclasse. O código alterado só pode ser acessado do Java indo para o registro da metaclasse.

O Groovy também permite sobrescrever métodos como getProperty(), propertyMissing()entre outros, habilitar o desenvolvedor a interceptar chamadas a um objeto e especificar uma ação para elas, de maneira simplificada e orientada a aspectos . O código a seguir permite que a classe java.lang.Stringresponda à hexpropriedade:

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

O framework Grails usa metaprogramação extensivamente para habilitar localizadores dinâmicos GORM , como User.findByName('Josh')e outros.

Ponto e parênteses

A sintaxe do Groovy permite omitir parênteses e pontos em algumas situações. O seguinte código bacana

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

pode ser escrito como

take coffee with sugar, milk and liquor

permitindo o desenvolvimento de linguagens específicas de domínio (DSLs) que se parecem com o inglês simples.

Programação funcional

Embora Groovy seja principalmente uma linguagem orientada a objetos, também oferece recursos de programação funcionais.

Fechamentos

De acordo com a documentação do Groovy: "Fechamentos no Groovy funcionam de forma semelhante a um 'ponteiro de método', permitindo que o código seja escrito e executado posteriormente". Os fechamentos do Groovy suportam variáveis ​​livres, isto é, variáveis ​​que não foram explicitamente passadas como um parâmetro para ele, mas existem em seu contexto de declaração, aplicação parcial (que denomina ' currying '), delegação, parâmetros implícitos, digitados e não digitados.

Ao trabalhar em coleções de um determinado tipo, o fechamento passado para uma operação na coleção pode ser inferido:

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]

Um grupo de expressões pode ser escrito em um bloco de fechamento sem referência a uma implementação e o objeto de resposta pode ser atribuído em um ponto posterior usando a delegação:

// 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

Normalmente chamado de aplicativo parcial , esse recurso do Groovy permite que os parâmetros de fechamento sejam configurados como um parâmetro padrão em qualquer um de seus argumentos, criando um novo fechamento com o valor vinculado. Fornecer um argumento ao curry()método corrigirá o argumento um. Fornecer N argumentos corrigirá os argumentos 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'

Curry também pode ser usado na direção inversa (corrigindo os últimos N argumentos) usando 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 também suporta avaliação preguiçosa , redução / dobra , estruturas infinitas e imutabilidade , entre outros.

Processamento JSON e XML

Em JavaScript Object Notation ( JSON ) e processamento XML, Groovy emprega o padrão Builder , tornando a produção da estrutura de dados menos prolixa. Por exemplo, o seguinte XML:

<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>

pode ser gerado por meio do seguinte código Groovy:

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"
  }
}

e também pode ser processado de forma contínua StreamingMarkupBuilder. Para alterar a implementação para JSON, o MarkupBuilderpode ser trocado para JsonBuilder.

Para analisá-lo e procurar uma linguagem funcional, o findAllmétodo do Groovy pode 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"]

Interpolação de string

No Groovy, as strings podem ser interpoladas com variáveis ​​e expressões usando 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"

GStrings contendo variáveis ​​e expressões devem ser declaradas usando aspas duplas.

Uma expressão complexa deve ser colocada entre colchetes. Isso evita que partes dela sejam interpretadas como pertencentes à string ao redor em vez de à expressão:

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"

A avaliação da expressão pode ser adiada empregando a sintaxe de seta:

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"

Transformação da árvore de sintaxe abstrata

De acordo com a própria documentação do Groovy, "Quando o compilador Groovy compila scripts e classes Groovy, em algum ponto do processo, o código-fonte vai acabar sendo representado na memória na forma de uma Árvore Sintaxe Concreta, então transformado em uma Árvore Sintaxe Abstrata . O objetivo das Transformações AST é permitir que os desenvolvedores se conectem ao processo de compilação para poder modificar o AST antes que ele seja transformado em bytecode que será executado pela JVM. As Transformações AST fornecem ao Groovy recursos aprimorados de metaprogramação em tempo de compilação, permitindo uma flexibilidade poderosa no nível do idioma, sem uma penalidade no desempenho do tempo de execução. "

Exemplos de ASTs no Groovy são:

  • Transformação de categoria e mixin
  • Macro AST imutável
  • Transformação Newify
  • Transformação Singleton

entre outros.

Características

De acordo com a documentação do Groovy, " Traits são uma construção estrutural da linguagem que permite: composição de comportamentos, implementação de interfaces em tempo de execução, substituição de comportamento e compatibilidade com verificação / compilação de tipo estático."

As características podem ser vistas como interfaces que transportam implementações e estados padrão. Um traço é definido usando a palavra-chave trait:

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

Então, ele pode ser usado como uma interface normal usando a palavra implements- chave :

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 */

As características permitem uma ampla gama de habilidades, desde composição simples até testes.

Adoção

Exemplos notáveis ​​de adoção do Groovy incluem:

  • Adaptavist ScriptRunner, incorpora uma implementação Groovy para automatizar e estender as ferramentas Atlassian , em uso por mais de 20.000 organizações em todo o mundo.
  • Apache OFBiz , o sistema de planejamento de recursos empresariais (ERP) de código aberto , usa Groovy.
  • Eucalyptus , um sistema de gerenciamento de nuvem, usa uma quantidade significativa de Groovy.
  • Gradle é uma ferramenta de automação de compilação popular que usa o Groovy.
  • O LinkedIn usa Groovy e Grails para alguns de seus subsistemas.
  • LogicMonitor, uma plataforma de monitoramento baseada em nuvem, usa Groovy em fontes de dados baseadas em script.
  • Jenkins , uma plataforma de integração contínua . Com a versão 2, o Jenkins inclui um plug-in Pipeline que permite que as instruções de construção sejam escritas em Groovy.
  • Liferay, usa groovy em seu fluxo de trabalho Kaleo
  • Sky.com usa Groovy e Grails para fornecer conteúdo massivo de mídia online.
  • SmartThings , uma plataforma aberta para casas inteligentes e a Internet das Coisas para o consumidor , usa um subconjunto orientado para segurança do Groovy
  • SoapUI fornece Groovy como uma linguagem para desenvolvimento de testes de serviço da web.
  • Survata , uma startup de pesquisa de mercado, usa Groovy e Grails.
  • O European Patent Office (EPO) desenvolveu uma linguagem de programação de fluxo de dados em Groovy "para alavancar semelhanças nos processos de comunicação com o escritório de patentes de cada país e transformá-los em um único processo universal."
  • Embora Groovy possa ser integrado a qualquer ambiente JVM, a estrutura JBoss Seam fornece Groovy, além de Java, como uma linguagem de desenvolvimento pronta para uso.
  • O vCalc.com usa o Groovy para toda a matemática definida pelo usuário em seu mecanismo de crowdsourcing de matemática.
  • Wired.com usa Groovy e Grails para a seção independente de Avaliações de produtos do site.
  • O XWiki SAS usa Groovy como linguagem de script em seu produto colaborativo de código aberto.

Suporte IDE

Muitos ambientes de desenvolvimento integrado (IDEs) e editores de texto suportam Groovy:

Dialetos

Existe uma implementação alternativa do Groovy:

  • O Grooscript converte o código Groovy em código JavaScript . Embora o Grooscript tenha algumas limitações em comparação com o Apache Groovy, ele pode usar classes de domínio no servidor e no cliente. É fornecido suporte de plug-in para Grails versão 3.0, bem como conversões de código online.

Veja também

Referências

Citações

Fontes

links externos