Conheça Groovy e o lado Lean do Java

Salve Devs!

Hoje descobriremos como deixar nossa programação Java um pouco mais Lean (Enxuta).

lean

Você é daqueles que gosta de Java mesmo com toda a sua verbosidade ou daqueles que não gosta de Java graças a sua verbosidade? Resumindo … Você acha o Java verboso?

Se você respondeu SIM para alguma dessas questões, essa postagem foi feita para você!

A um tempo atrás montei uma apresentação falando um pouco sobre como Groovy tem trazido uma nova ropagem para a familia de frameworks que funcionam na JVM.

Conheça tecnologias como:

  • Grails
  • RatPack
  • Glide
  • Spock
  • GEB

Aproveita que é uma apresentação de leitura rápida, que foca no código e está cheio de imagens!

Link da apresentaçãohttp://slides.com/jonatasemidio/deck#/

leanjavaweb

Se você conhece mais alguma tecnologia com essa característica LEAN para a JVM deixe um comentário.

Até a próxima!

Groovy e o seu selo de NERD!

Você já brincou de [Pedra, Papel e Tesoura]? …

db2e_lizard_spock

Se sua infância foi normal, provavelmente a resposta será sim… No entanto, se você já jogou a sua versão extendida [Pedra, Papel, Tesoura, LAGARTO e SPOCK] não sei se podemos dizer o mesmo!

Para quem não sabe, estamos falando da versão criada por Sam Kass, que ganhou popularidade quando foi apresentado no The Big Bang Theory.

Pois bem, não estamos aqui para falar de seriados e sim de programação, programação com Groovy!
Há um tempo atrás, participei de um dojo de programação onde o problema a ser resolvido foi exatamente esse… Pouco tempo depois, só por curiosidade fui ver como Groovy poderia facilitar ou complicar na resolução deste problema.

Em um primeiro momento decidi programar normalmente (de uma maneira que um ser humano possa ler >> ler código)

def play(play1, play2){
    warning = {i, n -> (i + n) % 5}
    position = plays.indexOf(play1)
    play1 == play2 ? 'draw' : play2 in [plays[warning(position, 1)] , plays[warning(position, 3)]] ? 'play1' : 'play2'
}

Mas não demorou muito tempo para eu tentar incurtar isso, já que o objetivo também era ver maneiras diferentes de resolver o mesmo problema e o resultado foi segundo script:

Como podemos ver abaixo, usando os recursos nerds do Groovy, o mesmo algorítimo está com apenas 88 caracteres! Se é que podemos chamar isso de algorítimo!
p={p1,p2,c={a,b->l[(l.indexOf(a)+b)%5]}->p1==p2?'eq':p2 in [c(p1, 1),c(p1,3)]?'p1':'p2'}
Segue gist completo dos exemplos com seus respectivos testes:

OK OK!! Não é bonito, mas de vez em quando é legal dar uma descontraida!

Se ficou alguma dúvida ou se você sabe como deixar o código menor ainda, é só deixar um comentário.

Etiquetado

Descubra os novos métodos do Groovy para ordenação e remoção de duplicações

Professortocat_v2

No Groovy, nós podemos usar os métodos sort() e unique() para ordenar ou remover duplicações de nossas coleções. Esses métodos alteram a estrutura das próprias coleções utilizadas. Porém esses são os efeitos colaterais que queremos evitar. No entanto, os métodos sort e unique foram alterados para receber um parâmetro boleano para indicar se a coleção deve ser alterada ou se nós teremos uma nova coleção como resultado, deixando a coleção atual em seu estado original.

Desde a versão 2.4 do Groovy nós temos dois novos métodos que retornam por default uma nova coleção: toSorted e toUnique.

No exemplo abaixo, podemos ver esses métodos em ação:

Curiosidades:

Acabamos de ver a lista de usuários sendo criada com o asImmutable(), que transforma o objeto em outro imutável, ou seja, se tentarmos executar apenas um sort() ou um unique() receberemos uma exceção de método não suportado. Pois, como descrito no início dos post, estes métodos por default alterão o estado do objetos e isso não é possível nos imutáveis.

Se em nossa aplicação temos estruturas que não são alteradas no decorrer de seu ciclo de vida, é aconcelhavel que utilizemos estas estruturas como imutáveis para melhoria de performace.

Considerações

Estamos falando de casos em que estamos lidando com listas externas, que por algum motivo de performace ou segurança não podem ser alteradas ou ja vir ordenadas.

Em situações onde a nossa estrutura de dados tenha que estar sempre ordenada e sem repetições, é aconcelhado já cria-la como TreeSet(). TreeSet: É uma coleção que além de não permitir repetição graças ao Set, ela indiretamente implementa o SortedSet, ou seja, manterá a classe sempre ordenada.

Gostaria de agradecer mais uma vez ao Dev Hubert Klein Ikkink que tem contribuído bastante com a comunidade groovy com seus exemplos no Groovy Goodness.

Fonte original

Grep e a ciência por detrás do switch do Groovy

Salve Devs!

Esse post é uma continuação do SE AVENTURANDO NO SWITCH DO GROOVY que fala sobre os melhoramentos que o switch passou a ter no Groovy.

Conheça o grep! A inteligência por detrás do switch

heisencat

O grep é mais um dos métodos que são definidos no DefaultGroovyMethods.java. Onde este será inserido em tempo de execução em todas as Collections instanciadas do projeto em questão.

 

Indo um pouco mais fundo:

Este método utiliza o DefaultGroovyMethodsSupport.createSimilarCollection() para retornar a Collection mais especifica relacionada com o parâmetro de entrada (Ex: ArrayList ou LinkedList) e o BooleanReturningMethodInvoker.invoke() para definir se o parametro possui os critérios necessários para fazer parte do retorno.

 

Segue um exemplo de como o grep trabalha:

Veja em execução no GroovyConsole.

Lembrando que conforme descrito na documentação, o grep específico para collection só está disponível a partir da versão 2.0 do Groovy. Antes disso temos o grep mais genérico voltado para Objects.

Gostaria de agradecer mais uma vez ao Dev Hubert Klein Ikkink que tem contribuído bastante com a comunidade groovy com seus exemplos no Groovy Goodness.

Fonte original

 

 

Se aventurando no Switch do Groovy

O switch no Java fica sem graça quando comparado com o do Groovy (mesmo quando falamos do switch do Java 7 que já aceita Strings em sua estrutura).

gitfinn

O switch do Groovy suporta diferentes classifiers, ao contrário do Java que apenas suporta String e int com seus derivados. Qualquer um que implemente o método isCase() (seu código fonte) pode ser usado como um classifier. Groovy adicionou o isCase() para as seguintes situações: Class (com o isInstance), Object (com o equals), collections (com o contains) e expressões regulares (com o matches). Se implementarmos o isCase() em nossa classe groovy ela também poderá ser usada como um classifier.

E Finalmente podemos usar uma closure como classifier, lembrando que ela será avaliada como boolean.
Segue exemplo no gist: switch.groovy

 

Veja o exemplo funcionando no Groovy Console: switch.groovy

Gostaria de agradecer o Dev Hubert Klein Ikkink que tem contribuído bastante com a comunidade groovy com seus exemplos no Groovy Goodness.

Fonte original

Etiquetado

O Jedi das Collections

Salve Devs!

octobiwan

Depois de quase 2 anos sem postar, tive que voltar depois de descobrir a existência do GroovyCollections disponível desde a versão 2.2 do groovy!

Ok! esse título ficou meio OVER, mas foi exatamente a impressão que tive assim que dei uma boa lida no código-fonte desse cara.

Além do código estar muito bem organizado e documentado, na própria descrição do método tem os exemplos de utilização. Que aqui entre nós … Nem todo mundo manja dos paranauês dos algorítimos e sabe de có o que é um transpose por exemplo.

Pois bem… Chega de blá blá blá e show me the code!
Vou destacar aqui os três métodos que mais me chamaram a atenção:

  • subsequence;
  • combitations;
  • transpose;
  1. Subsequence
    Como o nome já diz, esse cara é responsável por retornar todas as subsequencias não nulas de uma lista:
    Ex:

    subsequences([1, 2, 3]) => [[1, 2, 3], [1, 3], [2, 3], [1, 2], [1], [2], [3]]
  2. Combinations
    Já este é responsável por retornar todas as cominações de uma determinada coleção:
    Ex:

    combinations([[true, false], [true, false]]) => [[true, true], [false, true], [true, false], [false, false]]</pre>
    combinations([['a', 'b'],[1, 2, 3]]) => [['a', 1], ['b', 1], ['a', 2], ['b', 2], ['a', 3], ['b', 3]]

    Digo mais, se passarmos como parâmetro um item que não seja uma lista ele considera como uma lista de um item só:
    Ex:

    combinations([[1, 2], 'x']) => [[1, 'x'], [2, 'x']] 
  3. Transpose
    Por fim, o transpose é o que nos retorna a transposição de um array de list. “?”
    Segundo o Wikipedia: Em matemática, matriz transposta é a matriz que se obtém da troca de linhas por colunas de uma dada matriz. Desta forma, transpor uma matriz é a operação que leva na obtenção de sua transposta.
    Ex:

    transpose([['a', 'b'], [1, 2]]) => [['a', 1], ['b', 2]]</pre>
    transpose([['a', 'b', 'c']]) => [['a'], ['b'], ['c']]

 

Conforme visto acima, o código fonte desta classe está no repositório do groovy-core no github;

Se você não quiser, não precisa futucar o código fonte, pois temos sua API;

Caso você goste de mais detalhes a webingenia tem uma documentação bem detalhada com os exemplos e gráficos;

Pontos negativos
Com certeza devem ter mais, mas um ponto negativo assim como boa parte das classes em java rsrs é que alguns métodos já estão depreciados.

Fiquem livres para comentar, criticar e divulgar.
Espero que tenham gostado e até o próximo post!

Relato FSLDC 2013 + saiba como iniciar com Grails!!

Salve Groovy Coders,

No dia 20/07/2013 tive a oportunidade de palestrar no V Fórum de Software Livre de Duque de Caxias.

fsldc2013

O foco da minha apresentação era mostrar como é fácil aprender a usar o Grails. Para quem ainda não conhece, a apresentação utilizada está disponível online no Heroku e o seu código fonte está no meu github, lembrando que esta apresentação foi feita utilizando o Reveal.js dentro de uma aplicação Grails. Ou seja, até a apresentação foi feita com Grails.

Um dos itens mais interessantes deste dia foi que eu convidei uma das pessoas que estavam assistindo a palestra para criar um projeto do zero, isso no esquema Piloto e Copiloto (Lembrando que eu era apenas o copiloto). O Jogador do dia foi o Douglas Lemos. Que por sua vez criou um projeto do zero, ao vivo e sem IDE (Apenas o Terminal e o VIM) sem nunca ter nem ouvido falar de Grails antes da palestra. Às vezes eu acho que ele teve mais facilidade com o framework do que com o VIM.

Alguns dias depois, recebi alguns emails de pessoas que queria começar a estudar Grails, pedindo indicações de livros, apostilas e links. Logo tive a ideia de escrever esse post com a minha opinião sobre qual é o melhor caminho para começar neste novo mundo, pois intendo que esta dúvida pode ser a de outros Devs também.

Lembrando que essa é apenas uma opinião pessoal. Aqui tem o que eu considero importante por ter dado certo comigo.

 

grails

Como iniciar com Grails?

Primeiro e mandatório: Faça exemplos, escreva, erre, isso fará com que você evolua;

Livros:

Para aqueles que gostam de uma boa literatura, algo que te leve do básico ao avançado respeitando todo um fluxo natural da linguagem eu indico dois livros:

1 – Grails in Action: Para mim o official deste framework.

2 – Groovy in Action: Sobre a linguagem por de traz do Grails. Escrito pelo próprio criador da linguagem.

Sites:

1 – O próprio site da aplicação, já com uma série de tutoriais e exemplos.

2 – Grails.io, que é o blog oficial do criador do framework Graeme Rocher.

3 – Glaforge, que é o blog oficial do criador da linguagem por de traz do Grails, o Groovy.

4 – DevKiko, este é o site do Henrique Lobo, referência Grails no Brasil.

5 – SantoGrails o próprio. Que está descrito aqui não por ser melhor do que os demais e sim por ser escrito por um iniciante que sou eu. A idéia é descrever uma linha de raciocínio na linguagem dos iniciantes.

Tutoriais:

1 – O oficial.

2 – Instalando e configurando o Grails.

3 – Criando minha primeira aplicação Grails

4 – Boas Praticas com Grails. Este é muito importante, pois seguir as dicas descritas neste post evita uma série de erros que acabam com a vida de qualquer iniciante.

Comunidade:

Algo muito importante é ter acesso ou de preferência conhecer pessoas envolvidas com o framework e nada melhor do que as listas para conhecer esses caras.

1 – O próprio site do Grails tem uma lista das comunidade de Grails.

2 – No linkedin tem uma galera muito ativa.

3 – Grupo de Devs Grails no Brasil.

4 – GrailsRio, criada para juntar a galera de Grails do Rio de Janeiro.

Por fim, sei que talvez isso não tenha muito a ver, mas de preferência criem seus códigos usando o GIT. Caso ainda não conheçam façam este treinamento free online de apenas 15 minutos. Vale muito a pena.

Após ter sua conta no Github, porque não dar um fork no projeto do Grails?

Espero ter ajudado e caso alguém conheça mais itens que podem ajudar no estudo, comentem, pois, além de eu responder posso atualizar o post.

Até a próxima e bons estudos.

Reutilização com Grails Validators

Salve Groovistas!!

É sempre bom descobrir recursos que podem tornar o nosso código mais reutilizável.
Logo, hoje focaremos nos famosos validators do grails.

Sabemos que todas as classes que implementam o @Validatable possuem uma closure estática de nome constraints que pode empacotar algumas regras comumente ligadas ao domínio em questão, facilitando muito na hora de verificar a integridade dessas informações antes de tentar persistir o mesmo.

Depois de muito tempo criando e alterando constraints, eu comecei a ficar incomodado com tanta repetição de código e decidi averiguar a possibilidade de tornar o meu código um pouco mais reutilizável. Foi ai que encontrei três maneiras de reutilizar os validadores do grails.

Podemos separar os validadores reutilizáveis em três categorias:
Empacotados
Globais
Formulário de CommandObject

1 – Empacotados:
Neste caso não é preciso muito conhecimento em grails, pois estamos apenas utilizando orientação a objetos.

Onde pegamos o que se repete e separamos em uma classe, sendo que a única novidade é a maneira que chamamos esse código.

// É sempre bom descobrir recursos que podem tornar nosso projeto mais reutilizável.
class Validators {

    static final confirmPasswordValidator = { value, command ->
        if (command.password != command.confirmPassword) {
            return 'command.confirmPassword.error.mismatch'
        }
    }

    static def requiresAtleastOne =  {val, obj->
        if(!val?.size()){
            return "default.requires.atleast.one"
        }
    }
}
class MyDomain {
        static constraints = {
              items(validator: requiresAtleastOne)
        }
}

Primeiro criamos a classe que ira empacotar as nossas validações, para logo em seguida criar as nossas validações como closures estáticas com seus parâmetros de entrada, lógica de verificação e mensagem de erro para o retorno caso seja necessário.
Para que essa classe seja utilizada como validação, precisamos apenas chama-la de dentro da constraints de nossa classe em questão seguindo a seguinte convenção <atributo_da_classe_local>(<classe_de_validacao>:<closure_de_validacao>). Simples assim.

2 – Globais:
Também podemos reaproveitar nossas validações utilizando o “Global Constraints”
Este é um recurso que precisa ser configurado de dentro do grails-app/conf/Config.groovy. Definindo validações genéricas que serão seguidas por todos os nossos domínios.

//Tambem podemos reaproveitar nossas validações com o "Global Constraints ".

//Podemos aplicar este recurso de dentro do grails-app/conf/Config.groovy
//Definindo validações para todos os domínios
grails.gorm.default.constraints = {
    '*'(nullable: true, size: 1..20)
}

// Ou até até criando diferentes validações globais
grails.gorm.default.constraints = {
    myShared(nullable: true, size: 1..20)
}

//Que pode ser chamadas da seguinte forma
class User {
    static constraints = {
        login(shared: "myShared")
    }
}

3 – Formulário de CommandObject:
Por último, temos o importForm muito utilizado em projetos que seguem o conceito de command object.

Neste caso temos duas classes de cara, o nosso domínio e o seu respectivo Command Object. Praticamente replicamos o constraints do Domain no Command Object, mas seus problemas acabaram!!!!

Com o importForm, no lugar de reescrevermos todas as validações do Domain, nós precisamos apenas escrever importForm . Mais simples impossível!

Segue um exemplo mostrando sua utilização e praticidade:

//Outro recurso que chamou bastante minha atenção foi o importForm.
//Este é um recurso muito utilizado para replicar as validações do domínio para o seu command object.

//Digamos que em nosso projeto tenhamos o seguinte domínio:
class User {
    String firstName
    String lastName
    String passwordHash
    static constraints = {
        firstName blank: false, nullable: false
        lastName blank: false, nullable: false
        passwordHash blank: false, nullable: false
    }
}

//Podemos com o importForm replicar as validações do domínio para o nosso command:
class UserCommand {
    String firstName
    String lastName
    String password
    String confirmPassword
    static constraints = {
        importFrom User

        password blank: false, nullable: false
        confirmPassword blank: false, nullable: false
    }
}

Se você conhece outra maneira de reaproveitar seus validadores não deixe de compartilhar. Comente no post.

Transformando métodos complexos em closures

Salve Groovystas,

Peço desculpas pelo tempo sem posts. Espero que isso não se repita… pois tenho bastante coisa para escrever e com isso pretendo criar a rotina de postar semanalmente.

Em alguns momentos nos deparamos com métodos que devido sua complexidade são difíceis de refatorar.
Recentemente, passei pelo seguinte problema de desempenho:
No sistema existe um método complexo que precisava ser chamado de dentro de um loop e isso sobrecarregava o processamento da funcionalidade em questão.
Devido à urgência desta tarefa, o melhor recurso encontrado neste momento foi a utilização do “memoize()”.
Este é um resumo sobre memoize para facilitar o entendimento:

//Problema: Quando temos um loop e dentro dele temos uma determinada
//lógica que precisará ser executada em todas as iterações;
(1..10).each{println  "este numero é ${it+5*(10-1)}"}

//Solução: Podemos otimizar nosso código inserindo nossa lógica dentro
//de uma closure, onde ao final desta chamamos o método memoize().
c = {println "este numero é ${it+5*(10-1)}"}.memoize()

//Por fim, chamamos esta closure de dentro do loop para que apenas a primeira
//interação seja 100% processada, pois nas próximas a parte repetida desta
//logica ficará em cache apenas sofrendo alteração de parâmetro.
(1..10).each(c)

Esse foi apenas um resumo, um exemplo rápido para não jogarmos termos novos sem explicação no post, mas em breve pretendo escrever exclusivamente sobre esse recurso que já me salvou varias vezes.

Mas, para nossa infelicidade, esta complexidade estava dentro de um método. Logo este precisou virar uma closure.

Imagine que estamos lidando com um método que é frequentemente alterado, como um cálculo de tarifa ou algo parecido e que é chamado por varias outras classes. Nesta situação, se alterássemos este método para uma closure, isso implicaria em um preenchimento desnecessário da PermGem, sem contar que iriamos inserir o memoize(), que seria um recurso desnecessário para a maioria dos casos. Logo estaríamos concertando de um lado para provavelmente estragar de outro.

Chega de revira volta!!! Vamos para o Show me the code!

Neste caso podemos utilizar “reference.&”, que recupera toda a lógica de um determinado método e a transforma em uma closure.

class SizeFilter {
    Integer limit
    boolean filter (String value) {
        return value.length() <= limit
    }
}

SizeFilter six = new SizeFilter(limit:6) //#1 Construtor

SizeFilter five = new SizeFilter(limit:5) //#1 Chamada

Closure smallerSix = six.&filter //#2 Associando o método à closure

def words = ['long string', 'medium', 'short', 'tiny']

assert 'medium' == words.find (smallerSix) //#3 Chamando a closure

assert 'short' == words.find (five.&filter) //#4 Passando a closure diretamente

Lembrando que os recursos fornecidos, raramente são para todas as situações. Logo, nada como uma boa análise antes de sairmos codificando.

Por fim, algo que chamou muito minha atenção, foi o fato de o “reference.&” também trabalhar em cima do polimorfismo conforme exemplo abaixo:

class MultiMethodSample{
    int mysterMethod(String value){
        return value.length()
    }
    int mysterMethod(List list){
        return list.size()
    }
    int mysterMethod(int x, int y){
        return x+y
    }
}

MultiMethodSample instance = new MultiMethodSample()
Closure multi = instance.&mysterMethod

assert 10 == multi ('string arg')
assert 3  == multi (['list', 'of', 'values'])
assert 14 == multi (6, 8)

Como podemos notar, o processamento da closure muda quando alteramos os parâmetros.

Espero ter ajudado com a dica e até os próximos posts.

O Nirvana da Programação parte 2 – Montando meu ecossistema social:

PodCasts de Tecnologia: GrokPodCast e CastalioPodCast

Definição: Audios disponíveis para ouvir online ou baixar sobre tecnologia.

Detalhes: As vezes quando não temos tempo para uma boa leitura ou não conseguimos ler muito bem no ônibus, podemos optar por ouvir o mesmo conteudo.

Aqui eu estou listando dois podcasts que realmente deram a uma cara nova ao meu ecossistema tecnológico!

Temos o CastalioPodCast(http://www.castalio.info ) voltado para tecnologia em geral e o GrokPodCast(http://www.grokpodcast.com/) completamente voltado para desenvolvedores!! É impressionante a quantidade de coisas que eu já aprendi só ouvindo estes podcasts indo para o trabalho e se você esta na mesma situação que eu (transito louco do Rio de Janeiro) você leva bastante tempo dentro do ônibus! Rsrs!

Dojo de programação

Definição: Local para treinamento de desenvolvedores ninjas!

Detalhes: Em um dojo, aprendemos a de fato entender o problema antes de sair codando, praticamos trabalho em grupo, TDD e fazemos um network de causar inveja em algumas pessoas que ficam curtindo o mundo pela janela de casa!

CodeSchool

Denifição: site com cursos online completamente voltados para programação que seguem a seguinte filosofia, aprender fazendo! E ainda não vi curso melhor dentro dessa categoria!

Detalhes:  Apesar de termos poucos cursos disponíveis de graça, os pagos são baratos, rápidos e intuitivos. Eu tenho a impressão de que ele faz até quem não gosta de programação gostar.

Network

Definição: Todo bom programador não é bom programador sozinho, estamos em um ecossistema rico de seres vivos cheio de conhecimento para disseminar e não podemos nos trancar em uma bolha, precisamos sim nos envolver e muito!

Detalhes:

Dojos e programação – Estou citando novamente este cara porque os melhores desenvolvedores que conheço fazem parte de algum grupo de dojo.

Eventos de TI: Temos que nos localizar… e nada melhor que escolher o mundo que queremos fazer parte após conhecer a galera que esta nele! Ex: Podemos ir a um evento de Python e ver como rola o network ou podemos ir a um evento de Ruby e assim por diante. O importante é tentar ficar por dentro.

GeeksOnBeer: Este é um evento que ocorre todo mês e tem como objetivo reunir programadores com espirito empreendedor com os caras que podem financiar o seu projeto. Fala sério!!… Qual programador não quer tirar uma onde de Mark Zuckerberg!

Inglês

Definição: Não preciso nem falar o quanto ele é importante em nosso cinto de utilidades.

Detalhes: Muitos podem estar esperando ter condições para poder entrar em um curso de inglês, mas isso não e completamente necessário existe recursos web que para alguns ajudam até mais que cursos e não estou falando de cursos online, estou falando de aplicativos como se fossem redes sociais voltadas para quem quer aprender outra língua. Ex: LiveMocha (http://livemocha.com/). Aqui você além de aprender inglês interagindo faz amigos fora do Brasil.

Motivação e Internet disponível

Não adianta ter todos esses aparatos se não existir muita motivação e vontade de aprender!

Por fim, não tenha vergonha de entrar em contato. Grande parte dos ícones do mundo tecnológico que conhecemos tem uma disposição muito grande em contribuir com conhecimento.

Certamente existem outros itens de grande valor, mas o intuito foi tentar traças um norte.

Espero ter ajudado!

Referências:

Linkedin            : http://linkedin.com/

Git                 : http://git-scm.com/

Github              : http://github.com/

Heroku              : http://heroku.com/

Appengine           : http://developers.google.com/appengine/

CastalioPodCast     : http://www.castalio.info/

GrokPodCast         : http://grokpodcast.com/

Dojo de programação : http://dojorio.org/

CodeSchool          : http://codeschool.com/

Geeksonbeer         : http://geeksonbeer.com/

Livemocha           : http://livemocha.com/

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.