Você está na página 1de 71

Groovy & Grails

Desenvolvimento gil para plataforma Java

Lus Bruno P. Nascimento


luisbrunu@gmail.com

Enucomp 2010

Groovy e Grails Parte I

Introduo ao Groovy

O Projeto Groovy

Tudo comeou em 29 de Agosto de 2003, com uma publicao no blog de James Strachan, o primeiro artigo sobre o que seria o groovy.

O Projeto Groovy
Segundo James:
Minha idia inicial fazer uma pequena linguagem dinmica, que seja compilada diretamente em classes Java e que tenha toda a produtividade e elegante encontrada em Ruby e Python

O Projeto Groovy
James uniu-se com Bob McWhirter, e juntos, em 2003 fundaram oficialmente o projeto Groovy. Em 2004, fundao do GroovyOne;

Mais desenvolvedores se uniram ao projeto


Entre eles Guillaume Laforge, hoje o gerente oficial do projeto Groovy e lder do Expert Group que padroniza Groovy.

Groovy Hoje

Linguagem com asceno mais rpida no indice do Tiobe Index; Do limbo para o 38 lugar entre 200 linguagens em 2 anos e meio de vida;

Hoje ocupa a 44 posio; http://www.tiobe.com/index.php/content/ paperinfo/tpci/index.html 1 lugar entre as linguagens da JVM.

Alternativas ao Groovy

Existem cerca de 240 linguagens compatveis JVM; Funcionam junto ao cdigo Java ou so compiladas para formar bytecodes; Mais sobre o assunto:
http://www.is-research.de/info/vmlanguages

Alternativas ao Groovy

Groovy ou JRuby

Sintax do Groovy bem similar Java; Possui todas as vantagens do Ruby; Interpolaridade entre Groovy e Java;

Arquivos .groovy compilados tornam-se .class; Se trocar a extenso .java para .groovy funciona exatamente como o tal;

Tratamento com a JVM

file.java

file.groovy

bytecode

bytecode

Mquina Virtual Java

Introduo ao Groovy

Linguagem gil e dinmica para java; Muitos recursos foram inspirados em linguagens como Ruby, Python e Smalltalk; Sintaxe simples, enxuta e similar linguagem Java; Interpretada ou Compilada para bytecode; Linguagem de Scripts; Open Source;

Introduo ao Groovy

Totalmente OO;

No h tipos primitivos; TUDO objetos;


O nmero 1 um objeto; 1.class >> java.lang.Integer;

Meta-Programao;

Adicionar funcionalidades em tempo de execuo.

Criar um novo comportamento para classe String.

Instalao

Pr-requisitos:

JDK - http://java.sun.com/javase/downloads GDK - http://groovy.codehaus.org/Download Descompactar os binrios do Groovy - Qualquer diretrio; Variveis de Ambiente

1 Passo: Download do Groovy:


2 Passo: Definir as variveis de ambiente e o PATH:

GROOVY_HOME GROOVY_HOME/bin

Definir o PATH:

Instalao no Windows

Definir variveis de ambiente:

V em Painel de Controle >> Propriedades do Sistema >> V na aba Avanado, e clique no boto Variveis de Ambiente.

Em Variveis de usurio, crie uma nova com:


Varivel: GROOVY_HOME Valor: C:\groovy-1.3.4 Adicione no final ;C:\groovy-1.3.4\bin

Em Variveis do sistema, edite a varivel PATH:

Instalao no Windows

Instalao no Linux

Usando um editor de texto, abra o arquivo /etc/environment, e adicione os segintes valores:


JAVA_HOME = "/usr/lib/jvm/java-6-sun" GROOVY_HOME = "/opt/groovy-1.7.5" /usr/lib/jvm/java-6-sun/bin /opt/groovy-1.7.5/bin

Adicione ao fim da linha PATH:


Groovy - Caractersticas

Alguns Importes j implcitos;


java.io.* java.lang.* java.math.BigDecimal java.math.BigInteger java.net.* java.util.* groovy.lang.* groovy.util.*

Groovy - Caractersticas

Ponto e vrgula e comando return so opcionais; Mtodos e Classes so public por default, por isso tambm opcional o uso dos modificadores; Pode ser omitido o tipo das variveis, atributos, assim como o tipo de retorno dos mtodos. Parnteses opcionais em chamadas de mtodos com um parmetro.
print "hello" 5.plus 5 //==>hello //==>10

'Bruno'.concat ' Nascimento' //==> Bruno Nascimento

Ferramentas Groovy
>>groovysh

Groovy shell; Executa um cdigo iterativamente.

Groovy Shell
------------------------------------------------------------------

groovy:000> print 'Ol, eu sou Groovy! hello, world===> null groovy:000> System.out.println("Ol, sou do Java!"); hello, world===> null

Ferramentas Groovy
>>groovyConsole

Console com interface grfica escrito em Groovy pra executar cdigos instantaneamente.

Classes, instancias, methodos soltos, cdigos em java...

Ferramentas Groovy
>>groovy

Usado para executar programas e scripts em Groovy; Roda programas em Groovy na forma de arquivos, passando o nome do arquivo.

//programa.groovy println "Hello, Bruno!"


groovy:000>groovy programa.groovy groovy:000>Hello, Bruno!

Ferramentas Groovy
Suporte s IDEs

Netbeans Groovy e Grails nativo; Eclipse plug-in

Eclipse + Groovy

V no site:

http://groovy.codehaus.org/Eclipse+Plugin

Escolha a sua verso do eclipse e pegue a url correspondente; Adicione em Help >> Install New Software Colar a url e fazer o download

Operadores

Aritmticos: +, -, *, /, %, **, ... etc Comparao: >, <, >=,==, !=,<=> etc Atribuio: =, +=, +=, <<, <<=, ... etc. Lgicos: &&, ||, ! etc Ternrio: a == 2 ? Dois : Outro Elvis Operator: ?: Safe Navigation Operator: ?.

Operadores

(<=>)

Operador de comparao que retorna -1, 0 ou 1 se for menor, igual ou maior que seu argumento.
String a; a?:"A varivel a nula" //em Groovy String a; //em Java a != null ? a : "A varivel a nula";

(?:) - Elvis Operator

Se a varivel no for nula, retorna ela mesma, seno, retorna a String.

Operadores

(?.) - Safe Navigation Operator

Acessa um mtodo ou propriedade se o objeto no for nulo.


obj?.facaAlgo() //em Groovy //em Java if(obj != null){ obj.facaAlgo(); }

Variveis

So objetos das classes das quais foram tipadas;

Podem ser tipadas dinamicamente atravs da palavra def;


String str = 'String tipada' def s = 'String dinmica'

Atribuio Mltipla:
def (a,b,c) = [2, 4, 6] print a //===> 2

Nmeros

Em Groovy, os nmeros so tipados atravs do seu tamanho:


1.class 1.class.superclass 1000000000.class (100**100).class

//java.lang.Integer //java.lang.Number //java.lang.Long //java.math.BigInteger

Groovy suporta nmeros de tamanhos imensos. Os nmeros da classe BigInteger se restringem apenas memria e ao processador da mquina.

Nmeros

Alguns mtodos da classe Number:

times(Closure closure)
5.times {print 'k'} //kkkkk

upto(Number to, Closure closure)


1.upto 5, {print it } //12345

step(Number to, Number stepNumber, Closure c)


0.step( 10, 2 ) {print it} //2,4,6,8,10

Strings

String um conjunto de caracteres. Strings Groovy so completamente MUTVEIS. Pode ser delimitado por aspas 'simples' ou
"duplas" Pode ocupar uma ou vrias linhas. Pode ser injetada a ela operaes, variveis... Mtodos destrutivos e no destrutivos

Strings

Strings
'String de aspas simples' "Ol, sou uma 'String'!"

GStrings Groovy Strings

Strings interpoladas. Permitem adicionar pedaos de cdigo dentro delas.


"1 + 1 = ${1+1}" // 1 + 1 = 2

Strings com mltiplas linhas.


"""String de Multiplas linhas"""

Strings

Strings como Arrays s = 'Bem vindos ao Enucomp' s.getAt(1) /* e */ s[1] /* e */ s[0,20] /* Bp */ s[4..9] /* vindos */

Strings

Brincando com os Operadores


s = 'Bem vindos ao Enucomp' s + ' com Groovy' Groovy*/ /*Bem vindos ao Enucomp com /*Bem vindos ao Groovy*/

s - 'Enucomp' + 'Groovy' s = 'k' s * 3

/* kkk */

Obs.: Os operadores so mtodos nodestrutivos.

Strings

Outros mtodos interessantes:


s = 'hello, Groovy' s.capitalize() s.center(15) s.padLeft(16, '-') s.padRight(16, '-') s.reverse() /*Hello, Groovy*/ /* hello, Groovy */ /*---hello, Groovy*/ /*hello, Groovy---*/ /*yvoorG ,olleh*/

....

Strings

Interpolao de valores em Strings;

Possvel apenas em Strings com aspas duplas.


def nome = 'Joo' //===>Joo print "Ol, ${nome}, bem vindo ao curso!" //===>Ol, Joo, bem vindo ao curso!'

Colees

List Coleo de objetos;


def numeros = [1, 2, 3.5] def string = ["1", '2', "3"] def tudo = [10, "50", """Hello"""] def list = [numeros, string, tudo] list.each{println it} [1, 2, 3.5] [1, 2, 3] [1, 2, 3]

Colees

List - Alguns mtodos teis:


def list = [1,2,3,9,5] list.each {print it } //123495 list.reverse() //[5,9,3,2,1] list.putAt(3,4) //[1,2,3,4,5] list << 6 //[1,2,3,9,5,6] list.pop() //[1,2,3,9,5] list + 10 list - 9 //1,2,3,4,9,5,10 //1,2,3,4,5

Colees

Range

Representa um intervalo de valores;


def range = (1..4) range.each {print "$it "} //1 2 3 4===> 1..4 ('a'..'c').each {print "$it "} //a b c ===> a..c for (i in 1..10) {println i}

Colees

Map

O mesmo que array associativo, dicionrios ou hashes; Cada entrada composta por uma chave e um valor;

def frameworks = [groovy: "Grails", ruby: "Rails"] def map = [a:(1..4), 10:"Dez"] print framework.groovy //===>Grails print map.a //===>1..4 print map[10] //===>Dez

Receber do teclado

Para brincar recebendo valores do usurio em Groovy, use isso:


System.in.withReader { print "Digite algo: " valor = it.readLine() println "Voc me disse: ${valor.toUpperCase()}" }

Praticando...
1. Imprimir uma String na vertical; 2. Imprimir uma String em formato de escada; 3. Receber uma linguagem, retorna uma framework; 4. Dado um determinado vetor, faa:

Some todos os elementos; Mostre o maior e o meno elemento; Mostre os elementos invertidos; Ordene todos os elementos;

Estruturas de Controle

O que verdadeiro em Groovy?


Objetos no-nulos; Nmeros diferentes de 0; Strings, GStrings, colees no-vazias;


assert assert assert assert assert

!''; !0; ![]; !false; !null;

assert 'Ol' assert 50 assert [2,'a'] assert true assert new Object()

Mtodo assert um mtodo para testes unitrios. Se retornar algo false, gera uma exceo.

Estruturas de Controle

Estruturas de deciso:

If else
If(10 > 5){ print 'Groovy' } else{ print 'Java' }

Operador condicional - ?:
def retorno = (1==1) ? "Iguais" : "Diferentes"

Estruturas de Controle

Switch
switch(ling) { case 'Ruby' case 'Groovy' case 'PHP' default } : : : : println println println println 'Rails' 'Grails' 'Cake' 'Outra' ;break ;break ;break ;break

if(ling.isCase('Ruby')) println 'Rails' else if (ling.isCase('Groovy')) println 'Grails' else if (ling.isCase('PHP')) println'Cake' else 'Outra' //Rails //Rails

Estruturas de Controle

Switch

Em Groovy, o switch suporta vrios tipos, e no s chars.


switch (10) { case 0 : assert case 0..9 : assert case [8,9,11] : assert case Float : assert case {it%3 == 0} : assert case ~/../ : assert default : assert } false false false false false true false ;break ;break ;break ;break ;break ;break ;break

Estruturas de Controle

while
def list = [1,2,3] while (list) { list.remove(0) } assert list == [] while (list.size() < 3) list << list.size()+1 assert list == [1,2,3]

Estruturas de Controle

for
for (variable in iterable) { body } def store = '' for (String i in 'a'..'c') assert store == 'abc' def j = 0 for (i in 0..10) { j += i } print j //55

store += i

Excees

O tratamento de excees igual ao do Java. A nica diferena em termos de exceo que no Groovy opcional colocar o throws na assinatura do mtodo, tanto para excees checadas quanto em no-checadas;

Com isso, podemos escolher como e quando tratar essas excees.

Excees
def myMethod() { 'string'.toLong() } def log = [] try { myMethod() } catch (Exception e) { log << e.toString() } finally { log << 'finally' } log.each{println it}

Mtodos

Em Groovy, todo mtodo retorna alguma coisa. Quando nenhum valor explicitamente mostrado, ele retorna null. O return opcional
def hello(nome){ println 'Hello, meu nome : ${nome}' } hello('Bruno') ou hello 'Bruno'

//Hello, meu nome : Bruno //Hello, meu nome : Bruno

Mtodos

Podemos declarar mtodos com parmetros com valores default


def soma(a,b = 2){ println a + b } soma 2 //4 soma 2,3 //5

Mtodos com parmetros opcionais


int sum(a, Object[] optionals){ for(o in optionals) a+=o a } sum(1) //1 sum(20, 1, 10, 4) //35

Closures

Um bloco de cdigo reutilizvel delimitado por chaves.


Semelhante a uma classe interna; Podem ser declarados no s dentro das classes No executado quando definido, apenas quando for chamado; Apenas agem como mtodos, mas so objetos normais(groovy.lang.Closure). Para entender melhor esse recurso, acesse: http://groovy.codehaus.org/Closures+-+Formal+Definition

Closures

Pode conter parmetros; Modifica variveis declaradas fora da closure; Invocados pelo mtodo

call(); doCall(); ou simplesmente pela seu nome;

Se tiver apenas um parmetro, no necessrio defini-lo, basta usar a palavra reservada it para referenci-lo.

Closures
Closure cloj1 = {println 'Hello, World!'} // Sem parmetro def cloj2 = { obj -> println "Hello, $obj!"} // Parmetro sem tipo definido def cloj3 = {println "Hello, $it!"} // Parmetro acessado pela palavra-chave 'it' cloj2.call('Groovy') cloj3.doCall('Groovy') cloj3('Groovy') //===> Hello, Groovy //===> Hello, Groovy //===> Hello, Groovy

Closures

Outros exemplos:
def soma = { a, b -> print "A soma : ${a+b}" } map = ['a':1, 'b':2] map.each{ key, value -> map[key] = value * 2 } print map //[a:2, b:4]
letras = 'a'..'z' letrasUpper=[] letras.collect (letrasUpper){it * 2 } println letras println letrasUpper

//[a, b, c, d, ...] //[aa, bb, cc, ...]

Praticando...

Fazer um programinha que receba um nmero, imprima-o o nmero de vezes que o representa de 0 at ele mesmo.
Entrada: 6 Sada: 1 2 2 3 3 4 4 5 5 6 6

3 4 4 5 5 5 6 6 6 6

Orientao Objetos

Classes e Objetos

Classes uma estrutura que abstrai coisas do mundo real para o mundo computacional; Define o tipo dos objetos;

Se classes fossem formas de bolo, os objetos seriam os bolos; Objetos so instancias das classes; Os dados so os atributos; Comportamentos so os mtodos;

Objetos possuem dados em comportamentos;


1, 50, 999 so instancias da classe Integer;

Orientao Objetos

Classes e Objetos

Oi, 'Groovy', '8' so instancias da classe String; Instanciando uma classe:


p = new Pessoa()

Para os tipos bsicos basta fazer isso:


s = "String" i = 50 array = [10,20,60]

Ou do modo brutal...
i = new Integer(25) s = new String('Sou uma String')

Orientao Objetos

Herana:

Classes tem a capacidade de herdar comportamento de outras classes; As classes que provm os comportamentos herdados so chamadas de super-classes;
1.class 1.class.superclass //java.lang.Integer //java.lang.Number

Para herdar de outras classes usa-se o extends


class Integer extends Number { ... }

Meta-Programao

MOP Meta-Object Protocol Mgica da programao; Adicionar comportamento s classes em tempo de execuo;

Adicionar mtodos s classes; Adicionar propriedades;

Todas as classes escritas em Groovy herdam de Object e implementam a interface GroovyObject;

Meta-Programao

Meta Classes

As classes definem o comportamento dos objetos; As meta classes definem o comportamento de certas classes ou de suas instancias;

De certa forma at as classes so objetos...

public interface GroovyObject { Object invokeMethod(String name, Object args); Object getProperty(String property); void setProperty(String property, Object newValue); MetaClass getMetaClass(); void setMetaClass(MetaClass metaClass); }

Meta-Programao

Adicionando um mtodo classe String


String.metaClass.digaOla = { lang -> if(lang == 'English') println 'Hello' else if(lang == 'Swedish') println 'Hej' } 'Chamando o diga Ol por uma String'.digaOla('Swedish') class Pessoa{ String nome, sobrenome } Pessoa.metaClass.getNomeCompleto = { nome + ", " + sobrebome } println new Pessoa(nome:'groovy', sobrenome : 'Grails').getNomeCompleto()

Java Bean
public class HelloWorld { private String nome; public void setNome(String nome) { this.nome = nome; } public String digaHello(){ return "Hello " + nome + "."; } public static void main(String[] args) { HelloWorld hw = new HelloWorld(); hw.setNome("Bruno"); System.out.println(hw.digaHello()); } }

Em Groovy
public class HelloWorld { private String nome; public void setNome(String nome) { this.nome = nome; } public String digaHello(){ return "Hello " + nome + "."; } public static void main(String[] args) { HelloWorld hw = new HelloWorld(); hw.setNome("Bruno"); System.out.println(hw.digaHello()); } }

Groovy Bean

Por defaulf as classes so public; Mtodos modificadores dos atributos so gerados dinamicamente; No necessrio criar um mtodo construtor:
p = new Pessoa(nome:'Bruno')

Groovy Bean
class HelloWorld { String nome String digaHello(){ "Hello, ${nome}." }

Getters e Setters gerados automaticamente Strings Groovy (GString)

static void main(args) { def hw = new HelloWorld(nome:"Groovy") print hw.digaHello() }

Parmetro do construtor

Groovy Bean
class HelloWorld { def nome def digaHello(){ "Hello, $nome" } } print new HelloWorld(nome:"Groovy").digaHello()

Duky Typing Tipagem dinmica

Script Groovy solto/livre

Totalmente em Groovy
Closure com parmetro
class HelloWorld { def digaHello = {nome-> "Hello ${nome}"} } print new HelloWorld().digaHello.call("Bruno")

Chamada da Closure Em todos esses exemplos tm o mesmo resultado: >>Hello, Bruno

Java vs Groovy
public class HelloWorld { private String nome; public void setNome(String nome) { this.nome = nome; } public String digaHello(){ return "Hello " + nome + "."; } public static void main(String[] args) { HelloWorld hw = new HelloWorld(); hw.setNome("Bruno"); System.out.println(hw.digaHello()); }

Em java: 18 linhas

Em Groovy: 4 linhas

class HelloWorld { def digaHello = {nome-> "Hello ${nome}"} } print new HelloWorld().digaHello.call("Bruno")

Referncias

Groovy in Action; Introduction to Groovy and Grails

Mohamed Seifeddine http://groovy.codehaus.org/Getting+Started+Guide Fernando Anselmo Oficial docs http://www.itexto.net/devkico/?p=231

Getting Started Guide

Em Busca do Grails

Groovy Documentation

Bsico do Groovy para quem for aprender Grails

Referncias

Um pouco de Groovy

Artigo Dev-Media Java Magazine - Marcelo Castellani Regis Pires Magalhes

Slide curso_ruby do ENUCOMP 2008