<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>Groselhas - O blog do Mauro George</title>
 <link type="application/atom+xml" rel="self" href="http://feeds.feedburner.com/groselhas"/>
 <link href="http://groselhas.maurogeorge.com.br/"/>
 <updated>2016-04-07T01:01:10+00:00</updated>
 <id>http://groselhas.maurogeorge.com.br/</id>
 <author>
   <name>Mauro George</name>
   <email>maurogot@gmail.com</email>
 </author>

 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/como-foi-criar-um-jogo-para-fazer-um-pedido-de-casamento</id>
   <title>Como foi criar um jogo para fazer um pedido de casamento</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/como-foi-criar-um-jogo-para-fazer-um-pedido-de-casamento.html"/>
   <updated>2016-04-06T00:00:00+00:00</updated>
   <content type="html">&lt;h2 id=&quot;a-ideia&quot;&gt;A ideia&lt;/h2&gt;

&lt;p&gt;Ano passado em algum dia próximo ao fim do ano a noite estava em casa e me bateu
uma ideia “E se eu fizesse um jogo para pedir a Jéssica em casamento?”. Começei
a pensar um pouco sobre o assunto, fui anotando as ideias no Google Calendar.
Sim, utilizei o calendar pois pretendia começar o projeto apenas em Janeiro.&lt;/p&gt;

&lt;p&gt;Anotei que teria que ser um jogo de plataforma, com a Jéssica como personagem
principal, jogo 2D, assets do Mario, interação com personagens conhecidos
durante a fase etc.&lt;/p&gt;

&lt;h2 id=&quot;imprevistos-acontecem&quot;&gt;Imprevistos acontecem&lt;/h2&gt;

&lt;p&gt;Comecei o ano de 2016 doente, fiquei com dengue e não consegui trabalhar nem me
dedicar ao novo projeto.&lt;/p&gt;

&lt;p&gt;Tive que ficar de repouso e visitar o médico basicamente de 2 em 2 dias.&lt;/p&gt;

&lt;p&gt;Mas deu tudo certo e depois de aproximadamente 2 semanas, consegui começar o
projeto.&lt;/p&gt;

&lt;h2 id=&quot;organizao-do-projeto&quot;&gt;Organização do projeto&lt;/h2&gt;

&lt;p&gt;Para controlar as tarefas e o que fazer no projeto utilizei o Trello. Com um
simples kanban com 3 colunas “A fazer”, “Fazendo” e “Finalizado”.&lt;/p&gt;

&lt;p&gt;Além disso criei uma coluna chamada “Sempre lembrar de” de coisas que deveria
ter sempre em mente enquanto trabalhava no projeto. Como por exemplo tinha um
card com a ideia inicial, um que falava para manter as coisas simples, um para
salvar todas as referências etc.&lt;/p&gt;

&lt;h3 id=&quot;o-planning&quot;&gt;O planning&lt;/h3&gt;

&lt;p&gt;Não queria que este projeto se extendesse por muito tempo, queria que no começo
de maio já o tivesse apresentado para Jéssica e feito uma surpresa a ela.&lt;/p&gt;

&lt;p&gt;Então criei um card na coluna “Sempre lembrar de” para analisar a duração das
tarefas. Então toda segunda que, era quando começava a trabalhar no projeto, eu
começava olhando para a semana anterior e vendo se ela foi produtiva, seja de
aprendizado ou de desenvolvimento de fato.
Sempre colocava um &lt;em&gt;due date&lt;/em&gt; no card assim toda vez eu era lembrado dele quando
chegava o começo da iteração.&lt;/p&gt;

&lt;p&gt;Além de criar mais tarefas para serem realizadas, caso ainda não tenham sido
criadas. Também era comum tarefas serem criadas durante o próprio
desenvolvimento.&lt;/p&gt;

&lt;h3 id=&quot;roadmap&quot;&gt;Roadmap&lt;/h3&gt;

&lt;p&gt;Sabemos que tentar ser previsivel no desenvolvimento de software é algo
complicado. Levando em conta que estava desenvolvendo algo que nunca tinha feito
antes então a imprevisibilidade era maior ainda.&lt;/p&gt;

&lt;p&gt;No entanto depois de ter algum conhecimento do processo, provavelmente depois de
ter finalizado a prova de conceito, decidi criar um roadmap para ver se as
tarefas que eu havia criado seriam plausiveis de serem realizados dado que tinha
um deadline.&lt;/p&gt;

&lt;p&gt;E como todo bom roadmap ele falhou miseravélmente. No dia 25/03/2016 eu fiz o
pedido de casamento. Ou seja com aproximadamente um mês de antecedência.&lt;/p&gt;

&lt;h3 id=&quot;acompanhando-o-andamento&quot;&gt;Acompanhando o andamento&lt;/h3&gt;

&lt;p&gt;Utilizo o &lt;a href=&quot;https://www.coach.me/&quot;&gt;Coach.me&lt;/a&gt; há algum tempo para acompanhar
certas tarefas.&lt;/p&gt;

&lt;p&gt;Para quem não o conhece é uma ferramenta para ajudar a criar hábitos e o legal é
poder acompanhar o andamento, e assim ver quando foi realizada tal tarefa.&lt;/p&gt;

&lt;p&gt;Então para me dedicar a este projeto eu tive que parar outros, como por exemplo
contribuir com projetos open source. Sendo assim criei este novo hábito no
Coach.me e coloquei que iria me dedicar a ele de segunda a quinta em torno de 2
horas por dia.&lt;/p&gt;

&lt;p&gt;Segue a visão do Coach.me dos dias que trabalhei no projeto.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2016-04-06/coach-me.png&quot; alt=&quot;Andamento do projeto no Coach.me&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Como pode ver foram 42 dias que trabalhei no projeto. Algumas semanas com mais
dias e outras com menos, provavelmente devido a ter que resolver outros
compromissos nas que estavam com menos e nas que estavam com mais dias é devido
a não ter compromisso em alguns sábados em especifico e nestes normalmente o
trabalho foi maior do que 2hs.&lt;/p&gt;

&lt;h3 id=&quot;ritmo-sustentvel&quot;&gt;Ritmo sustentável&lt;/h3&gt;

&lt;p&gt;Para quem esteja se perguntando por que de parar uma coisa para começar outra.
Primeiro para ter foco e conseguir entregar algo de qualidade. É bastante
complicado querermos iniciar e manter N iniciativas ao mesmo tempo ainda mais
que todos nós trabalhamos e temos outras tarefas no nosso dia a dia. Então
preferi cortar algumas atividades por um tempo.&lt;/p&gt;

&lt;p&gt;Há um tempo escrevi sobre
&lt;a href=&quot;http://helabs.com/blog/2015/02/06/ritmo-sustentavel/&quot;&gt;Ritmo Sustentável no blog da HE:labs&lt;/a&gt;.
Além do ritmo sustentável no trabalho trago esta prática para os projetos
paralelo que inicio também.&lt;/p&gt;

&lt;h2 id=&quot;qual-engine-usar&quot;&gt;Qual engine usar?&lt;/h2&gt;

&lt;p&gt;Como fazer um jogo é algo que nunca tinha feito, comecei realizando pesquisas de
engines para jogos 2D e que atendecem aos requisitos que eu tinha que
desenvolver.&lt;/p&gt;

&lt;p&gt;A principio a ideia era utilizar Unity, no entanto continuei pesquisando
&lt;a href=&quot;https://github.com/showcases/javascript-game-engines&quot;&gt;engines&lt;/a&gt;
de &lt;a href=&quot;https://html5gameengine.com/&quot;&gt;JavaScript&lt;/a&gt;, passei por
&lt;a href=&quot;https://www.ruby-toolbox.com/categories/game_libraries&quot;&gt;Ruby&lt;/a&gt; também.&lt;/p&gt;

&lt;p&gt;Por mais que desenvolver algo em Unity fosse uma experiência nova e
desafiadora, tinha que lembrar que tinha um deadline então o que fosse mais
próximo da minha realidade seria melhor de atingir um resultado num espaço de tempo
menor.&lt;/p&gt;

&lt;p&gt;Então depois de pesquisar diversas engines de JavaScript acabei escolhendo o
&lt;a href=&quot;http://phaser.io/&quot;&gt;Phaser&lt;/a&gt; que parecia resolver meu problema, tinha diversos
cases e uma documentação boa.&lt;/p&gt;

&lt;h2 id=&quot;prova-de-conceito&quot;&gt;Prova de conceito&lt;/h2&gt;

&lt;p&gt;Escolhida a Game Engine, parti para a prova de conceito. Como tinha que ter um
servidor web rodando e não poderia ser apenas HTMLs soltos dentro de uma pasta,
montei um pequeno projeto utilizando o
&lt;a href=&quot;https://pages.github.com/&quot;&gt;GitHub Pages&lt;/a&gt;. Antes utilizei um pouco do
SimpleHTTPServer do Python, mas depois que comecei a desenvolver a projeto de
fato prefiri utilizar o Github Pages pois assim facilitaria o deploy e também
estou mais acostumado com o mundo Ruby de qualquer maneira.&lt;/p&gt;

&lt;p&gt;Comecei lendo alguns
&lt;a href=&quot;https://software.intel.com/en-us/html5/hub/blogs/how-to-make-a-sidescroller-game-with-html5&quot;&gt;tutoriais&lt;/a&gt;
&lt;a href=&quot;http://phaser.io/tutorials/getting-started&quot;&gt;sobre&lt;/a&gt; o
&lt;a href=&quot;http://phaser.io/tutorials/making-your-first-phaser-game&quot;&gt;Phaser&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;E ir implementando cada um dos requisitos iniciais que eu tinha.&lt;/p&gt;

&lt;h2 id=&quot;resoluo&quot;&gt;Resolução&lt;/h2&gt;

&lt;p&gt;Antes estava utilizando a resolução de 800X600. No entanto ao adicionar um
sprite do Mario Bros de NES numa resolução dessa, como pode imaginar o
personagem ficou bem pequeno.&lt;/p&gt;

&lt;p&gt;Então pesquisei sobre qual era a resolução do NES para fazer exatamente a mesma.
Com isso alterei a resolução do jogo para a mesma do NES. No entanto em nossos
monitores com resoluções maiores como deve imaginar a resolução de 256x240 é bem
pequena.&lt;/p&gt;

&lt;p&gt;Para resolver o problema eu fiz o resize do jogo diretamente pelo CSS aumentando
em 2 vezes a resolução.
Pesquisei sobre algumas soluções de fazer o resize, fiz testes e no final das
contas utilizando apenas CSS consegui o mesmo resultado e com menos
complexidade.&lt;/p&gt;

&lt;h2 id=&quot;game-design&quot;&gt;Game Design&lt;/h2&gt;

&lt;p&gt;No meio dos estudos acabei conhecendo o &lt;a href=&quot;http://www.mapeditor.org/&quot;&gt;Tiled&lt;/a&gt; uma
excelente ferramenta para criação de tile maps.&lt;/p&gt;

&lt;p&gt;Com o Tiled consegui importar facilmente incluir o tilemap do Mario Bros de NES
e criar a fase conforme eu quisesse.&lt;/p&gt;

&lt;p&gt;Um fato legal do Tiled, é que por um acaso no processo do desenvolvimento do
jogo estava jogando Shovel Knight: Plague of Shadows e ao finalizar percebi que
nos créditos é listado o Tiled. Fiquei feliz de está utilizando a mesma
ferramenta que o pessoal do Shovel Knight.&lt;/p&gt;

&lt;p&gt;Como os arquivos originais do Tiled o &lt;code class=&quot;highlighter-rouge&quot;&gt;.tmx&lt;/code&gt; é um XML e não era grande preferi
manter eles no repositório e estava utilizando o formato JSON para carregar o
tile map no jogo.&lt;/p&gt;

&lt;h2 id=&quot;assets&quot;&gt;Assets&lt;/h2&gt;

&lt;p&gt;Para os assets utilizei o &lt;a href=&quot;http://www.spriters-resource.com/&quot;&gt;The Spriters Resource&lt;/a&gt;
onde consegui os tile maps, itens, inimigos etc.&lt;/p&gt;

&lt;p&gt;Para criar os personagens customizados, no caso Jéssica e eu, utilizei o
&lt;a href=&quot;http://pixel.tools/&quot;&gt;Pixel.Tools&lt;/a&gt; um editor de pixel-art online.
Na criação dos personagens customizados mantive a mesma paleta de cores do NES.
Utilizei também o Pixel.Tools para gerar o logo do jogo.&lt;/p&gt;

&lt;p&gt;Para os efeitos sonoros utilizei o &lt;a href=&quot;http://www.sounds-resource.com&quot;&gt;The Sounds Resource&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;vendor&quot;&gt;Vendor&lt;/h2&gt;

&lt;p&gt;No processo preciva criar balões de fala no entano não queria ter que fazer
isso do zero. Acabei encontrando uma
&lt;a href=&quot;http://www.html5gamedevs.com/topic/8837-speech-bubble-text-with-rectangle-as-background/&quot;&gt;discussão sobre isso aqui&lt;/a&gt;
a solução pode ser encontrada &lt;a href=&quot;http://jsfiddle.net/lewster32/81pzgs4z/&quot;&gt;aqui&lt;/a&gt;.
Para manter isso isolado, adicionei tal código em uma pasta de vendor e alterei
para atingir o que eu realmente precisava.&lt;/p&gt;

&lt;p&gt;Não achei nenhum plugin pronto para o Phaser que fazia isso, aparentemente tem
algum sistema de plugins, mas não cheguei a utilizar nenhum plugin no processo.&lt;/p&gt;

&lt;h2 id=&quot;roteiro&quot;&gt;Roteiro&lt;/h2&gt;

&lt;p&gt;Além das tarefas de programar o jogo, era necessário escrever os textos para o
mesmo, então para não negligenciar tais pontos criei tarefas no Trello para
criar texto para todas as partes que tinha texto envolvido.&lt;/p&gt;

&lt;h2 id=&quot;testes-e-mais-testes&quot;&gt;Testes e mais testes&lt;/h2&gt;

&lt;p&gt;Foi necessário bastante teste para ver se tudo estava rodando como deveria, e no
caso aqui abrir o browser e rodar de fato o jogo, passar pelo jogo e ver se
estava tudo certo.&lt;/p&gt;

&lt;p&gt;Como a ideia era fazer o pedido o mais rápido possivel não pesquisei sobre
testes automatizados.
Acredito que seja razoavelmente simples testar classes especificas do jogo de
forma unitária. Agora testes de ponta a ponta não cheguei a pesquisar.&lt;/p&gt;

&lt;h2 id=&quot;mundo-real&quot;&gt;Mundo real&lt;/h2&gt;

&lt;p&gt;Além das tarefas relacionadas ao jogo também criei outras tarefas no Trello
relacionado ao mundo real como por exemplo “Comprar aliança”.
Era importante criar tais tarefas para não esquecer de nada, além de poder
priorizar com clareza o que deveria ser realizado na semana.&lt;/p&gt;

&lt;h2 id=&quot;t-mas-e-o-tal-jogo&quot;&gt;Tá mas e o tal jogo?&lt;/h2&gt;

&lt;p&gt;Então agora que você chegou aqui fica aqui o link para o código no
&lt;a href=&quot;https://github.com/maurogeorge/segredario&quot;&gt;GitHub&lt;/a&gt; tem também uma
&lt;a href=&quot;https://github.com/maurogeorge/segredario/releases/tag/proof-of-concept&quot;&gt;tag para a prova de conceito&lt;/a&gt;
e uma &lt;a href=&quot;https://github.com/maurogeorge/segredario/releases/tag/v1.0.0&quot;&gt;tag para versão que foi utilizada para fazer o
pedido&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Além disso você pode jogar o jogo em &lt;a href=&quot;http://segredario.maurogeorge.com.br/&quot;&gt;segredario.maurogeorge.com.br&lt;/a&gt;.
Recomendo utilizar o Chrome, não sei por que mas no
&lt;a href=&quot;https://github.com/maurogeorge/segredario/issues/8&quot;&gt;Firefox&lt;/a&gt; a perfomance não
está boa.&lt;/p&gt;

&lt;p&gt;Espero que curtam =D
Sim ela curtiu e estamos noivos!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/rolify-com-pundit-para-uma-autorizacao-com-multiplos-papeis</id>
   <title>Rolify com Pundit para uma autorização com múltiplos papéis</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/rolify-com-pundit-para-uma-autorizacao-com-multiplos-papeis.html"/>
   <updated>2014-09-04T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;No &lt;a href=&quot;http://groselhas.maurogeorge.com.br/autorizacao-com-pundit.html&quot;&gt;último post utilizando o Pundit&lt;/a&gt; vimos como implementar um sistema de autorização com um único papel(&lt;em&gt;single role&lt;/em&gt;). Porém os requisitos mudam e temos que &lt;a href=&quot;http://agilemanifesto.org/&quot;&gt;responder a mudanças&lt;/a&gt;. Nosso problema agora é:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;No sistema de gerenciamento de empresas temos 3 papeis o do gerente e o do empregado. O Gerente pode visualizar todas as telas do sistema. O empregado não pode criar, editar ou excluir nenhuma empresa. &lt;strong&gt;O investidor deve visualizar apenas as empresas em que ele investe.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Agora que nossos requisitos mudaram saimos de um sistema de um unico papel para multiplos papéis(&lt;em&gt;multiple roles&lt;/em&gt;). Pois eu devo poder definir para cada um dos investidores quais empresas ele tem acesso, supondo que tenhamos as empresas A, B e C, deve ser possivel dizer que o investidor tem o papel &lt;em&gt;investidor&lt;/em&gt; apenas na empresa A e C, ou seja ele possui 2 papeis diferentes.&lt;/p&gt;

&lt;h2 id=&quot;conhecendo-o-rolify&quot;&gt;Conhecendo o Rolify&lt;/h2&gt;

&lt;p&gt;O &lt;a href=&quot;https://github.com/RolifyCommunity/rolify&quot;&gt;Rolify&lt;/a&gt; é uma gem responsável para lidar com papéis, possui uma interface legal que veremos durante o nosso exemplo.&lt;/p&gt;

&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;/h2&gt;

&lt;p&gt;Começamos pelo clássico, adicionar &lt;code class=&quot;highlighter-rouge&quot;&gt;gem &quot;rolify&quot;&lt;/code&gt; no nosso &lt;code class=&quot;highlighter-rouge&quot;&gt;Gemfile&lt;/code&gt;. Depois de instalado temos que rodar o gerador do Rolify.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;rails g rolify Role User&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Depois do gerador criado rode a migration gerada com &lt;code class=&quot;highlighter-rouge&quot;&gt;$ rake db:migrate&lt;/code&gt;. Além da migration gerada será criado um model &lt;code class=&quot;highlighter-rouge&quot;&gt;Role&lt;/code&gt; e adicionado uma macro &lt;code class=&quot;highlighter-rouge&quot;&gt;rolify&lt;/code&gt; no nosso model &lt;code class=&quot;highlighter-rouge&quot;&gt;User&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;No exemplo do Pundit utilizamos o &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Enum&lt;/code&gt; para definirmos o nosso papel, o ideal seriamos movermos toda esta parte de papeis agora para o rolify, para não ficarmos com 2 sistemas de papeis diferentes, não entrarei em detalhes dado a isso ser bem simples como verá a seguir.&lt;/p&gt;

&lt;h2 id=&quot;definindo-os-recursos-que-aplicaremos-um-papel&quot;&gt;Definindo os recursos que aplicaremos um papel&lt;/h2&gt;

&lt;p&gt;Simplesmente adicionamos o macro &lt;code class=&quot;highlighter-rouge&quot;&gt;resourcify&lt;/code&gt; no model que queremos utilizar na definição dos papeis.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Company&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;resourcify&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;adicionando-e-removendo-um-papel&quot;&gt;Adicionando e removendo um papel&lt;/h2&gt;

&lt;p&gt;Agora com o setup definido vamos adicionar o nosso primeiro papel a um usuário. Para isso simplemente chamamos o método &lt;code class=&quot;highlighter-rouge&quot;&gt;#add_role&lt;/code&gt; passando o papel e o recurso que estamos dando acesso ao usuário.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add_role&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:investor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;company&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Não entrarei no mérito de controller, ou onde este papel é definido.&lt;/p&gt;

&lt;p&gt;Para removermos um papel de um usuário simplesmente utilizamos do método &lt;code class=&quot;highlighter-rouge&quot;&gt;#remove_role&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;remove_role&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:investor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;company&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Com isso já somos capazes de definir e remover papeis de usuários.&lt;/p&gt;

&lt;h2 id=&quot;garantindo-a-integridade-dos-papeis&quot;&gt;Garantindo a integridade dos papeis&lt;/h2&gt;

&lt;p&gt;O Rolify nos permite definir qualquer papel e ainda em qualquer entidade, mesmo aquelas em que não foram aplicados o &lt;code class=&quot;highlighter-rouge&quot;&gt;resourcify&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add_role&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:magician&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;store&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Como no nosso caso só temos o papel &lt;code class=&quot;highlighter-rouge&quot;&gt;investor&lt;/code&gt; e o único recurso que estamos adicionando papel é o &lt;code class=&quot;highlighter-rouge&quot;&gt;Company&lt;/code&gt; seria uma boa definirmos uma validação para isso. Assim evitamos que novos papeis sejam criados por engano, deixando o nosso &lt;a href=&quot;http://legacy.python.org/dev/peps/pep-0020/&quot;&gt;código mais explicito&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;O Rolify nos fornece um model &lt;code class=&quot;highlighter-rouge&quot;&gt;Role&lt;/code&gt; então o que temos que fazer é apenas definir as validações de inclusão no mesmo.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Role&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;

  &lt;span class=&quot;no&quot;&gt;NAMES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{ investor }&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;RESOURCE_TYPES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{ Company }&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;validates&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;inclusion: &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;in: &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;NAMES&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;validates&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:resource_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;inclusion: &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;in: &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;RESOURCE_TYPES&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Agora ao tentarmos adicionar um papel e uma entidade que não existem com o &lt;code class=&quot;highlighter-rouge&quot;&gt;#add_role&lt;/code&gt; não seremos capazes, receberemos um objeto &lt;code class=&quot;highlighter-rouge&quot;&gt;Role&lt;/code&gt; não persistido como retorno.&lt;/p&gt;

&lt;h2 id=&quot;recuperando-as-empresas-do-usurio&quot;&gt;Recuperando as empresas do usuário&lt;/h2&gt;

&lt;p&gt;O Rolify nos oferece &lt;em&gt;query methods&lt;/em&gt; para interagirmos com nossos recursos que estão como &lt;code class=&quot;highlighter-rouge&quot;&gt;resourcify&lt;/code&gt;. E com o método &lt;code class=&quot;highlighter-rouge&quot;&gt;.with_role&lt;/code&gt; conseguimos recuperar todas as empresas em que possuem o papel &lt;code class=&quot;highlighter-rouge&quot;&gt;investor&lt;/code&gt; e atrelada a um usuário especifico.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;Company&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;with_role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:investor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Assim temos todas as empresas em que o &lt;code class=&quot;highlighter-rouge&quot;&gt;user&lt;/code&gt; é investidor, com uma simples chamada de método.&lt;/p&gt;

&lt;h2 id=&quot;pundit-em-conjunto-com-o-rolify&quot;&gt;Pundit em conjunto com o Rolify&lt;/h2&gt;

&lt;p&gt;Voltando nos nossos requisitos, temos que listar apenas as empresas que o investidor investe. O Pundit nos permite definir um escopo baseado nas permissões do usuário para isso definimos uma classe &lt;code class=&quot;highlighter-rouge&quot;&gt;Scope&lt;/code&gt; dentro do nosso &lt;code class=&quot;highlighter-rouge&quot;&gt;CompanyPolicy&lt;/code&gt; e implementamos o método &lt;code class=&quot;highlighter-rouge&quot;&gt;#resolve&lt;/code&gt;. Como estamos herdando do &lt;code class=&quot;highlighter-rouge&quot;&gt;Scope&lt;/code&gt; do &lt;code class=&quot;highlighter-rouge&quot;&gt;ApplicationPolicy&lt;/code&gt; já temos acesso ao &lt;code class=&quot;highlighter-rouge&quot;&gt;user&lt;/code&gt; e ao &lt;code class=&quot;highlighter-rouge&quot;&gt;scope&lt;/code&gt; a partir daí apenas fazemos a consulta que precisamos.&lt;/p&gt;

&lt;p&gt;O Rolify define também o método &lt;code class=&quot;highlighter-rouge&quot;&gt;#has_role?&lt;/code&gt; o utilizamos para verificar se o usuário possui qualquer papel de &lt;code class=&quot;highlighter-rouge&quot;&gt;investor&lt;/code&gt;, caso ele possua listamos apenas as empresas em que ele tem acesso, caso não possua nenhum papel de investidor exibimos todas as empresas.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CompanyPolicy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ApplicationPolicy&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Scope&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Scope&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;resolve&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;has_role?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:investor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:any&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;with_role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:investor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;all&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Com o nosso escopo definido simplesmente chamamos ele no controller com o &lt;code class=&quot;highlighter-rouge&quot;&gt;policy_scope&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;index&lt;/span&gt;
  &lt;span class=&quot;vi&quot;&gt;@companies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;policy_scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Company&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Agora dependendo do papel do usuário é exibido uma listagem com todas as empresas, ou apenas com as que o usuário é investidor.&lt;/p&gt;

&lt;h2 id=&quot;concluso&quot;&gt;Conclusão&lt;/h2&gt;

&lt;p&gt;O Rolify é uma excelente ferramenta para quando necessitamos lidar com multiplos papéis em uma aplicação rails, e facilita ainda mais a nossa vida ao integrarmos ele com o Pundit.
No nosso exemplo utilizamos o Active Record, mas o Rolify tem suporte ao Mongoid também.
Não deixe de visualizar a &lt;a href=&quot;https://github.com/RolifyCommunity/rolify/wiki&quot;&gt;wiki do Rolify&lt;/a&gt; para conhecer mais formas de adicionar/remover papéis, além das queries que ele implementa.&lt;/p&gt;

&lt;h2 id=&quot;referncias&quot;&gt;Referências&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/elabs/pundit&quot;&gt;https://github.com/elabs/pundit&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/RolifyCommunity/rolify&quot;&gt;https://github.com/RolifyCommunity/rolify&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://eng.joingrouper.com/blog/2014/03/20/rails-the-missing-parts-policies/&quot;&gt;http://eng.joingrouper.com/blog/2014/03/20/rails-the-missing-parts-policies/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://railsapps.github.io/rails-authorization.html&quot;&gt;http://railsapps.github.io/rails-authorization.html&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/RolifyCommunity/rolify/wiki&quot;&gt;https://github.com/RolifyCommunity/rolify/wiki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/autorizacao-com-pundit</id>
   <title>Autorização com Pundit</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/autorizacao-com-pundit.html"/>
   <updated>2014-09-02T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Quem é da comunidade ruby há algum tempo já é acostumado com o &lt;a href=&quot;https://github.com/ryanb/cancan&quot;&gt;CanCan&lt;/a&gt; e com o seu sucessor o &lt;a href=&quot;https://github.com/CanCanCommunity/cancancan&quot;&gt;CanCanCan&lt;/a&gt; que é a continuação do CanCan dado que o mesmo foi abandonado.&lt;/p&gt;

&lt;p&gt;Em ambas das soluções temos apenas uma class &lt;code class=&quot;highlighter-rouge&quot;&gt;Ability&lt;/code&gt; e definimos os nossos métodos de autorização ali. Para projetos pequenos pode ser uma boa saida, no entanto com o passar do tempo a complexidade aumenta e temos que extrair isso para classes expecificas e chama-las dentro da nossa interface do CanCan que é o model &lt;code class=&quot;highlighter-rouge&quot;&gt;Ability&lt;/code&gt;. Mas e se já começassemos com uma abordagem mais inteligente? Com pequenas classes e cada uma definindo sua responsabilidade?&lt;/p&gt;

&lt;h2 id=&quot;ol-pundit&quot;&gt;Olá Pundit&lt;/h2&gt;

&lt;p&gt;O &lt;a href=&quot;https://github.com/elabs/pundit&quot;&gt;Pundit&lt;/a&gt; utiliza o conceito de &lt;a href=&quot;http://eng.joingrouper.com/blog/2014/03/20/rails-the-missing-parts-policies/&quot;&gt;Policies ou Policy Objects&lt;/a&gt; para lidar com autorização. Mas antes de entrarmos a fundo no Pundit primeiro devemos ter um problema, então nosso problema é:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;No sistema de gerenciamento de empresas temos 2 papeis o do gerente e o do empregado. O Gerente pode visualizar todas as telas do sistema. O empregado não pode criar, editar ou excluir nenhuma empresa.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Agora com o nosso problema em mão vamos iniciar. Não entrarei no mérito de autenticação, em que podemos utilizar o &lt;a href=&quot;https://github.com/plataformatec/devise&quot;&gt;devise&lt;/a&gt;, nem na definição de papéis em que podemos utilizar o &lt;a href=&quot;http://groselhas.maurogeorge.com.br/good-bye-jacaranda-and-welcome-activerecord-enum.html&quot;&gt;ActiveRecord::Enum&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;/h2&gt;

&lt;p&gt;Como de costume adicionamos ao nosso Gemfile &lt;code class=&quot;highlighter-rouge&quot;&gt;gem &quot;pundit&quot;&lt;/code&gt;. Depois de instalado incluimos o Pundit em nosso application controller.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ApplicationController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActionController&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Pundit&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Agora executamos o seu generator para termos a nossa primeira policy definida.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;rails g pundit:install&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Esta nossa primeira policy ainda não é utilizada ela será utilizada como base para as policies que formos definir. Ela define alguns padrões como por exemplo o &lt;code class=&quot;highlighter-rouge&quot;&gt;destroy?&lt;/code&gt; como &lt;code class=&quot;highlighter-rouge&quot;&gt;false&lt;/code&gt;, sendo assim se invocarmos um policy de &lt;code class=&quot;highlighter-rouge&quot;&gt;destroy&lt;/code&gt; mas não o definirmos por padrão será &lt;code class=&quot;highlighter-rouge&quot;&gt;false&lt;/code&gt; desde que herdermos de &lt;code class=&quot;highlighter-rouge&quot;&gt;ApplicationPolicy&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Assim como o CanCan o Pundit utiliza do método &lt;code class=&quot;highlighter-rouge&quot;&gt;current_user&lt;/code&gt; para pegar o usuário atual.&lt;/p&gt;

&lt;h2 id=&quot;criando-nossa-primeira-policy&quot;&gt;Criando nossa primeira Policy&lt;/h2&gt;

&lt;p&gt;Voltando lá ao nosso problema, devemos proteger as ações de criar, editar e excluir de empresa do usuário com o papel de empregado. Então vamos criar uma &lt;code class=&quot;highlighter-rouge&quot;&gt;CompanyPolicy&lt;/code&gt;, para isso utilizamos do generator da seguinte maneira.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;rails g pundit:policy company&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Que nos gera uma classe para iniciarmos definindo a nossa policy. Então vamos definir primeiro que apenas o gerente pode criar uma nova empresa. Para isso definimos o método &lt;code class=&quot;highlighter-rouge&quot;&gt;create?&lt;/code&gt;, por convenção o nome da action com um interrogação no final, e simplesmente utilizamos o método &lt;code class=&quot;highlighter-rouge&quot;&gt;@user.manager?&lt;/code&gt; do &lt;code class=&quot;highlighter-rouge&quot;&gt;User&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CompanyPolicy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ApplicationPolicy&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create?&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;manager?&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Com isso garantimos que apenas o usuário com o papel de gerente pode criar uma nova empresa. Mas você deve estar se perguntando, por que eu defini apenas o &lt;code class=&quot;highlighter-rouge&quot;&gt;create?&lt;/code&gt; e não defini &lt;code class=&quot;highlighter-rouge&quot;&gt;new?&lt;/code&gt; afinal não queremos que o funcionário acesse a tela de criar.&lt;/p&gt;

&lt;p&gt;Isto ocorre por que no nosso &lt;code class=&quot;highlighter-rouge&quot;&gt;ApplicationPolicy&lt;/code&gt; temos definidos estas regras da seguinte maneira.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create?&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;new?&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;create?&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Ou seja &lt;code class=&quot;highlighter-rouge&quot;&gt;new?&lt;/code&gt; executa o &lt;code class=&quot;highlighter-rouge&quot;&gt;create?&lt;/code&gt; então devido ao poder da herança definimos apenas o &lt;code class=&quot;highlighter-rouge&quot;&gt;create?&lt;/code&gt; em nossa classe filha. Este é um bom caso para o uso de herança, &lt;a href=&quot;http://groselhas.maurogeorge.com.br/prefira-composicao-ao-inves-de-heranca-um-simples-exemplo-em-ruby.html&quot;&gt;mas não se esqueça que composição tem um papel muito importante também quando estamos falando de orientação a objetos&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Em seguida definimos as demais policies da nossa company.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CompanyPolicy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ApplicationPolicy&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;update?&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;manager?&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;destroy?&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;manager?&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Sem nada de novo aqui.&lt;/p&gt;

&lt;h2 id=&quot;aplicando-nossa-policy&quot;&gt;Aplicando nossa policy&lt;/h2&gt;

&lt;p&gt;Agora com nossa policy criada vamos a nosso controller de company aplicá-la. Para isso simplesmente utilizamos do método &lt;code class=&quot;highlighter-rouge&quot;&gt;authorize&lt;/code&gt; e passamos o objeto que estamos testando.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;
  &lt;span class=&quot;vi&quot;&gt;@company&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Company&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;authorize&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@company&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Não se esqueça de aplicar a policy para todas as actions que quer proteger.&lt;/p&gt;

&lt;p&gt;Agora temos nossas actions protegidas, qualquer um que tentar acessar alguma dessas actions e não tiver permissão receberá uma excessão &lt;code class=&quot;highlighter-rouge&quot;&gt;Pundit::NotAuthorizedError&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Protegemos o nosso controller, mas também não queremos links espalhados pelo sistema que levem a uma página de erro o ideal é esconde-los. Para isso vamos ao helper do pundit.&lt;/p&gt;

&lt;h2 id=&quot;aplicando-nossa-policy-na-view&quot;&gt;Aplicando nossa policy na view&lt;/h2&gt;

&lt;p&gt;O Pundit nos oferece o helper &lt;code class=&quot;highlighter-rouge&quot;&gt;policy&lt;/code&gt; para utilizarmos na view para checarmos alguma policy. Para checarmos a exibição do link de criar por exemplo, fazemos assim.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;policy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Company&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new?&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;link_to&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;Nova empresa&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new_company_path&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Passamos apenas a classe dado que não estamos referenciando nenhum registro. Na listagem passamos o proprio objeto para o Pundit.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;policy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;company&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;update?&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;td&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;link_to&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;Editar&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;edit_company_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;company&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;O legal do passarmos um objeto para dentro do Pundit, é que podemos por exemplo exibir o link de editar apenas para o gerente e em que a empresa tenha sido homologada por exemplo.&lt;/p&gt;

&lt;h2 id=&quot;por-uma-boa-mensagem-de-erro&quot;&gt;Por uma boa mensagem de erro&lt;/h2&gt;

&lt;p&gt;Até o momento caso algum usuário acesso alguma das actions em que ele não tem permissão ele recebe apenas uma excessão, o que se torna um erro 500 em produção, e não queremos isso. Então vamos tratar esta excessão para exibirmos uma boa mensagem de erro.&lt;/p&gt;

&lt;p&gt;No nosso &lt;code class=&quot;highlighter-rouge&quot;&gt;ApplicationController&lt;/code&gt; resgatamos da excessão e redirecionamos o usuário com uma mensagem de erro.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ApplicationController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActionController&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;rescue_from&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Pundit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;NotAuthorizedError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;with: :user_not_authorized&lt;/span&gt;

  &lt;span class=&quot;kp&quot;&gt;private&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;user_not_authorized&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;flash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;Você não tem permissão para fazer esta ação&#39;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;redirect_to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;referrer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Agora o usuário recebe uma melhor mensagem de erro.&lt;/p&gt;

&lt;h2 id=&quot;concluso&quot;&gt;Conclusão&lt;/h2&gt;

&lt;p&gt;O Pundit é uma boa alternativa ao CanCan, no entanto utilizando de objetos Ruby sem nenhuma DSL ou nada &lt;em&gt;fancy&lt;/em&gt;.
Não entrei no mérito dos testes para não alongar demais o post, mas o Pundit possui uma integração com o &lt;a href=&quot;https://github.com/elabs/pundit#rspec&quot;&gt;RSpec&lt;/a&gt; o que facilita bastante a nossa vida.
Não deixe de experimentá-lo e tirar suas próprias conclusões.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/lancamento-do-livro-rspec-crie-especificacoes-executaveis-em-ruby</id>
   <title>Lançamento do Livro RSpec: Crie especificações executáveis em Ruby</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/lancamento-do-livro-rspec-crie-especificacoes-executaveis-em-ruby.html"/>
   <updated>2014-07-29T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Há um tempo escrevi que estava &lt;a href=&quot;/rspec-best-friends-meu-primeiro-e-book.html&quot;&gt;começando a escrever um e-book&lt;/a&gt; e hoje é hora de anunciar que finalizei o livro e ele foi lançado hoje pela &lt;a href=&quot;http://www.casadocodigo.com.br/products/livro-rspec&quot;&gt;Casa do Código&lt;/a&gt; \o/.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.casadocodigo.com.br/products/livro-rspec&quot;&gt;&lt;img src=&quot;/images/posts/2014-07-29/rspec-ebook.png&quot; alt=&quot;Livro RSpec: Crie especificações executáveis em Ruby&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;e-com-isso-o-que-muda-da-proposta-original&quot;&gt;E com isso o que muda da proposta original?&lt;/h2&gt;

&lt;p&gt;Não poderei disponibilizar uma versão gratuita, que eu planejava enquanto eu estava trabalhando sozinho e ainda não fazia ideia de como publicar o mesmo.&lt;/p&gt;

&lt;p&gt;No entanto em relação ao conteúdo nada foi alterado, tive total flexibilidade para escrever o quanto eu quisesse. Com a vantagem de ter a revisão e instrução dos editores da Casa do Código. E mais, agora teremos uma versão impressa e em diversos formatos digitais.&lt;/p&gt;

&lt;p&gt;Ou seja com esta parceria com a &lt;a href=&quot;http://www.casadocodigo.com.br/&quot;&gt;Casa do Código&lt;/a&gt; o livro só teve a ganhar, primeiro pela edição e revisão de uma equipe de profissionais e na publicação que eu não tive que me preocupar em como iria fazer, assim pude deixar este trabalho para quem já está no mercado fazendo isso no dia a dia.&lt;/p&gt;

&lt;p&gt;Outra parceria que foi firmada no caminho foi com a &lt;a href=&quot;http://helabs.com.br&quot;&gt;HE:labs&lt;/a&gt; que me cedeu algumas horas por semana do meu trabalho para me dedicar ao livro, o que ajudou bastante no andamento &amp;lt;3&lt;/p&gt;

&lt;p&gt;É isso pessoal espero que gostem do conteúdo do livro, &lt;a href=&quot;http://www.casadocodigo.com.br/products/livro-rspec&quot;&gt;não deixe de conferir&lt;/a&gt;!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/flexibilidade-na-criacao-de-metodos-com-named-parameters</id>
   <title>Flexibilidade na criação de métodos com named parameters</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/flexibilidade-na-criacao-de-metodos-com-named-parameters.html"/>
   <updated>2014-07-08T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Temos que calcular o frete de um produto para isso temos que saber qual a sua altura, largura, profundidade, preço e peso deve ser possivel selecionar qual a unidade de medidas que enviaremos a informação.&lt;/p&gt;

&lt;p&gt;Para resolver este problema criaremos uma classe que recebe estas opções. Como são diversas opções utilizaremos um hash, para não precisarmos ficar dependendo da ordem dos paramêtros.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ShippingCalculator&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;kp&quot;&gt;private&lt;/span&gt;

    &lt;span class=&quot;kp&quot;&gt;attr_reader&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:options&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Nosso método &lt;code class=&quot;highlighter-rouge&quot;&gt;call&lt;/code&gt; simplesmente retorna os paramêtros apenas para a simplicidade do exemplo, também não nos preocupamos em checar a presença dos valores. Nosso exemplo funciona e é um padrão adotado pela comunidade Ruby.&lt;/p&gt;

&lt;p&gt;Percebemos que é muito comum definirmos o paramêtro &lt;code class=&quot;highlighter-rouge&quot;&gt;unit&lt;/code&gt; sempre com o valor &lt;code class=&quot;highlighter-rouge&quot;&gt;:metric&lt;/code&gt; para utilizar a unidade de medida métrica. Então vamos definir isto como padrão da nossa classe.
Para isso criamos uma constante com o valor como padrão e o juntamos com os paramêtros passados.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ShippingCalculator&lt;/span&gt;

  &lt;span class=&quot;nc&quot;&gt;DEFAULT_OPTIONS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;unit: :metric&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DEFAULT_OPTIONS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;merge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Legal! Agora não precisamos mais ficar passando o &lt;code class=&quot;highlighter-rouge&quot;&gt;unit&lt;/code&gt; apenas quando formos utilizar outro sistema de medida que não seja o métrico.&lt;/p&gt;

&lt;p&gt;A partir do Ruby &lt;a href=&quot;https://www.ruby-lang.org/en/news/2013/02/24/ruby-2-0-0-p0-is-released/&quot;&gt;Ruby 2.0.0&lt;/a&gt; foi incluido o suporte a &lt;em&gt;named parameters&lt;/em&gt; o que nos permite declarar paramêtros nomeados que é exatamente como fizemos no exemplo anterior com o hash. Vamos alterar o nosso código parar utilizar do named parameter.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ShippingCalculator&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;unit: :metric&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;unit: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Como pode ver temos acesso ao paramêtro passado diretamente, simplesmente o adicionamos a um hash para mantermos o nosso retorno.
No entanto no Ruby 2.0.0 para definirmos os named parameter temos que definir todos com um valor padrão. Se tentarmos passar o atributo &lt;code class=&quot;highlighter-rouge&quot;&gt;weight&lt;/code&gt; por exemplo receberemos uma exceção &lt;code class=&quot;highlighter-rouge&quot;&gt;unknown keyword: weight (ArgumentError)&lt;/code&gt; dado que ele não foi declarado.&lt;/p&gt;

&lt;p&gt;Para não precisarmos ter que definir um valor padrão para cada um dos atributos podemos receber mais opções utilizando do &lt;code class=&quot;highlighter-rouge&quot;&gt;**&lt;/code&gt; e juntarmos estas opções com os paramêtros que definimos no named parameter.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ShippingCalculator&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;unit: :metric&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;unit: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;merge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;A partir do &lt;a href=&quot;https://github.com/ruby/ruby/blob/v2_1_0/NEWS&quot;&gt;Ruby 2.1.0&lt;/a&gt; foi removida esta necessidade de todos os named parameter ter que ter um valor padrão. Alteramos nosso exemplo para aceitar cada um dos named params.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ShippingCalculator&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;unit: :metric&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lenght&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;unit: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;weight: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;weight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;lenght: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lenght&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;width: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                 &lt;span class=&quot;ss&quot;&gt;height: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;price: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Sei que você vai me dizer que este código é mais verboso do que aquele que fizemos com o Ruby 2.0 certo? Concordo, no entanto aqui ganhamos de bônus estes paramêtros serem requeridos, que foi uma parte da nossa classe que não implementamos, no entanto não queremos que seja possivel realizar um cálculo de frete sem o peso certo? Agora será lançada uma exceção &lt;code class=&quot;highlighter-rouge&quot;&gt;ArgumentError&lt;/code&gt; informando os paramêtros que não foram enviados.&lt;/p&gt;

&lt;p&gt;Lembrando que além do named parameter, que pode ter seu valor padrão definido ou não, podemos fazer como no exemplo do Ruby 2.0 e aceitar paramêtros extras.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ShippingCalculator&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;unit: :metric&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lenght&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;unit: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;weight: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;weight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;lenght: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lenght&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;width: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                 &lt;span class=&quot;ss&quot;&gt;height: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;price: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;merge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

   &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;É muito legal ver um padrão criado pela comunidade ser adotado como funcionalidade da linguagem. Como pode ver temos uma grande flexibilidade quando vamos definir paramêtros para os nossos métodos.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/removendo-hash-driven-development-com-struct-e-open-struct</id>
   <title>Removendo hash-driven development com Struct e OpenStruct</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/removendo-hash-driven-development-com-struct-e-open-struct.html"/>
   <updated>2014-07-06T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Temos que criar uma classe que exiba as informações de um Pokémon baseado no seu &lt;a href=&quot;http://bulbapedia.bulbagarden.net/wiki/List_of_Pok%C3%A9mon_by_National_Pok%C3%A9dex_number&quot;&gt;id nacional&lt;/a&gt; consumindo estes valores de uma API. Para isso simplesmente acessamos a API e parseamos a resposta do JSON a retornando por completo.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FetchPokemon&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;national_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@national_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;national_id&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;build_info&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;kp&quot;&gt;private&lt;/span&gt;

    &lt;span class=&quot;kp&quot;&gt;attr_reader&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:national_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:info&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;endpoint&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;http://pokeapi.co/api/v1/pokemon/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;national_id&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;build_info&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Net&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HTTP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;vi&quot;&gt;@info&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Este código atende a nossa necessidade mais podemos melhorar o seu retorno, pois hoje precisamos apenas do nome, altura e peso. Então vamos alterar o nosso método &lt;code class=&quot;highlighter-rouge&quot;&gt;call&lt;/code&gt; para retornar apenas estes atributos do &lt;code class=&quot;highlighter-rouge&quot;&gt;info&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FetchPokemon&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;name: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;name&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;height: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;height&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;weight: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;weight&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Agora temos apenas as informações que necessitamos. No entanto seria melhor se tivessemos um objeto &lt;code class=&quot;highlighter-rouge&quot;&gt;Pokemon&lt;/code&gt; e não um hash, com um objeto sabemos exatamente com que estamos lidando, qual a entidade. E assim evitamos o &lt;em&gt;hash-driven development&lt;/em&gt; e utilizamos uma abordagem orientada a objetos.&lt;/p&gt;

&lt;p&gt;Para isso criamos uma &lt;a href=&quot;http://en.wikipedia.org/wiki/Inner_class&quot;&gt;&lt;em&gt;inner class&lt;/em&gt;&lt;/a&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;Pokemon&lt;/code&gt; que define exatamente os atributos que precisamos e os expõe através de um &lt;code class=&quot;highlighter-rouge&quot;&gt;attr_accessor&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FetchPokemon&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Pokemon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;name&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;height&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;weight&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;kp&quot;&gt;private&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Pokemon&lt;/span&gt;

      &lt;span class=&quot;kp&quot;&gt;attr_accessor&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:weight&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;vi&quot;&gt;@name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@weight&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weight&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Não se esqueça que uma &lt;a href=&quot;http://blog.elpassion.com/ruby-gotchas/&quot;&gt;inner class possui o comportamento diferente de quando estamos utilizando módulos como &lt;em&gt;namespace&lt;/em&gt;&lt;/a&gt;. No nosso caso não é um problema dado que estamos utilizando a classe &lt;code class=&quot;highlighter-rouge&quot;&gt;Pokemon&lt;/code&gt; apenas como um container, não nos importamos com nada declarado na classe &lt;code class=&quot;highlighter-rouge&quot;&gt;FetchPokemon&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora nossa classe &lt;code class=&quot;highlighter-rouge&quot;&gt;FetchPokemon&lt;/code&gt; retorna um &lt;code class=&quot;highlighter-rouge&quot;&gt;FetchPokemon::Pokemon&lt;/code&gt; no método &lt;code class=&quot;highlighter-rouge&quot;&gt;call&lt;/code&gt;, bem legal. No entanto estamos repetindo 3 vezes cada atributo na declaração da classe.&lt;/p&gt;

&lt;p&gt;Para remover esta repetição podemos criar um &lt;a href=&quot;http://www.ruby-doc.org/core-2.1.2/Struct.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Struct&lt;/code&gt;&lt;/a&gt; que faz exatamente o que precisamos: cria &lt;em&gt;accessors&lt;/em&gt; para cada um dos atributos passados no &lt;code class=&quot;highlighter-rouge&quot;&gt;initialize&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FetchPokemon&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Pokemon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;name&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;height&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;weight&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;kp&quot;&gt;private&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;no&quot;&gt;Pokemon&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:weight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Continuamos com o &lt;code class=&quot;highlighter-rouge&quot;&gt;FetchPokemon::Pokemon&lt;/code&gt; como classe no entanto removemos a repetição ao se declarar a classe &lt;code class=&quot;highlighter-rouge&quot;&gt;Pokemon&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;openstruct&quot;&gt;OpenStruct&lt;/h2&gt;

&lt;p&gt;Para casos em que desejamos transformar um hash completo em um objeto temos o &lt;a href=&quot;http://www.ruby-doc.org/stdlib-2.1.2/libdoc/ostruct/rdoc/OpenStruct.html&quot;&gt;OpenStruct&lt;/a&gt;. Voltando lá no inicio quando tínhamos um hash reduzido com apenas as informações que precisamos podemos criar uma classe &lt;code class=&quot;highlighter-rouge&quot;&gt;Pokemon&lt;/code&gt; a partir dele utilizando do &lt;code class=&quot;highlighter-rouge&quot;&gt;OpenStruct&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para isso criamos uma classe &lt;code class=&quot;highlighter-rouge&quot;&gt;Pokemon&lt;/code&gt; que herda de &lt;code class=&quot;highlighter-rouge&quot;&gt;OpenStruct&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FetchPokemon&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Pokemon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;name: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;name&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;height: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;height&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;weight: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;weight&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;kp&quot;&gt;private&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Pokemon&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;OpenStruct&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Seja utilizando o &lt;code class=&quot;highlighter-rouge&quot;&gt;Struct&lt;/code&gt; ou o &lt;code class=&quot;highlighter-rouge&quot;&gt;OpenStruct&lt;/code&gt; teremos um objeto &lt;code class=&quot;highlighter-rouge&quot;&gt;FetchPokemon::Pokemon&lt;/code&gt; a diferença é que um será herdado de &lt;code class=&quot;highlighter-rouge&quot;&gt;Struct&lt;/code&gt; e outro de &lt;code class=&quot;highlighter-rouge&quot;&gt;OpenStruct&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;fetch_pokemon&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FetchPokemon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pokemon&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fetch_pokemon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; #&amp;lt;FetchPokemon::Pokemon name=&quot;Charizard&quot;, height=&quot;17&quot;, weight=&quot;905&quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pokemon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;                 &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;Charizard&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Com este refactoring saimos de um hash para uma entidade Pokémon, que deixa claro o que é aquele objeto. Afinal um hash que tem informações de um pokémon é um pokémon, então deixe isso explícito.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/rails-e-o-development-seed</id>
   <title>Rails e o Development Seed</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/rails-e-o-development-seed.html"/>
   <updated>2014-07-05T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Você mudou de equipe e começou em um projeto novo, rodou bundle, migrate e iniciou o servidor. Criou uma conta neste novo sistema e… WTF este sistema faz?&lt;/p&gt;

&lt;p&gt;É comum o projeto depender de algumas(muitas) informações para ele começar a mostrar estas informações ao invés de um monte de &lt;a href=&quot;http://patternry.com/p=blank-slate/&quot;&gt;&lt;em&gt;blank slates&lt;/em&gt;&lt;/a&gt;. Algumas destas informações algumas vezes são cadastradas apenas pela área administrativa do sistema. Como podemos deixar mais fácil a entrada de novos membros em um novo projeto?&lt;/p&gt;

&lt;p&gt;No Rails podemos definir o nosso &lt;em&gt;seed&lt;/em&gt; em &lt;code class=&quot;highlighter-rouge&quot;&gt;db/seeds.rb&lt;/code&gt;. Mas como queremos que nosso seed seja carregado apenas em desenvolvimento vamos criar um arquivo especifico para ele em &lt;code class=&quot;highlighter-rouge&quot;&gt;db/seeds/development.rb&lt;/code&gt;. Este arquivo não é carregado por padrão quando rodamos nosso seed, para fazer isso simplesmente o carregamos no nosso seed quando o ambiente for &lt;em&gt;development&lt;/em&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# db/seeds.rb&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;development?&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;require_relative&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;seeds/development&#39;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;E agora simplesmente criamos o nosso seed.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# db/seeds/development.rb&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_posts_to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;total_of_posts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;total_of_posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;times&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;create!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;title: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Post &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; from &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                       &lt;span class=&quot;ss&quot;&gt;content: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Content of post &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;any?&lt;/span&gt;

  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Creating User &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;create!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;name: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;User &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;email: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;user&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;@example.com&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;any?&lt;/span&gt;

  &lt;span class=&quot;no&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Creating posts to user &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;create_posts_to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Como queremos que o seed seja executado apenas quando não tivermos estas informações verificamos por elas antes de criarmos utilizando o &lt;code class=&quot;highlighter-rouge&quot;&gt;any?&lt;/code&gt;. Criamos um pequeno método para gerar os posts, pois assim cada usuário não terá sempre o mesmo número de post para isso utilizamos o &lt;code class=&quot;highlighter-rouge&quot;&gt;rand&lt;/code&gt;. E como dica sempre use métodos que lance uma exceção em caso de erro pois se alguma validação falhar por exemplo temos o feedback mais rápido.&lt;/p&gt;

&lt;p&gt;Seguindo esta prática você está ajudando a:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Novas pessoas que entrarem no projeto&lt;/li&gt;
  &lt;li&gt;Você mesmo quando precisar reiniciar o banco de dados ou trocar de máquina&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lembrando que sempre temos que revisitar estes seeds pois novos campos são adicionados no banco, novas validações e mesmo novos models que ainda não foram criados. Podemos revisitá-los quando rodamos o seed em algum momento ou quando uma nova pessoa entra no projeto e sente falta de alguma informação. Ela já pode contribuir gerando esta informação no seed.&lt;/p&gt;

&lt;p&gt;Aprendi esta técnica enquanto trabalhava com o &lt;a href=&quot;https://twitter.com/fgrehm&quot;&gt;Fábio&lt;/a&gt; =)&lt;/p&gt;

&lt;p&gt;Pode parecer uma boa ideia utilizar FactoryGirl, mas não é ;p &lt;a href=&quot;http://robots.thoughtbot.com/factory_girl-for-seed-data&quot;&gt;saiba mais aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Caso queira dados “mais reais” pode utilizar o &lt;a href=&quot;https://github.com/stympy/faker&quot;&gt;faker&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Precisando de uma solução mais complexa de uma olhada no &lt;a href=&quot;https://github.com/james2m/seedbank&quot;&gt;seedbank&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/placehold-de-imagens-com-o-placehold-it</id>
   <title>Placehold de imagens com o placehold.it</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/placehold-de-imagens-com-o-placehold-it.html"/>
   <updated>2014-07-02T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Quando estamos fazendo o nosso Front-end é comum ter momentos onde ainda não termos o upload de imagem funcionando por exemplo e temos que exibir uma imagem padrão. Para evitar o processo de criar uma imagem no Photoshop com as medidas exatas podemos utilizar o &lt;a href=&quot;http://placehold.it/&quot;&gt;placehold.it&lt;/a&gt; que gera uma imagem para nós.&lt;/p&gt;

&lt;p&gt;Para termos um resultado como o:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://placehold.it/350x150&quot; alt=&quot;Placeholder de 350x150&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Simplesmente criamos uma imagem utilizando o placehold.it da seguinte maneira.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;img&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;alt=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Placeholder de 350x150&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://placehold.it/350x150&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Por padrão o formato é gif, podemos alterar simplesmente passando o formato.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;img&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;alt=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Placeholder de 350x150&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://placehold.it/350x150.png&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Podemos passar um texto qualquer para ser renderizado, passando o parametro &lt;code class=&quot;highlighter-rouge&quot;&gt;text&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;img&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;alt=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Placeholder de 350x150&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://placehold.it/350x150.png&amp;amp;text=Mauro&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Podemos customizar a cor do background e do texto, passando os paramêtros nessa ordem.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;img&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;alt=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Placeholder de 350x150&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://placehold.it/350x150.png/ffffff/000000&amp;amp;text=Mauro&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;As cores devem ser definidas sempre depois das dimensões.&lt;/p&gt;

&lt;p&gt;Fica aí com mais uma ferramenta para ajudar no desenvolvimento Front-end.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/good-bye-jacaranda-and-welcome-activerecord-enum</id>
   <title>Good Bye Jacaranda and welcome ActiveRecord::Enum</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/good-bye-jacaranda-and-welcome-activerecord-enum.html"/>
   <updated>2013-12-29T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;A time ago I want to create a Gem to learn how this works. But in the Ruby/Rails world we live in a mature community when we have a lot of libs to do our job, so  I give up for a moment, until I have a problem that more people have experiencied too.&lt;/p&gt;

&lt;p&gt;So in a moment I find a pattern, that I and my friends do. When I have a model, with validation of inclusion like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;validates&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;inclusion: &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;in: &lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;%w{published unpublished draft}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I normally need predicate methods like &lt;code class=&quot;highlighter-rouge&quot;&gt;@post.published?&lt;/code&gt; and scopes like &lt;code class=&quot;highlighter-rouge&quot;&gt;Post.published&lt;/code&gt;. So by this idea and some work born &lt;a href=&quot;https://github.com/maurogeorge/jacaranda&quot;&gt;Jacaranda&lt;/a&gt; my first gem.&lt;/p&gt;

&lt;p&gt;But now in the rails 4.1.0, I testing using 4.1.0.beta1 since no release yet. We have the &lt;a href=&quot;http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html&quot;&gt;ActiveRecord::Enum &lt;/a&gt; that can do the same thing we do with Jacaranda.&lt;/p&gt;

&lt;h2 id=&quot;meeting-the-activerecordenum&quot;&gt;Meeting the ActiveRecord::Enum&lt;/h2&gt;

&lt;p&gt;Lets create the same behavior of Jacaranda now using the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Enum&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;migration&quot;&gt;Migration&lt;/h3&gt;

&lt;p&gt;We started with a migration like this.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CreatePosts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Migration&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;change&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;create_table&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:posts&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:title&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;integer&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;default: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;timestamps&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The important part is the column is a integer and we set the default value as 0.&lt;/p&gt;

&lt;h3 id=&quot;model&quot;&gt;Model&lt;/h3&gt;

&lt;p&gt;In our model we simply use the macro &lt;code class=&quot;highlighter-rouge&quot;&gt;enum&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;status: &lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;%w(published unpublished draft)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;in-the-wild&quot;&gt;In the Wild&lt;/h3&gt;

&lt;h4 id=&quot;predicate-methods&quot;&gt;Predicate methods&lt;/h4&gt;

&lt;p&gt;We start with a post with status is &lt;code class=&quot;highlighter-rouge&quot;&gt;published&lt;/code&gt;. Remember you need to pass to the model the string and not integer, a &lt;code class=&quot;highlighter-rouge&quot;&gt;ArgumentError&lt;/code&gt; is raised if you try pass the integer value.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;title: &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;Post title&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;status: &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;published&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;first&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;published?&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# true&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;draft?&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# false&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;scopes&quot;&gt;Scopes&lt;/h4&gt;

&lt;p&gt;We can use the scopes with the same name as declareted on our model.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;published&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# SELECT &quot;posts&quot;.* FROM &quot;posts&quot;  WHERE &quot;posts&quot;.&quot;status&quot; = 0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Search is made using the integer value on the database.&lt;/p&gt;

&lt;h4 id=&quot;the-bang&quot;&gt;The bang!&lt;/h4&gt;

&lt;p&gt;The bang are not in Jacaranda, but are cool =)&lt;/p&gt;

&lt;p&gt;You can use the bang method to change the status of post.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;draft!&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &quot;draft&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now our post have the status as a draft.&lt;/p&gt;

&lt;p&gt;One cool thing about the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Enum&lt;/code&gt; is that all values are stored like a integer and accessed as a string.&lt;/p&gt;

&lt;h4 id=&quot;using-explicit-mapping&quot;&gt;Using explicit mapping&lt;/h4&gt;

&lt;p&gt;Add status without key can be annoying since if one new status is added in a wrong position all objects have values changed.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;status: &lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;%w(reviewed published unpublished draft)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We add reviewed before the published, so now all published posts have the status as reviewed.&lt;/p&gt;

&lt;p&gt;To avoid this problem, we can use the explicit mapping like.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;status: &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;published: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;unpublished: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;draft: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;reviwed: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This way we dont care about the order but with the value.&lt;/p&gt;

&lt;p&gt;Of course good specs ensure we are adding a thing that dont break others.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Jacaranda is now deprecated, since we can use the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Enum&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I learned a lot in the way using services like:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://rubygems.org&quot;&gt;RubyGems&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://travis-ci.org&quot;&gt;Travis CI&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://coveralls.io&quot;&gt;Coveralls&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://codeclimate.com&quot;&gt;Code Climate&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://gemnasium.com&quot;&gt;Gemnasium&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I used the &lt;a href=&quot;http://semver.org&quot;&gt;Semantic Versioning&lt;/a&gt;. I learned how hard is the work to maintain a Gem. I started &lt;a href=&quot;https://github.com/maurogeorge&quot;&gt;work in others open source projects&lt;/a&gt;. And is so enjoyable know that I was in the right direction =)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/criando-um-ambiente-de-staging-no-heroku-para-nossa-rails-app</id>
   <title>Criando um ambiente de staging no heroku para nossa rails app</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/criando-um-ambiente-de-staging-no-heroku-para-nossa-rails-app.html"/>
   <updated>2013-11-21T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;É uma boa prática termos um ambiente que rode no heroku, mas que não seja o ambiente de produção, este ambiente é chamado de staging, um ambiente que é o mais proximo de produção.&lt;/p&gt;

&lt;p&gt;Primeiro temos que criar uma app de staging no heroku, dado que nossa app tenha o nome de &lt;code class=&quot;highlighter-rouge&quot;&gt;myapp&lt;/code&gt; crie uma heroku app com o nome de &lt;code class=&quot;highlighter-rouge&quot;&gt;myapp-staging&lt;/code&gt; para isto podemos utilizar do &lt;a href=&quot;https://devcenter.heroku.com/articles/fork-app&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;heroku fork&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;heroku fork -a myapp myapp-staging&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Primeiro temos que dizer ao rails que temos um ambiente de staging para isso temos que criar o &lt;code class=&quot;highlighter-rouge&quot;&gt;config/environments/staging.rb&lt;/code&gt;. Simplesmente cria o arquivo &lt;code class=&quot;highlighter-rouge&quot;&gt;config/environments/staging.rb&lt;/code&gt; com o mesmo conteúdo do &lt;code class=&quot;highlighter-rouge&quot;&gt;config/environments/production.rb&lt;/code&gt; apenas trocando o &lt;code class=&quot;highlighter-rouge&quot;&gt;log_level&lt;/code&gt; para &lt;code class=&quot;highlighter-rouge&quot;&gt;:debug&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;Myapp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;configure&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;log_level&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:debug&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;No heroku agora utilizamos a gem &lt;a href=&quot;https://devcenter.heroku.com/articles/rails4#logging-and-assets&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;rails_12factor&lt;/code&gt;, no entanto ele apenas recomenda o uso em &lt;code class=&quot;highlighter-rouge&quot;&gt;:production&lt;/code&gt;&lt;/a&gt;, devemos incluir o nosso ambiente de staging aqui também no nosso Gemfile.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;rails_12factor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;0.0.2&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;group: &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:production&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:staging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Como este ambiente é um ambiente para apenas os usuários que desejamos visualizar, como os colaboradores do nosso sistema, colocamos um basic auth apenas no ambiente de staging.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ApplicationController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActionController&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;#...&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;http_basic_authenticate_with&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:password&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;secret&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;staging?&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Para finalizar definimos as variaveis de ambiente no heroku, devemos definir o &lt;code class=&quot;highlighter-rouge&quot;&gt;RACK_ENV&lt;/code&gt; e o &lt;code class=&quot;highlighter-rouge&quot;&gt;RAILS_ENV&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;heroku config:set &lt;span class=&quot;nv&quot;&gt;RACK_ENV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;staging &lt;span class=&quot;nv&quot;&gt;RAILS_ENV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;staging --app myapp-staging&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Caso estejamos utilizando serviços como Amazon S3, Facebook etc. É uma boa pratica termos um bucket exclusivo de staging no caso da S3 e uma app do facebook para staging, assim como qualquer outro serviço que estejamos utilizando.&lt;/p&gt;

&lt;p&gt;Adicione as variaveis de ambiente destes serviços como S3(&lt;code class=&quot;highlighter-rouge&quot;&gt;AMAZON_S3_BUCKET&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;AMAZON_ACCESS_KEY_ID&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;AMAZON_SECRET_ACCESS_KEY&lt;/code&gt;), Facebook(&lt;code class=&quot;highlighter-rouge&quot;&gt;FACEBOOK_APP_KEY&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;FACEBOOK_APP_SECRET&lt;/code&gt;) e qualquer outra variável de ambiente necessária para a sua app funcionar.&lt;/p&gt;

&lt;p&gt;Deste modo temos uma app que é bem próxima de produção, assim reduzimos a chance de termos alguma surpresa desagradável.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/rspec-best-friends-meu-primeiro-e-book</id>
   <title>RSpec Best Friends meu primeiro e-book</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/rspec-best-friends-meu-primeiro-e-book.html"/>
   <updated>2013-11-10T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Sim, estou escrevendo um e-book =) Seguindo a sugestão do meu amigo &lt;a href=&quot;http://www.yogodoshi.com/&quot;&gt;Cayo&lt;/a&gt;, vou compartilhar com a comunidade a minha ideia.&lt;/p&gt;

&lt;p&gt;A ideia é falar sobre o ecossistema que existe em volta do RSpec, e como isso agiliza o trabalhao do dia a dia.
Não é um e-book para iniciante mais para quem já sabe usar o RSpec no dia a dia é quer aprender técnicas para melhorar e agilizar o processo de BDD.&lt;/p&gt;

&lt;p&gt;Os tópicos que falarei:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;factory_girl&lt;/li&gt;
  &lt;li&gt;shoulda-matchers&lt;/li&gt;
  &lt;li&gt;webmock&lt;/li&gt;
  &lt;li&gt;vcr&lt;/li&gt;
  &lt;li&gt;email_spec&lt;/li&gt;
  &lt;li&gt;timecop&lt;/li&gt;
  &lt;li&gt;rspec-sidekiq&lt;/li&gt;
  &lt;li&gt;simplecov&lt;/li&gt;
  &lt;li&gt;mongoid-rspec&lt;/li&gt;
  &lt;li&gt;mock/stub&lt;/li&gt;
  &lt;li&gt;factory_girl-preload&lt;/li&gt;
  &lt;li&gt;gems com matchers, como paperclip&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Até o momento tenho ~30 páginas escritas sobre o mongoid-rspec. Eu estava pensando em ter um e-book de aproximadamente 100 páginas, mas pelo jeito isto vai crescer.&lt;/p&gt;

&lt;p&gt;Mas ainda assim acho que não será uma leitura massante devido a maioria dos capítulos poder ser usado como um guia de consulta rápida. E aparentemente não terá uma ordem lógica de leitura.&lt;/p&gt;

&lt;p&gt;Estou usando como ferramenta o &lt;a href=&quot;https://github.com/fnando/kitabu&quot;&gt;kitabu&lt;/a&gt; do &lt;a href=&quot;http://simplesideias.com.br/&quot;&gt;Nando&lt;/a&gt;. Ainda não parei para estilizar nada apenas estou gerando um pdf no modo default mesmo.&lt;/p&gt;

&lt;p&gt;No momento estou focado em apenas escrever o e-book, não pensando em publicação ou qualquer outra coisa. Mas a principio penso lança-lo como foi lançado o &lt;a href=&quot;http://objectsonrails.com&quot;&gt;Objects on Rails&lt;/a&gt; uma versão online de graça e uma versão paga com PDF, epub, mobi etc.&lt;/p&gt;

&lt;p&gt;Para finalizar deixo um &lt;a href=&quot;https://docs.google.com/forms/d/1gnt5QfG146fn7nLZLKMh4W2JBfRKvBhiUXnEKNKkD68/viewform&quot;&gt;form para quem quiser ajudar o projeto&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/duvidas-comuns-do-rvm</id>
   <title>Dúvidas comuns do RVM</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/duvidas-comuns-do-rvm.html"/>
   <updated>2013-10-10T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Dúvidas que algum dia você já teve, ou terá enquanto utiliza o &lt;a href=&quot;https://rvm.io/&quot;&gt;RVM&lt;/a&gt;, respondidas aqui.&lt;/p&gt;

&lt;h2 id=&quot;qual-o-ruby-e-o-gemset-que-estou-atualmente&quot;&gt;Qual o ruby e o gemset que estou atualmente?&lt;/h2&gt;

&lt;p&gt;Utilizamos o current quando queremos saber qual o ruby e versão estamos utilizando atualmente.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;rvm current&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;como-defino-um-gemset-como-default&quot;&gt;Como defino um gemset como default?&lt;/h2&gt;

&lt;p&gt;Para definirmos um gemset como default usamos o seguinte comando:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;rvm  --default use 2.0.0@global&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;é uma boa prática definir o &lt;code class=&quot;highlighter-rouge&quot;&gt;@global&lt;/code&gt; como gemset padrão.&lt;/p&gt;

&lt;h2 id=&quot;como-fao-para-criar-e-usar-um-gemset&quot;&gt;Como faço para criar e usar um gemset?&lt;/h2&gt;

&lt;p&gt;Parar criar e já sair usando um gemset utilize o seguinte comando:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;rvm use 2.0.0@rails --create&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;este eu utilizo muito para começar a trabalhar em projetos open source =)&lt;/p&gt;

&lt;h2 id=&quot;como-fao-para-utilizar-um-gemset&quot;&gt;Como faço para utilizar um gemset?&lt;/h2&gt;

&lt;p&gt;Parar usar um gemset utilize o seguinte comando:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;rvm use 2.0.0@rails&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;também muito utilizado para trabalhar com open source, dado que muito dos projetos não colocam em seus repos o &lt;code class=&quot;highlighter-rouge&quot;&gt;.ruby-version&lt;/code&gt; e &lt;code class=&quot;highlighter-rouge&quot;&gt;.ruby-gemset&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;como-fao-para-ver-os-gemsets-criados&quot;&gt;Como faço para ver os gemsets criados?&lt;/h2&gt;

&lt;p&gt;Para listar os gemsets utilizamos o seguinte comando:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;rvm gemset list&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;como-fao-para-remover-todas-as-gems-de-um-gemset&quot;&gt;Como faço para remover todas as gems de um gemset?&lt;/h2&gt;

&lt;p&gt;Para remover todas as gems de um gemset rode:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;rvm gemset empty my_gemset&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/como-saber-qual-a-ultima-versao-de-uma-gem-no-rubygems</id>
   <title>Como saber qual a última versão de uma gem no Rubygems</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/como-saber-qual-a-ultima-versao-de-uma-gem-no-rubygems.html"/>
   <updated>2013-10-10T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Quando queremos instalar uma nova gem é comum procurarmos em qual versão a Gem se encontra atualmente. Podemos obter este valor das seguintes maneiras:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;acessando o Readme e procuramos a versão, isso se o autor se importou em colocar este valor lá;&lt;/li&gt;
  &lt;li&gt;Rubygems, &lt;a href=&quot;https://rubygems.org/gems/jacaranda&quot;&gt;exemplo&lt;/a&gt;;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;nenhum dos 2 modos é muito prático, para ambos você deve sair do terminal para ir atrás destes valores. O que eu uso e recomendo é o seguinte comando do Rubygems:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;gem list jacaranda -r&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;ele retorna uma lista com a gem e sua ultima versão estável.&lt;/p&gt;

&lt;p&gt;Claro que isso não quer dizer que não tenhamos sempre que ler o Readme, e Changelog das gems para sabermos como funciona, instalamos etc. Mas ajuda em uma gem que costumamos usar, e precisamos saber apenas em qual versão ela está atualmente.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/por-que-voce-deve-ir-ao-hackdesignconf-2013</id>
   <title>Por que você deve ir ao HDC 2013</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/por-que-voce-deve-ir-ao-hackdesignconf-2013.html"/>
   <updated>2013-09-26T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Para quem não sabe, sou autodidata nunca sequer comecei uma faculdade. Mas nesse caminho sentia falta de feedback de saber se estou trilhando o caminho certo, se o que eu faço está certo e o que pode melhorar. Um modo que achei para resolver isso foi participar de eventos de tecnologia, fazer &lt;a href=&quot;http://howtocode.com.br/&quot;&gt;cursos com gente da área que confio&lt;/a&gt;, participar dos eventos da comunidade de Software Livre aqui do Rio de Janeiro e por fim trabalhar na &lt;a href=&quot;http://helabs.com.br/&quot;&gt;HE:labs&lt;/a&gt; uma empresa que apoia tudo isso &amp;lt;3 pois assim sempre estaria cercado de gente boa e que ama o que faz.&lt;/p&gt;

&lt;p&gt;Sei que nem todos que trabalham com TI gostam, para estes simplesmente recomendo que vá procurar outra coisa, fazer o que não gosta deve ser horrivel, ainda mais que deve estar pelo menos 8h por dia nisso, na boa faça outra coisa =)&lt;/p&gt;

&lt;p&gt;Mas para os que gostam recomendo muito ir ao evento, pois terá bastante &lt;a href=&quot;http://hackdesignconf.com.br/#speaker-anchor&quot;&gt;gente legal palestrando&lt;/a&gt; além de bastante gente para se conversar fora das palestras.&lt;/p&gt;

&lt;p&gt;Venha para o evento com o pensamento de se divertir, aprender e conhecer pessoas. Sabe aquele cara que você conhece que avassala provavelmente ele estára aqui no evento vem dizer isso para ele, com certeza o cara ficará feliz.&lt;/p&gt;

&lt;p&gt;Conheci muita gente foda nesse caminho como o &lt;a href=&quot;https://twitter.com/henriquebastos&quot;&gt;Henrique Bastos&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/smergulhao&quot;&gt;Mergulhão&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/rafaelp&quot;&gt;Rafael Lima&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/tapajos&quot;&gt;Tapajós&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/fnando&quot;&gt;Nando&lt;/a&gt; entre muitos outros nomes que você deve conhecer. Já trocamos ideias, almoçamos e fomos para o Bar =)&lt;/p&gt;

&lt;p&gt;Então venha para o evento com o intuito de conhecer pessoas, é sempre legal ouvir a opinião dos outros.&lt;/p&gt;

&lt;p&gt;Mas não venha com pensamentos de conhecer pessoas por interesse de vagas, projetos ou algo assim, venha conhecer a pessoa pelo seu trabalho se rolar algo assim bom, mas não venha com este pensamento. Venha com o pensamento de se divertir.&lt;/p&gt;

&lt;p&gt;Para você ter uma ideia de como quando gostamos do que fazemos não vemos como trabalho. Eu estou de férias no momento em que escrevo este post, além disso nas férias eu fiz a &lt;a href=&quot;http://maurogeorge.com.br/&quot;&gt;minha página pessoal&lt;/a&gt;, refiz o design desse blog, to fazendo minha palestra para o evento, to aprendendo elixir e &lt;a href=&quot;https://github.com/maurogeorge&quot;&gt;contribui em projetos open source&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Para fechar deixo aqui um relato meu de &lt;a href=&quot;http://dojorio.org/2010/04/10/forkinrio2/#comment-148&quot;&gt;11 abril 2010&lt;/a&gt; da minha experiência quando comecei conhecer a galera das comunidades de Software Livre aqui do Rio.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;To postando aqui pois lá no grupo a mensagem não apareceu.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Seguindo conselho do Henrique Bastos vou escrever aqui como foi a minha experiência com o pessoal do Pyhton Rio.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Resolvi ir ao EDTED em março de 2010, tive que ir sozinho pois onde trabalho ninguém foi e como todos são focados em design provavelmente não assistiríamos as mesmas palestras. Chegando ao evento havia palestras que estavam em áreas de maior destaque para mais de 200 pessoas, no entanto achei que seria mais interessante o minicurso de DJANGO pois afinal era 2:30 contra as palestras de 1:00. Fui em uma área ao fundo do evento e perguntei o que seria ali e se eles eram o pessoal do #horaextra. E me responderam que seriam um Dojo e que sim eles eram o pessoal do #horaextra, conhecia o dojo apenas pela internet, devido a ocorrer a noite e eu morar longe de tudo fica complicado para eu ir, mais pretendo ir. Perguntei quem iria palestrar sobre DJANGO foi quando o Henrique falou que seria ele e me mostrou a sala onde ocorreria a palestra. A palestra rolou bem legal em um clima descontraído, nada de só porque o Henrique palestrava ele ter um ar de superioridade ele era como todos nos ali afinal todos queríamos aprender. Após a palestra fomos todos nos almoçar juntos e voltamos em seguida para as lighting talks, clima também descontraído e palestras curtas. Por volta das quatro e pouco prefiri vir embora afinal já havia acabado as lighting talks, vi um pouco do dojo mais devido a hora preferi vir embora. Me despedi do Henrique e perguntei a ele como aprender DJANGO primeiro aprendo Python? E ele me deu um cartão e falou para eu aparecer em um dos encontros. Não havia ido em nenhum encontro até ontem, pois como já falei eles são a noite eu moro longe, ontem fui no Forkin’rio na casa do Bernardo, aprendi e me diverti bastante mesmo sem ter feito exercícios, pois meu pc estava ruim. Resumindo depois de ter me alongado muito, valeu mais a pena ver uma palestra “humana” para 30 pessoas do que uma para mais de 200 em que provavelmente o conteúdo se perderia e seria muito superficial. Então é isso quem quiser se juntar ao grupo vale muito a pena devido a amizade e de aprender todos juntos, e se morar longe tenta aparecer pelo menos nos que ocorrem de dia, afinal para eu chegar a casa do Bernardo tive que acordar 6:20, começava as 9:00, e pegar 3 ônibus, mais valeu a pena.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Então se você chegou até aqui, acredito que lhe convenci a ir ao evento. Para estes peço que depois do evento escreva em um blog, site, gist como foi sua experiência.&lt;/p&gt;

&lt;p&gt;Grande abraço e nos vemos lá&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/factory-girl-e-paperclip-usando-os-2-de-maos-dadas</id>
   <title>Factory Girl e Paperclip usando os 2 de mãos dadas</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/factory-girl-e-paperclip-usando-os-2-de-maos-dadas.html"/>
   <updated>2013-07-10T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Imagine a seguinte situação seu model User ganhou um atributo novo, avatar, e este atributo é uma imagem do &lt;a href=&quot;https://github.com/thoughtbot/paperclip/&quot;&gt;Paperclip&lt;/a&gt; detalhe que está imagem é obrigatória. Como arrumar a sua &lt;a href=&quot;https://github.com/thoughtbot/factory_girl/&quot;&gt;factory&lt;/a&gt; para definir esta imagem? Já que agora todos as specs que usam esta factory estão quebrando devido a obrigatoriedade do avatar.&lt;/p&gt;

&lt;h2 id=&quot;usando-um-file&quot;&gt;Usando um File&lt;/h2&gt;

&lt;p&gt;Talvez o primeiro movimento seria passar um file para a factory.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;FactoryGirl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:user&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;John Doe&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;avatar&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;spec/fixtures/photo.jpg&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;No entanto isto é problemático pois:&lt;/p&gt;

&lt;p&gt;A imagem realmente está sendo enviada para a S3, deixando meus testes mais lentos e dependentes de rede. Claro que posso usar o &lt;a href=&quot;https://github.com/vcr/vcr&quot;&gt;VCR&lt;/a&gt; para salvar estas requisições, mas imagina a quantidade de specs usando esta factory, imagina agora o trabalho de colocar todas estas specs no VCR, realmente não parece uma boa ideia. E o pior teria que se lembrar de toda vez que fosse usar tal factory as specs teriam que está usando o VCR.&lt;/p&gt;

&lt;h2 id=&quot;usando-um-before-create&quot;&gt;Usando um before create&lt;/h2&gt;

&lt;p&gt;A solução que tenho usado no momento é definir um before create na factory, definindo os campos salvos pelo paperclip.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;FactoryGirl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:user&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;John Doe&quot;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;before&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:create&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;avatar_file_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;photo.jpg&quot;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;avatar_content_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;image/jpeg&quot;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;avatar_file_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2588&lt;/span&gt; 
      &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;avatar_updated_at&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;zone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;now&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Assim não é enviado nada para a S3, assim não preciso me preocupar em chamar o VCR nas minhas specs antigas ou novas usando tal factory. E o melhor não preciso fazer nada onde a factory já é usada, pois agora ela simplesmente funciona não dando erro de validação do campo avatar.&lt;/p&gt;

&lt;p&gt;Se você resolve este problema de outra forma ou achou útil a dica, comenta aí!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/logs-melhores-do-unicorn-no-ambiente-de-desenvolvimento-rails</id>
   <title>Logs melhores do unicorn no ambiente de desenvolvimento Rails</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/logs-melhores-do-unicorn-no-ambiente-de-desenvolvimento-rails.html"/>
   <updated>2013-07-09T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Uma boa prática é termos o nosso ambiente de desenvolvimento o mais próximo de produção, de preferência igual.&lt;/p&gt;

&lt;p&gt;Há algum tempo trabalho em alguns projetos que usam o &lt;a href=&quot;http://rubygems.org/gems/unicorn&quot;&gt;Unicorn&lt;/a&gt;, o problema que tinha era não ter um log em desenvolvimento parecido com o WEBrick.&lt;/p&gt;

&lt;p&gt;Meus logs saiam como:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;127.0.0.1 - - &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;09/Jul/2013 08:56:08] &lt;span class=&quot;s2&quot;&gt;&quot;POST /usuario/entrar HTTP/1.1&quot;&lt;/span&gt; 200 - 0.4803&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Para melhorar o log, podemos definir em &lt;code class=&quot;highlighter-rouge&quot;&gt;config/environments/development.rb&lt;/code&gt; a seguinte configuração:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;STDOUT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;E agora meus logs são mais bonitões, saindo assim:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Started POST &lt;span class=&quot;s2&quot;&gt;&quot;/usuario/entrar&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;127.0.0.1 at 2013-07-09 08:53:52 -0300
Processing by SessionsController#create as HTML
  Parameters: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;utf8&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;s2&quot;&gt;&quot;✓&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;authenticity_token&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;s2&quot;&gt;&quot;OhLmZiYG84pfwAhftomXQaFno5Cq3sPNGAYc9U3KUxM=&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;s2&quot;&gt;&quot;johndoe@example.com&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;s2&quot;&gt;&quot;[FILTERED]&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;remember_me&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;s2&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;commit&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;s2&quot;&gt;&quot;Entrar&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  MOPED: 127.0.0.1:27017 QUERY        &lt;span class=&quot;nv&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;estoujogando_development &lt;span class=&quot;nv&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;users &lt;span class=&quot;nv&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;={&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;s2&quot;&gt;&quot;johndoe@example.com&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$orderby&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;:_id&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;1&lt;span class=&quot;o&quot;&gt;}}&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=[]&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;-1 &lt;span class=&quot;nv&quot;&gt;skip&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0 &lt;span class=&quot;nv&quot;&gt;batch_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;nil &lt;span class=&quot;nv&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;={&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;notifications&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;0&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;21.7881ms&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Completed 401 Unauthorized &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;189ms
Processing by SessionsController#new as HTML
  Parameters: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;utf8&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;s2&quot;&gt;&quot;✓&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;authenticity_token&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;s2&quot;&gt;&quot;OhLmZiYG84pfwAhftomXQaFno5Cq3sPNGAYc9U3KUxM=&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;email&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;s2&quot;&gt;&quot;johndoe@example.com&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;s2&quot;&gt;&quot;[FILTERED]&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;remember_me&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;s2&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;commit&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&quot;s2&quot;&gt;&quot;Entrar&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  Rendered sessions/_login_form.html.haml &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;16.0ms&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  Rendered registrations/_pre_register_form.html.haml &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2.8ms&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  Rendered sessions/new.html.haml within layouts/login &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;31.1ms&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  Rendered application/_flash_messages.html.haml &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;9.0ms&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  Rendered application/_login_nav.html.haml &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2.6ms&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Completed 200 OK &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;378ms &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Views: 284.3ms | Solr: 0.0ms&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;É isso, post rápido, espero que seja útil para alguem a dica.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/quando-entrei-para-a-igreja-do-vim</id>
   <title>Quando entrei para a igreja do Vim</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/quando-entrei-para-a-igreja-do-vim.html"/>
   <updated>2013-04-27T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;O título do post foi baseado em um comentário do amigo &lt;a href=&quot;https://twitter.com/argentinomota&quot;&gt;Argentino&lt;/a&gt; enquanto conversavamos no Gtalk ele me perguntou por que eu tinha entrado para igreja do Vim.&lt;/p&gt;

&lt;h2 id=&quot;por-que-o-vim&quot;&gt;Por que o Vim?&lt;/h2&gt;

&lt;p&gt;Já há algum tempo tenho vontade de aprender, de verdade, um editor de texto, antes do Vim utilizava o Textmate mas não usava quase nenhuma de suas funcionalidades. E segui a seguinte lógica, se fosse para aprender um editor de texto iria aprender o Vim.&lt;/p&gt;

&lt;p&gt;Recentemente assisti uns &lt;a href=&quot;https://peepcode.com/&quot;&gt;PeepCode&lt;/a&gt; com &lt;a href=&quot;https://twitter.com/tenderlove&quot;&gt;Aaron Patterson&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/coreyhaines&quot;&gt;Corey Haines&lt;/a&gt; e &lt;a href=&quot;https://twitter.com/r00k&quot;&gt;Ben Orenstein&lt;/a&gt; e todos utilizavam o Vim, além de uns amigos como o &lt;a href=&quot;https://twitter.com/lunks&quot;&gt;Pedro&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/pellegrino&quot;&gt;VP&lt;/a&gt; e o próprio Argentino. O que só me motivou mais e decidi botar o plano em prática.&lt;/p&gt;

&lt;h2 id=&quot;por-onde-comear&quot;&gt;Por onde começar&lt;/h2&gt;

&lt;p&gt;Vou relatar aqui o que usei/tenho usado para o aprendizado.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Os 2 PeepCode sobre vim &lt;a href=&quot;https://peepcode.com/products/smash-into-vim-i&quot;&gt;I&lt;/a&gt; e &lt;a href=&quot;https://peepcode.com/products/smash-into-vim-ii&quot;&gt;II&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://blog.tarsisazevedo.com/post/16543244858/aprenda-vim-progressivamente&quot;&gt;Tradução Aprenda Vim Progressivamente&lt;/a&gt; do &lt;a href=&quot;https://twitter.com/tarsisazevedo&quot;&gt;Tarsis Azevedo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;vimrc&quot;&gt;.vimrc&lt;/h2&gt;

&lt;p&gt;Caso escolha seguir o caminho de usar o Vim, irá saber que o .vimrc é um dos seus arquivos de configuração para o Vim.
Deixo aqui o link para o &lt;a href=&quot;https://gist.github.com/maurogeorge/5253970/799fc152503b1316cc38caf7d34f8f712edd5bdf&quot;&gt;gist da primeira versão do meu .vimrc&lt;/a&gt; foi baseado no do PeepCode, no entanto removi bastante coisa que não sabia para que servia, queria tentar manter o mais simples até começar a adicionar plugins e etc. Recomendo usar esta versão para quem está começando já que ele exibe os numeros das linhas, tem syntax highlight etc.
Quando foi escrito este post o meu &lt;a href=&quot;https://gist.github.com/maurogeorge/5253970/8c0ae40e0543786e4323d74066760e63a2dcf5c4&quot;&gt;.vimrc estava assim&lt;/a&gt; usando o &lt;a href=&quot;https://github.com/gmarik/vundle&quot;&gt;Vundle&lt;/a&gt; e alguns plugins.&lt;/p&gt;

&lt;p&gt;Por hora estou usando apenas o gist, pois ainda estou adicionando os plugins conforme a necessidade surge, mas quem sabe algum dia use um repo para isso.&lt;/p&gt;

&lt;p&gt;Caso queira dar uma olhada em como o pessoal tem configurado o vim, deixo aqui uns repos que andei observando também:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/pellegrino/dotfiles&quot;&gt;https://github.com/pellegrino/dotfiles&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/lunks/vimfiles&quot;&gt;https://github.com/lunks/vimfiles&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/thoughtbot/dotfiles&quot;&gt;https://github.com/thoughtbot/dotfiles&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/r00k/dotfiles&quot;&gt;https://github.com/r00k/dotfiles&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/ryanb/dotfiles&quot;&gt;https://github.com/ryanb/dotfiles&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/trate-o-ruby-como-a-linguagem-dinamica-que-ele-e</id>
   <title>Trate o ruby como a linguagem dinâmica que ele é</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/trate-o-ruby-como-a-linguagem-dinamica-que-ele-e.html"/>
   <updated>2013-04-10T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;O Ruby é uma linguagem de tipagem dinâmica, e para pessoas que vem de linguagens de tipagem estática tem que mudar sua mentalidade para trabalhar com uma linguagem dinâmica, veremos o que fazer e o que não fazer e como podemos lidar com o que as linguagens dinâmicas tem de ruim, afinal nem tudo são flores.&lt;/p&gt;

&lt;h2 id=&quot;no-fazemos-checagem-de-tipos&quot;&gt;Não fazemos checagem de tipos&lt;/h2&gt;

&lt;p&gt;Pode assustar um pouco a idéia de não fazermos nenhuma checagem de tipo, quando definimos um método que aceita parâmetros, definimos apenas o nome dos parâmetros e não o seu tipo:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;my_name_is&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;My name is &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Veja que não definimos nenhum tipo para o parâmetro &lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt;. Assim como não precisamos definir o tipo de nossos atributos de classe. E graças a esta não checagem de tipo que podemos usar uma das coisas mais legais da linguagem o Duck Typing, que veremos a seguir.&lt;/p&gt;

&lt;h2 id=&quot;no-fazemos-interfaces&quot;&gt;Não fazemos interfaces&lt;/h2&gt;

&lt;p&gt;Imagine que em nosso sistema tenhamos 2 entidades Post e AwesomePost, que é um post em destaque. Agora sempre queremos garantir que ambos tenham definidos os atributos &lt;code class=&quot;highlighter-rouge&quot;&gt;title&lt;/code&gt; e &lt;code class=&quot;highlighter-rouge&quot;&gt;content&lt;/code&gt;.
Talvez tenderíamos a usar uma interface, no entanto o ruby não tem suporte a interfaces, mas podemos simular uma fazendo algo como:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BasePost&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;title&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Not implemented&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;content&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Not implemented&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;BasePost&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@content&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;title&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@title&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;content&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@content&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AwesomePost&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;BasePost&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@content&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;title&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;The awesome post: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@title&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;content&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;The awesome content: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@content&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Que poderia ser utilizado:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;A new post&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &quot;A new post&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &quot;content&quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;AwesomePost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;A new awesome post&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Awesome content&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &quot;The awesome post: A new awesome post&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &quot;The awesome content: Awesome content&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;O código acima funciona, no entanto não é um bom código ruby.
O problema não é nas classes &lt;code class=&quot;highlighter-rouge&quot;&gt;Post&lt;/code&gt; e &lt;code class=&quot;highlighter-rouge&quot;&gt;AwesomePost&lt;/code&gt; e sim na classe &lt;code class=&quot;highlighter-rouge&quot;&gt;BasePost&lt;/code&gt; que não faz absolutamente nada. &lt;code class=&quot;highlighter-rouge&quot;&gt;BasePost&lt;/code&gt; existe apenas como uma tentativa de mantermos uma interface padrão para as classes &lt;code class=&quot;highlighter-rouge&quot;&gt;Post&lt;/code&gt; e &lt;code class=&quot;highlighter-rouge&quot;&gt;AwesomePost&lt;/code&gt; ou qualquer outra classe de &lt;code class=&quot;highlighter-rouge&quot;&gt;Post&lt;/code&gt; que venhamos a criar.&lt;/p&gt;

&lt;p&gt;No entanto é um esforço em vão pois como vimos anteriormente, não fazemos checagem de tipos na chamada de um método, sendo assim pouco importa a hierarquia de classes de um tal objeto, desde que ele saiba responder a tal método e é neste ponto que chegamos ao &lt;a href=&quot;http://en.wikipedia.org/wiki/Duck_typing&quot;&gt;Duck Typing&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;abrace-o-duck-typing&quot;&gt;Abrace o Duck Typing&lt;/h2&gt;

&lt;p&gt;Utilizando o Duck Typing, primeiro podemos remover a classe &lt;code class=&quot;highlighter-rouge&quot;&gt;BasePost&lt;/code&gt; e remover a herança de &lt;code class=&quot;highlighter-rouge&quot;&gt;Post&lt;/code&gt; e &lt;code class=&quot;highlighter-rouge&quot;&gt;AwesomePost&lt;/code&gt; afinal ambas as classes implementam os mesmos métodos ficando assim:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Post&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Mesmo conteúdo&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AwesomePost&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Mesmo conteúdo&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Agora imagine que tenhamos um decorator responsável por gerar um HTML para a exibição destas classes &lt;code class=&quot;highlighter-rouge&quot;&gt;Post&lt;/code&gt;s sua implementação seria algo como:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PostDecorator&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;show&lt;/span&gt;
    &lt;span class=&quot;sx&quot;&gt;%Q{&amp;lt;h1&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;&amp;lt;/h1&amp;gt;
       &amp;lt;div id=&quot;content&quot;&amp;gt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;&amp;lt;/div&amp;gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;E como já foi dito anteriormente que não fazemos checagem de tipos, seria aceito ambas as classes veja abaixo:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;A new post&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;awesome_post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;AwesomePost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;A new awesome post&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Awesome content&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;PostDecorator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &quot;&amp;lt;h1&amp;gt;A new post&amp;lt;/h1&amp;gt;\n       &amp;lt;div id=\&quot;content\&quot;&amp;gt;content&amp;lt;/div&amp;gt;&quot;&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;PostDecorator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;awesome_post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &quot;&amp;lt;h1&amp;gt;The awesome post: A new awesome post&amp;lt;/h1&amp;gt;\n       &amp;lt;div id=\&quot;content\&quot;&amp;gt;The awesome content: Awesome content&amp;lt;/div&amp;gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;E assim utilizamos o poder do Duck Typing, afinal:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Fazendo isso observamos a verdadeira diminuição de código de que se houve falar ao comparar linguagens estáticas com dinâmicas, e isto não está na remoção de &lt;code class=&quot;highlighter-rouge&quot;&gt;int&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;string&lt;/code&gt; etc. na declaração de variáveis e sim na não declaração de classes abstratas e interfaces que nunca escreveremos.&lt;/p&gt;

&lt;h2 id=&quot;srio-no-tenha-medo-do-duck-typing&quot;&gt;Sério, não tenha medo do Duck Typing&lt;/h2&gt;

&lt;p&gt;As vezes podemos encontrar código que tenta forçar uma tipagem estática, algo como assim:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;title isn&#39;t a string&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;kind_of?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;content isn&#39;t a string&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;kind_of?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;vi&quot;&gt;@title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;
  &lt;span class=&quot;vi&quot;&gt;@content&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Por favor não faça isso. Pois assim só estará perdendo:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Destrói o baixo acoplamento da tipagem dinâmica&lt;/li&gt;
  &lt;li&gt;Aumenta bastante o código, no entanto melhora um pouco apenas a garantia de que vai funcionar.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Como pode ver utilizando o ruby como a linguagem dinâmica que ela é, diminuímos bastante a complexidade de nossos códigos.&lt;/p&gt;

&lt;h2 id=&quot;mas-como-garantimos-que-tudo-simplesmente-funcione&quot;&gt;Mas como garantimos que tudo simplesmente funcione&lt;/h2&gt;

&lt;p&gt;Até agora vimos que não precisamos declarar tipo, mas e se por um acaso eu passar um tipo inválido para um método? Então temos as seguintes dicas para lidar com isso.&lt;/p&gt;

&lt;h3 id=&quot;utilize-nome-descritivos&quot;&gt;Utilize nome descritivos&lt;/h3&gt;

&lt;p&gt;Abaixo criamos um método tags que recebe “n”, pode ser claro para alguns que ele retorne as tags de um post limitando pela quantidade declarada em “n”.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;tags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;No entanto podemos fazer melhor:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;tags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;total_of_tags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Como pode ver agora ficou mais fácil de saber que o valor é um inteiro. A dica é escreva nomes para serem lidos por humanos.&lt;/p&gt;

&lt;h3 id=&quot;como-eu-sei-qual-tipos-o-parmetro-de-um-mtodo-espera&quot;&gt;Como eu sei qual tipo(s) o parâmetro de um método espera&lt;/h3&gt;

&lt;p&gt;Além da dica de nome descritivo, que já ajuda bastante.
Escreva testes automatizados, com testes saberá exatamente quais tipos de objetos são aceitos por um método ou não.&lt;/p&gt;

&lt;h2 id=&quot;concluso&quot;&gt;Conclusão&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Não crie mas complexidade do que precisa&lt;/li&gt;
  &lt;li&gt;aproveite o que a linguagem dinâmica tem para oferecer&lt;/li&gt;
  &lt;li&gt;abrace o Duck Typing&lt;/li&gt;
  &lt;li&gt;lembre-se que as classes não precisam de herança para compartilharem a mesma interface, só precisam implementar os mesmos métodos&lt;/li&gt;
  &lt;li&gt;não faça checagem de tipos sem sentido, lembre-se abrace o Duck Typing&lt;/li&gt;
  &lt;li&gt;Escreva código para humanos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Este post foi baseado no Cap. 8 do &lt;a href=&quot;http://www.amazon.com.br/Eloquent-Addison-Wesley-Professional-Series-ebook/dp/B004MMEJ36/ref=sr_1_1?s=digital-text&amp;amp;ie=UTF8&amp;amp;qid=1365598968&amp;amp;sr=1-1&amp;amp;keywords=eloquent+ruby&quot;&gt;livro Eloquent Ruby&lt;/a&gt;, espero escrever mais alguns posts baseado em conteúdo do livro, recomendo fortemente a compra do mesmo.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/a-notacao-de-porcento-em-ruby</id>
   <title>A notação de porcento em Ruby</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/a-notacao-de-porcento-em-ruby.html"/>
   <updated>2013-03-06T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;No Ruby temos a notação de &lt;code class=&quot;highlighter-rouge&quot;&gt;%&lt;/code&gt; que veio inspirada do Perl. Além do &lt;code class=&quot;highlighter-rouge&quot;&gt;%&lt;/code&gt; podemos usar um caractere modificador que muda o comportamento do nosso &lt;code class=&quot;highlighter-rouge&quot;&gt;%&lt;/code&gt;. Vamos ver como cada um destes funcionam.&lt;/p&gt;

&lt;h2 id=&quot;section&quot;&gt;%&lt;/h2&gt;

&lt;p&gt;Ao utilizarmos a sintaxe &lt;code class=&quot;highlighter-rouge&quot;&gt;%&lt;/code&gt; temos o mesmo resultado do uso de aspas duplas, no entanto não temos a necessidade de escapar nenhuma aspas, seja simples ou duplas.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Groselhas&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%{O #{blog} é o blog do Mauro}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;O Groselhas é o blog do Mauro&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;q&quot;&gt;%q&lt;/h2&gt;

&lt;p&gt;Ao utilizarmos a sintaxe &lt;code class=&quot;highlighter-rouge&quot;&gt;%q&lt;/code&gt; temos o mesmo resultado do uso de aspas simples, no entanto não temos a necessidade de escapar nenhuma aspas, seja simples ou duplas.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Groselhas&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%q{O #{blog} é o blog do Mauro}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;O \#{blog} é o blog do Mauro&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;q-1&quot;&gt;%Q&lt;/h2&gt;

&lt;p&gt;Utilizamos o &lt;code class=&quot;highlighter-rouge&quot;&gt;%Q&lt;/code&gt; obtemos o mesmo resultado do uso de aspas duplas, assim como o &lt;code class=&quot;highlighter-rouge&quot;&gt;%&lt;/code&gt;, ou seja &lt;code class=&quot;highlighter-rouge&quot;&gt;%&lt;/code&gt; e &lt;code class=&quot;highlighter-rouge&quot;&gt;%Q&lt;/code&gt; possuem o mesmo comportamento.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Groselhas&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%Q{O &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; é o blog do Mauro}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;O Groselhas é o blog do Mauro&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;w&quot;&gt;%w&lt;/h2&gt;

&lt;p&gt;Utilizamos o &lt;code class=&quot;highlighter-rouge&quot;&gt;%w&lt;/code&gt; para a criação de arrays de strings, e como o &lt;code class=&quot;highlighter-rouge&quot;&gt;%q&lt;/code&gt; ele não faz interpolação de strings.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Groselhas&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{#{blog} Mauro Blog}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; [&quot;\#{blog}&quot;, &quot;Mauro&quot;, &quot;Blog&quot;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;w-1&quot;&gt;%W&lt;/h2&gt;

&lt;p&gt;Com o uso do &lt;code class=&quot;highlighter-rouge&quot;&gt;%W&lt;/code&gt; criamos um array de strings, e assim como o &lt;code class=&quot;highlighter-rouge&quot;&gt;%Q&lt;/code&gt; podemos fazer interpolação de strings&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Groselhas&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%W{&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; Mauro Blog}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; [&quot;Groselhas&quot;, &quot;Mauro&quot;, &quot;Blog&quot;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;i&quot;&gt;%i&lt;/h2&gt;

&lt;p&gt;Recentemente adicionado no Ruby 2.0, o &lt;code class=&quot;highlighter-rouge&quot;&gt;%i&lt;/code&gt; é usado para gerarmos um array de symbols, e como você já deve esperar ele não faz interpolação de strings.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Groselhas&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%i{#{blog} item}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; [:&quot;\#{blog}&quot;, :item]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;i-1&quot;&gt;%I&lt;/h2&gt;

&lt;p&gt;O &lt;code class=&quot;highlighter-rouge&quot;&gt;%I&lt;/code&gt; possui quase o mesmo comportamento do &lt;code class=&quot;highlighter-rouge&quot;&gt;%i&lt;/code&gt;, no entanto ele faz interpolação de strings. Também adicionado no Ruby 2.0.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Groselhas&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%I{&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; item}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; [:Groselhas, :item]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;r&quot;&gt;%r&lt;/h2&gt;

&lt;p&gt;Com o &lt;code class=&quot;highlighter-rouge&quot;&gt;%r&lt;/code&gt; podemos criar uma expressão regular, e também podemos fazer interpolação de strings&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Groselhas&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;%r{&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;.*Mauro}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; /Groselhas.*Mauro/&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;s&quot;&gt;%s&lt;/h2&gt;

&lt;p&gt;Utilizamos o &lt;code class=&quot;highlighter-rouge&quot;&gt;%s&lt;/code&gt; para a criação de um symbol, e não conseguimos fazer interpolação de strings.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Groselhas&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%s{#{blog} item}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; :&quot;\#{blog} item&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;x&quot;&gt;%x&lt;/h2&gt;

&lt;p&gt;Usamos o &lt;code class=&quot;highlighter-rouge&quot;&gt;%x&lt;/code&gt; para executar comandos do sistema operacional, e ainda conseguimos fazer interpolação de strings.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;option&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;-l&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%x{ls &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; total 88\n-rw-r--r--   1 mauro...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;trocando-o-delimitador&quot;&gt;Trocando o delimitador&lt;/h2&gt;

&lt;p&gt;Em todos os nossos exemplos usamos o &lt;code class=&quot;highlighter-rouge&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;/code&gt; para iniciar e o &lt;code class=&quot;highlighter-rouge&quot;&gt;}&lt;/code&gt; para finalizar nosso comando, no entanto podemos usar qualquer um caractere que possua o seu par como os parêntesis(&lt;code class=&quot;highlighter-rouge&quot;&gt;(&lt;/code&gt; e &lt;code class=&quot;highlighter-rouge&quot;&gt;)&lt;/code&gt;) e o colchete(&lt;code class=&quot;highlighter-rouge&quot;&gt;[&lt;/code&gt; e &lt;code class=&quot;highlighter-rouge&quot;&gt;]&lt;/code&gt;). Caso utilizemos o mesmo delimitador não é necessário escapar desde que se use o de abertura e fechamento.
Também é possivel utilizar 2 caracteres iguais como delimitadores.
Veja um exemplo&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Groselhas&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%Q{O &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; {blog do Mauro}}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;O Groselhas {blog do Mauro}&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%Q(O &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; { blog do Mauro)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;O Groselhas { blog do Mauro&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%Q$O &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;blog&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; {blog do Mauro}$&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;O Groselhas {blog do Mauro}&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Como pode ver ao trocarmos o delimitador podemos usar o &lt;code class=&quot;highlighter-rouge&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;/code&gt; e o &lt;code class=&quot;highlighter-rouge&quot;&gt;}&lt;/code&gt; livremente em nosso código.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/do-php-para-o-ruby-o-que-mudou-no-meu-modo-de-desenvolver</id>
   <title>Do PHP para o Ruby o que mudou no meu modo de desenvolver</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/do-php-para-o-ruby-o-que-mudou-no-meu-modo-de-desenvolver.html"/>
   <updated>2013-02-27T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Este post não é uma comparação de linguagens para saber qual é a melhor, afinal linguagens são só ferramentas. Hoje estou no Ruby quem sabe amanhã não seja no Closure, Scala ou qualquer outra. O objetivo aqui é dizer o que mudou no meu modo de desenvolver depois de mais de 1 ano trabalhando com Ruby.&lt;/p&gt;

&lt;h2 id=&quot;controle-de-verso&quot;&gt;Controle de versão&lt;/h2&gt;

&lt;p&gt;Onde eu trabalhava era muito complicado convencer que o Git era uma boa ferramenta, apesar de eu usar sozinho, mas convencer a equipe toda a usar era complicado, era questionado ainda o por que de não usar o SVN, sim em 2011.&lt;/p&gt;

&lt;p&gt;Na &lt;a href=&quot;http://helabs.com.br&quot;&gt;HE:labs&lt;/a&gt; utilizamos o Git, todos do time, inclusive os designers, não sendo problema para ninguém do time o seu uso.&lt;/p&gt;

&lt;h2 id=&quot;testes&quot;&gt;Testes&lt;/h2&gt;

&lt;p&gt;Trabalhando com PHP tive poucas oportunidades de fazer testes, era o usual vai demorar mais etc. O Pouco que eu fiz, foi bem pouco mesmo em projetos de clientes e fico triste em conversando com o pessoal da comunidade que esta é a realidade. E no &lt;a href=&quot;https://github.com/maurogeorge/boletophp/tree/2.x-dev&quot;&gt;BoletoPHP&lt;/a&gt; onde estava fazendo testes, migrando a aplicação do procedural para uma orientada a objetos.&lt;/p&gt;

&lt;p&gt;No Ruby a comunidade é mais madura em relação a isso, toda Gem(lib) só é considerada completa se possui testes, afinal você não quer instalar uma dependência em seu sistema que pode estar funcionando. E no trabalho todos os nossos projetos na &lt;a href=&quot;http://helabs.com.br&quot;&gt;HE:labs&lt;/a&gt; possuem testes e outra &lt;strong&gt;100%&lt;/strong&gt; testados, não vai nenhum código para produção que não possui 100% de cobertura de testes.&lt;/p&gt;

&lt;p&gt;Se você não possui 100% de coverage em seus testes deixo apenas este &lt;a href=&quot;http://cleancoder.posterous.com/100-test-coverage&quot;&gt;vídeo aqui do Uncle Bob&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;integrao-e-deploy-continuo&quot;&gt;Integração e deploy continuo&lt;/h2&gt;

&lt;p&gt;Trabalhando com PHP para colocar um projeto em produção/staging era através de FTP, consegui mudar um pouco isso inserindo um simples hook no Git para fazer o deploy. Mas podia ser melhor.&lt;/p&gt;

&lt;p&gt;Hoje em dia utilizamos o &lt;a href=&quot;https://github.com/mergulhao/integration&quot;&gt;Integration&lt;/a&gt; que envia o nosso código para o ambiente de staging, e produção quando necessário, no entanto antes de enviar qualquer código entre outras coisas é rodada todas as specs, e verificado se está com 100% de coverage, caso não esteja com 100% de coverage o código não é enviado. Garantindo assim apenas que código que esteja funcionando seja integrado ao projeto.&lt;/p&gt;

&lt;h2 id=&quot;tcnicas-de-orientao-a-objetos&quot;&gt;Técnicas de orientação a objetos&lt;/h2&gt;

&lt;p&gt;No PHP, as ferramentas mais populares infelizmente são procedurais, e acredito que continuaram assim por muito tempo, entre elas digo o WordPress e o Drupal, fazem muito bem o seu papel, mas não são nenhum exemplo de engenharia de software. Os frameworks por outro lado, possuem um código orientado a objetos e com testes como o Zend Framework e o CakePHP no entanto via muito as pessoas presas ao MVC que o framework oferecia e só.&lt;/p&gt;

&lt;p&gt;Em Ruby como temos nosso código 100% testado, não ficamos apenas no MVC e no Fat Models Skiny Controllers, preferimos o Skiny Models e Controllers e uma camada de serviço. Esta camada de serviço, além de services, temos outras classes como Decorators, FormObjets etc separados logicamente claro.&lt;/p&gt;

&lt;h2 id=&quot;refactories-kiss-dry-e-yagni&quot;&gt;Refactories KISS, DRY e YAGNI&lt;/h2&gt;

&lt;p&gt;Trabalhando com PHP se uma coisa estava “pronta” ela estava “pronta”, pois como não possuía testes não me sentia confortável em refatorar algo já que teria que testar toda a interação pelo browser o que com certeza teria falhas.&lt;/p&gt;

&lt;p&gt;Em Ruby tenho total confiança para fazer um refactory, pois se algo quebrar o meu teste irá avisar. E assim consigo aplicar técnicas de &lt;a href=&quot;http://en.wikipedia.org/wiki/KISS_principle&quot;&gt;KISS&lt;/a&gt; quebrando métodos maiores em menores ou classes grandes em mais de uma classe dividindo a responsábilidade, &lt;a href=&quot;http://en.wikipedia.org/wiki/DRY_principle&quot;&gt;DRY&lt;/a&gt; se eu tenho repetição refatoro até não à ter e &lt;a href=&quot;http://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it&quot;&gt;YAGNI&lt;/a&gt; desenvolvendo para a interface e não criando métodos que posso precisar, desenvolvo utilizando &lt;a href=&quot;http://en.wikipedia.org/wiki/Test-driven_development&quot;&gt;TDD&lt;/a&gt; para a minha interface.&lt;/p&gt;

&lt;h2 id=&quot;agile-no-mundo-real&quot;&gt;Agile no mundo real&lt;/h2&gt;

&lt;p&gt;Trabalhando com PHP nunca trabalhei com agile, era sempre escopo fechado.&lt;/p&gt;

&lt;p&gt;Atualmente trabalho com agile, mas especificamente com &lt;a href=&quot;http://en.wikipedia.org/wiki/Extreme_programming&quot;&gt;XP&lt;/a&gt;. Temos iterações semanais, contrato de escopo variável, testes automatizados e diversas outras práticas do XP.&lt;/p&gt;

&lt;p&gt;Como pode ver considero que evolui bastante migrando do PHP para o Ruby. E com certeza não foi apenas a mudança de linguagem mais sim a mudança para a &lt;a href=&quot;http://helabs.com.br&quot;&gt;HE:labs&lt;/a&gt; onde temos um &lt;a href=&quot;http://helabs.com.br/#time&quot;&gt;time foda&lt;/a&gt;! E você tem evoluído bastante? Comenta aí.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/delegacao-em-ruby-utilzando-o-modulo-forwardable</id>
   <title>Delegação em Ruby utilzando o módulo Forwardable</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/delegacao-em-ruby-utilzando-o-modulo-forwardable.html"/>
   <updated>2013-02-21T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Em Ruby temos o poder de fazer overloading de operadores, ou seja definirmos nossa própria implementação para os operadores.&lt;/p&gt;

&lt;p&gt;Quando temos uma classe que é uma coleção é uma boa idéia, se fizer sentido, definirmos os operadores &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;&amp;lt;&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;[]&lt;/code&gt; e &lt;code class=&quot;highlighter-rouge&quot;&gt;[]=&lt;/code&gt; pois assim teremos uma interface igual a de um &lt;a href=&quot;http://ruby-doc.org/core-1.9.3/Enumerable.html&quot;&gt;Enumerable&lt;/a&gt;.
Tecnicamente os operadores &lt;code class=&quot;highlighter-rouge&quot;&gt;[]&lt;/code&gt; e &lt;code class=&quot;highlighter-rouge&quot;&gt;[]=&lt;/code&gt; não são operadores e sim métodos, em que o Ruby aplica um &lt;a href=&quot;http://en.wikipedia.org/wiki/Syntactic_sugar&quot;&gt;açucar sintático&lt;/a&gt; assim quando fazemos &lt;code class=&quot;highlighter-rouge&quot;&gt;foo[2]&lt;/code&gt; estamos chamando o método &lt;code class=&quot;highlighter-rouge&quot;&gt;[]&lt;/code&gt; em &lt;code class=&quot;highlighter-rouge&quot;&gt;foo&lt;/code&gt;, passando o parâmetro 2 e quando fazemos &lt;code class=&quot;highlighter-rouge&quot;&gt;foo[2] = 4&lt;/code&gt; estamos na realidade chamando o método &lt;code class=&quot;highlighter-rouge&quot;&gt;[]=&lt;/code&gt; em &lt;code class=&quot;highlighter-rouge&quot;&gt;foo&lt;/code&gt; passando os parâmetros 2 e 4, por isso conseguimos fazer overloading destes métodos também.&lt;/p&gt;

&lt;p&gt;Vamos a um exemplo:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Basket&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@items&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;total_of_items&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;size&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@items&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;[]=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;criamos uma classe &lt;code class=&quot;highlighter-rouge&quot;&gt;Basket&lt;/code&gt; que é nossa cesta, seu papel é ser uma coleção de items, vamos vê-la em ação:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;basket&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Basket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;basket&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Morango&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;basket&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Manga&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;basket&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Banana&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;basket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Pera&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;basket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;Morango&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;basket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;Pera&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;basket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;total_of_items&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 4&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Como pode ver agora nossa classe se comporta como um &lt;code class=&quot;highlighter-rouge&quot;&gt;Enumerable&lt;/code&gt; no entanto se observar bem os métodos que implementamos, nada mais são do que delegar para os métodos do &lt;code class=&quot;highlighter-rouge&quot;&gt;Enumerable&lt;/code&gt;, vamos a uma implementação mais inteligente.&lt;/p&gt;

&lt;h2 id=&quot;utilizando-o-forwardable&quot;&gt;Utilizando o Forwardable&lt;/h2&gt;

&lt;p&gt;O Ruby possui o módulo &lt;a href=&quot;http://ruby-doc.org/stdlib-1.9.2/libdoc/forwardable/rdoc/Forwardable.html&quot;&gt;Forwardable&lt;/a&gt; que nos permite delegar métodos específicos para um objeto.
Ou seja poderemos delegar os métodos de array, para o nosso próprio array &lt;code class=&quot;highlighter-rouge&quot;&gt;@items&lt;/code&gt;. Vamos ao código:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;forwardable&#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Basket&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;extend&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Forwardable&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@items&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;def_delegator&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:@items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:total_of_items&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;def_delegators&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:@items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:[]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:[]=&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Ao utilizarmos a nossa nova classe &lt;code class=&quot;highlighter-rouge&quot;&gt;Basket&lt;/code&gt; obtemos o mesmo resultado da classe anterior:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;basket&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Basket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;basket&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Morango&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;basket&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Manga&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;basket&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Banana&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;basket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Pera&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;basket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;Morango&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;basket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;Pera&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;basket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;total_of_items&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 4&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Vamos agora entender o que aconteceu.&lt;/p&gt;

&lt;h3 id=&quot;defdelegator&quot;&gt;def_delegator&lt;/h3&gt;

&lt;p&gt;Primeiro utilizamos o &lt;a href=&quot;http://ruby-doc.org/stdlib-1.9.2/libdoc/forwardable/rdoc/Forwardable.html#method-i-def_delegator&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;def_delegator&lt;/code&gt;&lt;/a&gt; que nos permite definir um delegator, para um único método do objeto e opcionalmente definir um nome diferente ao método. No nosso exemplo usamos o &lt;code class=&quot;highlighter-rouge&quot;&gt;Basket#total_of_items&lt;/code&gt; pois para a nossa interface faz mais sentido este nome do que apenas &lt;code class=&quot;highlighter-rouge&quot;&gt;Basket#size&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;defdelegators&quot;&gt;def_delegators&lt;/h3&gt;

&lt;p&gt;Como você já deve imaginar o &lt;a href=&quot;http://ruby-doc.org/stdlib-1.9.2/libdoc/forwardable/rdoc/Forwardable.html#method-i-def_delegators&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;def_delegators&lt;/code&gt;&lt;/a&gt; nos permite definir diversos delegators, para diversos métodos do objeto, no entanto não é possível definir um nome diferente ao método. Utilizamos ele para criar os demais métodos &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;&amp;lt;&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;[]&lt;/code&gt; e &lt;code class=&quot;highlighter-rouge&quot;&gt;[]=&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Como pode ver o uso do &lt;code class=&quot;highlighter-rouge&quot;&gt;Forwardable&lt;/code&gt; fez nossa classe mais &lt;strong&gt;enxuta&lt;/strong&gt; e não precisamos redefinir os métodos já existentes em nosso objeto. Lembrando que pode-se definir qualquer método de um dado objeto, cabe a você fazer as escolhas certas para manter uma interface clara.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/somando-valores-de-um-array-em-ruby-de-uma-forma-mais-elegante-utilizando-inject</id>
   <title>Somando valores de um array em ruby de uma forma mais elegante utilizando inject</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/somando-valores-de-um-array-em-ruby-de-uma-forma-mais-elegante-utilizando-inject.html"/>
   <updated>2013-02-16T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Imagine que tenhamos que somar os valores de um &lt;code class=&quot;highlighter-rouge&quot;&gt;array&lt;/code&gt;, provavelmente seguiríamos para uma abordagem neste sentido:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 19&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;No entanto o ruby possui o &lt;a href=&quot;http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-inject&quot;&gt;Enumerable#inject&lt;/a&gt;. Poderiamos trocar o nosso exemplo para algo como:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;inject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 19&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;uma versão bem mais simples e elegante do que o primeiro exemplo. O &lt;code class=&quot;highlighter-rouge&quot;&gt;inject&lt;/code&gt; ainda nos dá a possibilidade de definirmos um valor para iniciarmos o somatório.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;inject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 29&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Perceba que agora iniciamos a contagem em 10 e adicionamos os demais valores.&lt;/p&gt;

&lt;p&gt;Por padrão o valor que é iniciado no &lt;code class=&quot;highlighter-rouge&quot;&gt;inject&lt;/code&gt; é &lt;code class=&quot;highlighter-rouge&quot;&gt;nil&lt;/code&gt;, sendo assim se passarmos um array vázio o nosso retorno será &lt;code class=&quot;highlighter-rouge&quot;&gt;nil&lt;/code&gt; e não 0, que pode ser o esperado:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;inject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; nil&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Como vimos que podemos definir o valor inicial, podemos definir como 0 e assim conseguir o resultado que esperamos.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;inject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Para quem estiver utilizando o rails, o &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveSupport&lt;/code&gt; adiciona no &lt;code class=&quot;highlighter-rouge&quot;&gt;Enumerable&lt;/code&gt; o método &lt;a href=&quot;http://api.rubyonrails.org/classes/Enumerable.html#method-i-sum&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sum&lt;/code&gt;&lt;/a&gt; que pode ser utilizado assim:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 19&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;No nosso exemplo utilizamos o &lt;code class=&quot;highlighter-rouge&quot;&gt;array&lt;/code&gt; values criado manualmente, mas poderia muito bem ser um &lt;code class=&quot;highlighter-rouge&quot;&gt;array&lt;/code&gt; criado a partir do uso do &lt;a href=&quot;/conheca-o-pluck-do-activerecord.html&quot;&gt;pluck do ActiveRecord&lt;/a&gt; por exemplo.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/buscar-um-ou-mais-objetos-em-um-array-de-objetos-em-ruby</id>
   <title>Buscar um ou mais objetos em um array de objetos em Ruby</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/buscar-um-ou-mais-objetos-em-um-array-de-objetos-em-ruby.html"/>
   <updated>2013-02-16T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Como fariamos para conseguir pegar um objeto de um &lt;code class=&quot;highlighter-rouge&quot;&gt;array&lt;/code&gt; de objetos baseado em uma propriedade do objeto?&lt;/p&gt;

&lt;p&gt;Vamos ao seguinte cenário, dado que tenhamos o seguinte &lt;code class=&quot;highlighter-rouge&quot;&gt;array&lt;/code&gt; de &lt;code class=&quot;highlighter-rouge&quot;&gt;OpenStruct&lt;/code&gt;s, utilizamos &lt;code class=&quot;highlighter-rouge&quot;&gt;OpenStruct&lt;/code&gt; pela facilidade mas poderia ser qualquer objeto ou mesmo um &lt;code class=&quot;highlighter-rouge&quot;&gt;Hash&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;ostruct&#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;games&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;OpenStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;id: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;53&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;name: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Gears of War&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;gender: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;action&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;OpenStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;id: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;54&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;name: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Uncharted&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;gender: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;action&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Se quisessemos apenas o objeto com o id 53, poderiamos usar o &lt;a href=&quot;http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-select&quot;&gt;Enumerable#select&lt;/a&gt; que nos retornaria:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;games&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;53&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; [#&amp;lt;OpenStruct id=53, name=&quot;Gears of War&quot;, gender=&quot;action&quot;&amp;gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;como pode ver o &lt;code class=&quot;highlighter-rouge&quot;&gt;select&lt;/code&gt; nos retorna uma coleção, sendo assim ele retorna todos os objetos que satisfazerem a condição passada ao bloco, veja o exemplo a seguir:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;games&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;gender&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;action&#39;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; [#&amp;lt;OpenStruct id=53, name=&quot;Gears of War&quot;, gender=&quot;action&quot;&amp;gt;, #&amp;lt;OpenStruct id=54, name=&quot;Uncharted&quot;, gender=&quot;action&quot;&amp;gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Como temos 2 objetos com o gender igual a action ele retornou os 2. Caso queiramos apenas o primeiro objeto que satisfazer a condição, o que faz sentido no caso de uma busca por id por exemplo, podemos utilizar o &lt;a href=&quot;http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-detect&quot;&gt;Enumerable#detect&lt;/a&gt; veja:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;games&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;detect&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;53&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; #&amp;lt;OpenStruct id=53, name=&quot;Gears of War&quot;, gender=&quot;action&quot;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Então fica a dica precisando buscar em uma coleção, uma coleção de objetos que satisfaçam uma certa condição utilizar o &lt;code class=&quot;highlighter-rouge&quot;&gt;select&lt;/code&gt;, precisando retornar um único valor que satisfaça a condição utilizar o &lt;code class=&quot;highlighter-rouge&quot;&gt;detect&lt;/code&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/prefira-composicao-ao-inves-de-heranca-um-simples-exemplo-em-ruby</id>
   <title>Prefira composição ao invés de herança, um simples exemplo em Ruby</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/prefira-composicao-ao-inves-de-heranca-um-simples-exemplo-em-ruby.html"/>
   <updated>2013-02-15T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Um dos princípios da orientação a objetos é:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Prefira composição de objetos à herança de classes&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;como é descrito no &lt;a href=&quot;http://en.wikipedia.org/wiki/Design_Patterns&quot;&gt;livro Design Patterns: Elements of Reusable Object-Oriented Software da GoF&lt;/a&gt;.
Vamos agora ver um exemplo prático em ruby de como podemos usar composição ao invés de herança.&lt;/p&gt;

&lt;h2 id=&quot;o-problema&quot;&gt;O problema&lt;/h2&gt;

&lt;p&gt;Nossas classes representam um carro e os componentes que podem ser adicionados ao carro, os componentes são alarme e ar-condicionado, e o que precisamos saber ao final é o preço do carro.&lt;/p&gt;

&lt;h2 id=&quot;usando-herana&quot;&gt;Usando herança&lt;/h2&gt;

&lt;p&gt;Seguindo uma implementação baseada em herança teríamos algo assim:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Car&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;price&lt;/span&gt;
    &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CarWithAlarm&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Car&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;price&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CarWithAirConditioning&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Car&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;price&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CarWithAlarmAndAirConditioning&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Car&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;price&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Nossas classes são bem simples e usadas assim:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Car&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 1.0&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CarWithAlarm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 1.2&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CarWithAirConditioning&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;price&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 1.3&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CarWithAlarmAndAirConditioning&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;price&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 1.5&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Os 2 primeiros casos (&lt;code class=&quot;highlighter-rouge&quot;&gt;CarWithAlarm&lt;/code&gt; e &lt;code class=&quot;highlighter-rouge&quot;&gt;CarWithAirConditioning&lt;/code&gt;) funcionam muito bem, já o terceiro caso &lt;code class=&quot;highlighter-rouge&quot;&gt;CarWithAlarmAndAirConditioning&lt;/code&gt; temos os seguintes problemas:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;repetição&lt;/strong&gt; - pois pegamos o valor adicionado de &lt;code class=&quot;highlighter-rouge&quot;&gt;CarWithAlarm&lt;/code&gt; e &lt;code class=&quot;highlighter-rouge&quot;&gt;CarWithAirConditioning&lt;/code&gt; e somamos para chegar ao preço de &lt;code class=&quot;highlighter-rouge&quot;&gt;CarWithAlarmAndAirConditioning&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;dificil de manter&lt;/strong&gt; - pois se o valor de &lt;code class=&quot;highlighter-rouge&quot;&gt;CarWithAlarm&lt;/code&gt; mudar teremos que lembrar de alterar em &lt;code class=&quot;highlighter-rouge&quot;&gt;CarWithAlarmAndAirConditioning&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;dificil de estender&lt;/strong&gt; - imagine se tivermos mais um componente, Radio, teremos que criar:
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;CarWithRadio&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;CarWithRadioAndAlarm&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;CarWithRadioAndAirConditioning&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;CarWithRadioAlarmAndAirConditioning&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;deu para perceber que estamos fazendo errado né? Vamos agora ao exemplo usando composição.&lt;/p&gt;

&lt;h2 id=&quot;usando-composio&quot;&gt;Usando composição&lt;/h2&gt;

&lt;p&gt;Primeiro criamos a nossa classe &lt;code class=&quot;highlighter-rouge&quot;&gt;Car&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Car&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@price&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@components&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;add_component&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@components&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;component&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;price&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@components&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;inject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Vamos analisar a nossa classe.&lt;/p&gt;

&lt;h3 id=&quot;initialize&quot;&gt;Initialize&lt;/h3&gt;

&lt;p&gt;Criamos 2 váriaveis de instância:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;@price&lt;/code&gt; que é o preço do nosso carro&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;@components&lt;/code&gt; um array para armazenar os componentes de nosso carro&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;addcomponent&quot;&gt;add_component&lt;/h3&gt;

&lt;p&gt;Método que adiciona um componente ao nosso carro.&lt;/p&gt;

&lt;h3 id=&quot;price&quot;&gt;price&lt;/h3&gt;

&lt;p&gt;Retorna o preço total do carro&lt;/p&gt;

&lt;p&gt;Tendo nossa classe &lt;code class=&quot;highlighter-rouge&quot;&gt;Car&lt;/code&gt; criada vamos as classes de componentes:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Alarm&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;price&lt;/span&gt;
    &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AirConditioning&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;price&lt;/span&gt;
    &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Agora com nossas classes de componentes criadas, vamos a um exemplo de como podemos usar a nossa classe &lt;code class=&quot;highlighter-rouge&quot;&gt;Car&lt;/code&gt;, agora utilizando de composição.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;car&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Car&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;car&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add_component&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Alarm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;car&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 1.2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Como pode ver obtivemos o mesmo resultado que tinhamos com a classe &lt;code class=&quot;highlighter-rouge&quot;&gt;CarWithAlarm&lt;/code&gt;, agora se precisarmos ter o mesmo resultado de &lt;code class=&quot;highlighter-rouge&quot;&gt;CarWithAlarmAndAirConditioning&lt;/code&gt; fariamos:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;car&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Car&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;car&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add_component&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Alarm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;car&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add_component&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;AirConditioning&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;car&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;price&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; 1.5&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;como podemos ver com composição obtivemos um código bem mais fácil de se &lt;strong&gt;manter&lt;/strong&gt;, &lt;strong&gt;estender&lt;/strong&gt; e sem &lt;strong&gt;repetições&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Usámos o carro e seus componentes, mas poderia ser a modelagem de uma transação bancária que possui diversas taxas diferentes por exemplo.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/usando-o-simpledelegator-para-criar-decorators-em-ruby</id>
   <title>Usando o SimpleDelegator para criar decorators em Ruby</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/usando-o-simpledelegator-para-criar-decorators-em-ruby.html"/>
   <updated>2013-02-13T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Recentemente postei no &lt;a href=&quot;http://helabs.com.br/blog&quot;&gt;blog da HE:labs&lt;/a&gt; sobre &lt;a href=&quot;http://helabs.com.br/blog/2013/01/28/extraindo-a-responsabilidade-de-fat-models-com-o-uso-de-decorators/&quot;&gt;como extrair responsabilidade de models no rails utilizando-se de decorators&lt;/a&gt; para quem curtiu e já está utilizando decorators em suas apps apresento agora o &lt;a href=&quot;http://www.ruby-doc.org/stdlib-1.9.3/libdoc/delegate/rdoc/SimpleDelegator.html&quot;&gt;SimpleDelegator&lt;/a&gt; que nos ajuda a criar nossos decorators.&lt;/p&gt;

&lt;p&gt;Imagine que tenhamos a seguinte classe:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Saiyajin&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;attr_accessor&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:name&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;uma simples classe ruby, mas que poderia ser um de seus models active record por exemplo.&lt;/p&gt;

&lt;p&gt;A nossa classe é utilizada assim:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;goku&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Saiyajin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Goku&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;goku&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;Goku&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Agora iremos criar o Super Sayajin, vamos a nossa classe:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;delegate&#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SuperSaiyajin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SimpleDelegator&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; super saiyajin&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;power&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;It&#39;s Over 9000!&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;a nossa classe Super Sayajin poderia ser utilizada assim:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;goku&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SuperSaiyajin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;goku&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;goku&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;Goku super saiyajin&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;goku&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;power&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &quot;It&#39;s Over 9000!&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Criando o nosso decorator herdando de &lt;code class=&quot;highlighter-rouge&quot;&gt;SimpleDelegator&lt;/code&gt; não precisamos criar um &lt;code class=&quot;highlighter-rouge&quot;&gt;initialize&lt;/code&gt; e agora o nosso decorator responde a todos os métodos da classe “decorada”. Perceba que podemos utilizar o &lt;code class=&quot;highlighter-rouge&quot;&gt;super&lt;/code&gt; para nos referenciarmos a métodos da classe “decorada”, como usamos em &lt;code class=&quot;highlighter-rouge&quot;&gt;SuperSaiyajin#name&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Fica a dica do &lt;code class=&quot;highlighter-rouge&quot;&gt;SimpleDelegator&lt;/code&gt; para quando formos criar nossos decorators. Se você não conhecia o &lt;code class=&quot;highlighter-rouge&quot;&gt;SimpleDelegator&lt;/code&gt; ou usa outra abordagem comenta aí.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/javascript-string-multilinha</id>
   <title>JavaScript - string multilinha</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/javascript-string-multilinha.html"/>
   <updated>2012-08-31T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Ao tentarmos escrever uma string multilinha em JavaScript do seguinte modo:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;MY
awesome
string&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;recebemos o seguinte erro:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;SyntaxError: unterminated string literal
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Para “resolver” podemos concatenar a string fazendo assim:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;My &quot;&lt;/span&gt;
       &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;awesome &quot;&lt;/span&gt;
       &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;que até funciona, mais não seria a melhor abordagem.&lt;/p&gt;

&lt;p&gt;No entanto podemos usar a seguinte sintaxe, para enfim escrevermos strings multilinhas no JavaScript:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;MY \
awesome \
string&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Está última abordagem funciona tanto com aspas simples como duplas.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/vcr-e-dados-sensiveis-como-email-e-senha</id>
   <title>VCR e dados sensíveis como email e senha</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/vcr-e-dados-sensiveis-como-email-e-senha.html"/>
   <updated>2012-08-30T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Quando estamos utilizando o &lt;a href=&quot;https://github.com/myronmarston/vcr&quot;&gt;VCR&lt;/a&gt; em nossas specs podemos nos deparar com o seguinte problema: como passar dados sensíveis ao VCR, como senhas e emails, mais não salvar isto em nosso cassete?&lt;/p&gt;

&lt;p&gt;Vamos usar um exemplo real. Ao utilizarmos a api do &lt;a href=&quot;http://site.moip.com.br/&quot;&gt;moip&lt;/a&gt; de pagamento transparente temos que fazer um POST em uma uri&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://MOIP_TOKEN:MOIP_KEY@desenvolvedor.moip.com.br/sandbox/ws/alpha/EnviarInstrucao/Unica
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;utilizando &lt;a href=&quot;http://en.wikipedia.org/wiki/Basic_access_authentication&quot;&gt;Basic Authentication&lt;/a&gt;. Em um projeto interno, sem problemas deixar o seu dado de user e password nas specs, afinal o projeto é seu. Já em um projeto open source não seria legal todos terem acesso ao mesmo ambiente de desenvolvimento que você.&lt;/p&gt;

&lt;p&gt;Para resolver isto devemos criar uma configuração no VCR, para isto em &lt;code class=&quot;highlighter-rouge&quot;&gt;spec/support&lt;/code&gt; crie um arquivo com o nome de &lt;code class=&quot;highlighter-rouge&quot;&gt;vcr.rb&lt;/code&gt; e nele devemos definir além do padrão do vcr que já usamos o:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;VCR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;configure&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;filter_sensitive_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;&amp;lt;MOIP_KEY&amp;gt;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;my_key&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;filter_sensitive_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;&amp;lt;MOIP_TOKEN&amp;gt;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;my_token&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Agora em todos os cassetes que o VCR gerá teremos algo assim:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://&amp;lt;MOIP_TOKEN&amp;gt;:&amp;lt;MOIP_KEY&amp;gt;@desenvolvedor.moip.com.br/sandbox/ws/alpha/EnviarInstrucao/Unica.
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;No entanto ainda não está bom, afinal apenas movemos os dados sensíveis de um lugar para o outro.
Para resolvermos de verdade isto podemos usar variaveis de ambiente, assim a única coisa que tem que fazer é definir as variáveis de ambiente em seu sistema e na configuração do VCR mudar para&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;VCR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;configure&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;filter_sensitive_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;&amp;lt;MOIP_KEY&amp;gt;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ENV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;MOIP_KEY&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;filter_sensitive_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;&amp;lt;MOIP_TOKEN&amp;gt;&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ENV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;MOIP_TOKEN&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Pronto! Agora temos um modo de distribuir uma gem, com as specs funcionando, e sem a necessidade de deixarmos hard coded nossas informações.&lt;/p&gt;

&lt;p&gt;Para quem utilza o &lt;a href=&quot;https://rvm.io/&quot;&gt;rvm&lt;/a&gt; e seu arquivo &lt;a href=&quot;https://rvm.io/workflow/rvmrc/&quot;&gt;.rvmrc&lt;/a&gt;, pode definir no .rvmrc as váriaveis de ambiente, assim elas serão carregadas apenas quando estiver dentro do diretório do projeto.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MOIP_KEY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;my_key&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MOIP_TOKEN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;my_token&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Não se esqueça de sair e entrar no diretório novamente caso tenha acabado de definir as variáveis de ambiente e de documentar a sua gem para quem for testar definir as váriaveis de ambiente.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/conheca-o-pluck-do-activerecord</id>
   <title>Conheça o pluck do ActiveRecord</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/conheca-o-pluck-do-activerecord.html"/>
   <updated>2012-08-13T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;No rails, quando precisamos selecionar apenas o valor de uma coluna especifica de uma coleção de um objeto ActiveRecord podemos fazer algo como:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;e obtemos a resposta algo como:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Foo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Bar&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;no entanto a partir do &lt;a href=&quot;http://guides.rubyonrails.org/3_2_release_notes.html&quot;&gt;rails 3.2&lt;/a&gt; podemos usar o método &lt;a href=&quot;http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-pluck&quot;&gt;pluck&lt;/a&gt; do ActiveRecord. Ficando o nosso exemplo anterior com o pluck assim:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;pluck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Aparentemente não tem diferenças, afinal ambos ocupam apenas uma linha. No entanto ao utilizarmos o primeiro método estamos instanciando N objetos ActiveRecord e com o map obtendo o valor de cada um deles e retornando um array. Já no exemplo que usa o &lt;code class=&quot;highlighter-rouge&quot;&gt;pluck&lt;/code&gt; não precisamos instanciar N objetos ActiveRecord, obtemos o array diretamente.&lt;/p&gt;

&lt;p&gt;Por isso prefira sempre usar o &lt;code class=&quot;highlighter-rouge&quot;&gt;pluck&lt;/code&gt;, afinal é nativo do ActiveRecord e ainda tem uma performance melhor do que a solução com o &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/views-mais-limpas-ao-usar-i18n</id>
   <title>Views mais limpas ao usar I18n</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/views-mais-limpas-ao-usar-i18n.html"/>
   <updated>2012-08-10T00:00:00+00:00</updated>
   <content type="html">&lt;h2 id=&quot;melhorando-as-views-com-o-i18n&quot;&gt;Melhorando as views com o I18n&lt;/h2&gt;

&lt;p&gt;Quando estamos trabalhando com I18n no rails as vezes podemos nos deparar com algo como o código a seguir em nossas views:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;posts.index.title&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;veja que temos que passar por várias sessões do yml para chegarmos ao título que queremos exibir.&lt;/p&gt;

&lt;p&gt;Agora imagine que tenhamos em nossa pasta de views a seguinte estrutura:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;posts
  - index.html.haml
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;e em nosso yml&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pt-BR:
  posts:
    index:
      title: Meu título
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;podemos usar em nossa view (&lt;strong&gt;views/posts/index.html.haml&lt;/strong&gt;) apenas:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;.title&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;isso funciona desde que mantenhamos a convenção no yml, de manter as sessões do yml a mesma da estrutura de pastas das views.&lt;/p&gt;

&lt;h2 id=&quot;removendo-o-htmlsafe-das-views&quot;&gt;Removendo o .html_safe das views&lt;/h2&gt;

&lt;p&gt;Caso algum dos seus arquivos de tradução possua alguma tag html, você já deve ter encontrado algo assim nas views:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;.title&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;html_safe&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;este último para dar escape das tags html.&lt;/p&gt;

&lt;p&gt;No entanto isto poderia ser feito no yml como a seguir.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pt-BR:
  posts:
    index:
      title_html: Meu &amp;lt;strong&amp;gt;título&amp;lt;/strong&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;definindo o sufixo &lt;code class=&quot;highlighter-rouge&quot;&gt;_html&lt;/code&gt; no yml você não precisa mais usar o &lt;code class=&quot;highlighter-rouge&quot;&gt;html_safe&lt;/code&gt; podendo fazer apenas.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;.title&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/whitespace-textmate-bundle-removendo-espacos-em-branco-indesejaveis</id>
   <title>Whitespace TextMate Bundle - removendo espaços em branco indesejáveis</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/whitespace-textmate-bundle-removendo-espacos-em-branco-indesejaveis.html"/>
   <updated>2012-08-07T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;É chato ter espaços em branco após suas declarações de código, piora ainda para quem é da sua equipe e quando da um &lt;code class=&quot;highlighter-rouge&quot;&gt;git pull&lt;/code&gt; recebe seu código com uns espaços em branco sem sentido. Quem usa o textmate pode usar o &lt;a href=&quot;https://github.com/vigetlabs/whitespace-tmbundle&quot;&gt;Whitespace TextMate Bundle&lt;/a&gt; é um bundle bem simples, mas muito útil, a única coisa que ele faz é: &lt;strong&gt;antes de salvar o seu artigo ele remove qualquer espaço em branco desnecessário&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Para instalar apenas execute os seguintes comandos abaixo no terminal:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;mkdir -p ~/Library/Application&lt;span class=&quot;se&quot;&gt;\ &lt;/span&gt;Support/TextMate/Pristine&lt;span class=&quot;se&quot;&gt;\ &lt;/span&gt;Copy/Bundles/
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/Library/Application&lt;span class=&quot;se&quot;&gt;\ &lt;/span&gt;Support/TextMate/Pristine&lt;span class=&quot;se&quot;&gt;\ &lt;/span&gt;Copy/Bundles/
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git clone git://github.com/vigetlabs/whitespace-tmbundle.git Whitespace.tmbundle
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;osascript -e &lt;span class=&quot;s1&quot;&gt;&#39;tell app &quot;TextMate&quot; to reload bundles&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Verifique se o bundle foi instalado corretamente acessando no textmate &lt;strong&gt;Bundles&lt;/strong&gt; e na listagem procure por &lt;strong&gt;Whitespace&lt;/strong&gt;. Caso o bundle não apareça na lista faça &lt;strong&gt;Bundles&lt;/strong&gt; &amp;gt; &lt;strong&gt;Bundle Editor&lt;/strong&gt; &amp;gt; &lt;strong&gt;Reload Bundles&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;E é isso, agora sempre ao salvar um arquivo, este terá seus espaços em branco removidos.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/php-hackday</id>
   <title>PHP HackDay</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/php-hackday.html"/>
   <updated>2012-03-06T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Dia 03/03/2012 ocorreu na &lt;a href=&quot;http://www.iparos.com.br/&quot;&gt;Íparos&lt;/a&gt; o PHP HackDay organizado pelo pessoal do &lt;a href=&quot;http://phprio.org/&quot;&gt;php rio&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;pela-manh&quot;&gt;Pela manhã&lt;/h2&gt;

&lt;p&gt;Por volta das 9:30 da manhã já tínhamos um pessoal presente no evento. Ficou por conta do &lt;a href=&quot;https://twitter.com/raph_almeida&quot;&gt;Raphael&lt;/a&gt; explicar pro pessoal a proposta do evento.&lt;/p&gt;

&lt;h3 id=&quot;phpt&quot;&gt;PHPT&lt;/h3&gt;

&lt;p&gt;Após a introdução do Raphael sobre o evento, ficou por conta do Raphael e do &lt;a href=&quot;https://twitter.com/alganet&quot;&gt;Alganet&lt;/a&gt; um mão na massa sobre como escrever testes para o PHP utilizando o PHPT. Vimos um pouco sobre como baixar o package do php, para depois rodarmos os testes, além disso vimos a sintaxe, e o processo de como rodar os testes com o PHPT. Pensamos em desenvolver alguns testes para a biblioteca &lt;a href=&quot;http://br2.php.net/manual/en/book.dom.php&quot;&gt;DOM&lt;/a&gt; do PHP, no entanto acabamos ficando apenas com os exemplos, afinal tínhamos bastante coisas para o dia.&lt;/p&gt;

&lt;h3 id=&quot;xpath&quot;&gt;XPath&lt;/h3&gt;

&lt;p&gt;Como estávamos pensando em desenvolver testes para a biblioteca DOM precisava a galera toda ter uma noção sobre XPath. Alganet foi “intimado” a dar um mão na massa. Vimos alguns exemplos de seletores utilizando o XPath, recriamos alguns seletores de CSS em XPath e vimos alguns seletores XPath que só seriam possíveis com o XPath.&lt;/p&gt;

&lt;h3 id=&quot;git&quot;&gt;Git&lt;/h3&gt;

&lt;p&gt;Depois do Alganet, foi a vez deste que vos escreve. O Raphael me perguntou se eu queria apresentar a palestra, pensei que não seria tão interessante para o pessoal que estava presente, mais fui convencido, devido a galera já utilizar o git no dia a dia. Apresentei a palestra passando por alguns pontos bem rapidamente e fiquei o restante do tempo tirando dúvidas do pessoal. Se assistiu a palestra comenta ae se gostou.&lt;/p&gt;

&lt;h2 id=&quot;o-almoo&quot;&gt;O almoço&lt;/h2&gt;

&lt;p&gt;No almoço estamos em dúvida entre pedir pizza para continuarmos na sala ou irmos a algum lugar, depois de todos votarem e escolhermos o sabor das pizzas para entrega, resolvemos ir comer no &lt;a href=&quot;http://maps.google.com.br/?q=Vulc%C3%A3o%20das%20Massas,%20Rio%20de%20Janeiro&amp;amp;output=embed&quot;&gt;Vulcão das massas&lt;/a&gt;, onde fomos em um rodízio de massas. Onde possuía a melhor pizza de banana do Rio de Janeiro de acordo com o garçom, lembrando que eles só tinham &lt;strong&gt;2 sabores de pizza&lt;/strong&gt;, mussarela e banana,  mais eles tinham mais massas também, graças a &lt;a href=&quot;https://twitter.com/vivocah&quot;&gt;Vivi&lt;/a&gt; e seus poderes de persuasão eles fizeram mais um sabor de pizza o de calabresa.&lt;/p&gt;

&lt;h2 id=&quot;a-tarde&quot;&gt;A tarde&lt;/h2&gt;

&lt;p&gt;Voltando do almoço, chegamos um pouco mais cedo que o &lt;a href=&quot;https://twitter.com/andrepfeiffer&quot;&gt;André&lt;/a&gt;, assim não podiamos entrar na íparos. Mais o pessoal não desanimou e continuamos as conversas do almoço na frente da íparos até o retorno do André.&lt;/p&gt;

&lt;h3 id=&quot;xdebug&quot;&gt;Xdebug&lt;/h3&gt;

&lt;p&gt;Para continuar o evento depois do almoço foi a vez do &lt;a href=&quot;https://twitter.com/vitormattosrj&quot;&gt;Vitor&lt;/a&gt; iniciar com uma palestra/mão na massa sobre Xdebug. Onde ele mostrou como instalar e configurar, em diversas IDEs inclusive, e como utilizar o Xdebug para o debug em si e para fazer o profiling de aplicações.&lt;/p&gt;

&lt;h3 id=&quot;arquitetura-de-aplicaes-web-modernas&quot;&gt;Arquitetura de Aplicações Web Modernas&lt;/h3&gt;

&lt;p&gt;Logo em seguida foi a vez do &lt;a href=&quot;https://twitter.com/alganet&quot;&gt;Alganet&lt;/a&gt;, em que em sua palestra falou sobre arquitetura de aplicações web e como podemos manter um equilíbrio em nossa arquitetura para conseguirmos manutenção, performance, escalabilidade etc. Falou também sobre aranhas e carrapatos =)&lt;/p&gt;

&lt;h3 id=&quot;tcnicas-para-ser-escalvel-com-php&quot;&gt;Técnicas para ser escalável com PHP&lt;/h3&gt;

&lt;p&gt;Finalizando as palestras, foi a vez do &lt;a href=&quot;https://twitter.com/filaruina&quot;&gt;Filipe&lt;/a&gt; em que apresentou algumas técnicas para escalar um site com PHP, falando bastante sobre cache, filas e arquitetura.&lt;/p&gt;

&lt;h3 id=&quot;papo-de-corredor&quot;&gt;Papo de corredor&lt;/h3&gt;

&lt;p&gt;Finalizada as palestras fizemos uma pausa. Foi o momento em que diversos núcleos foram se montando organicamente e em que cada um falava sobre o que quisesse, tudo acontecendo naturalmente. No que eu estava, estávamos conversando sobre REST e Hypermedia, discutindo sobre o que era o que não era Rest as vantagens de Hypermidia etc.&lt;/p&gt;

&lt;h3 id=&quot;boleto-php&quot;&gt;Boleto PHP&lt;/h3&gt;

&lt;p&gt;Agora era a vez do &lt;a href=&quot;https://twitter.com/israelst&quot;&gt;Israel&lt;/a&gt; nos apresentar o &lt;a href=&quot;http://boletophp.com.br/&quot;&gt;Boleto PHP&lt;/a&gt;, no qual é mantenedor, conhecer o projeto todos devem conhecer mais ele nos mostrou mais os internals e a história do projeto até o momento. Decidimos também em dar um gás no projeto, que seria desde refatorar o código, arrumar o site entre outras coisas. O código do projeto pode ser encontrado no &lt;a href=&quot;https://github.com/BielSystems/boletophp&quot;&gt;github&lt;/a&gt;.
O André também sugeriu de ser uma coisa constante a contribuição de um projeto open source acontecer lá na íparos, iniciando este mês, por isso aconpanhe a &lt;a href=&quot;http://groups.google.com/group/phprio-org&quot;&gt;lista de discussões do PHP Rio&lt;/a&gt; e o &lt;a href=&quot;https://twitter.com/andrepfeiffer&quot;&gt;twitter do André&lt;/a&gt; para saber mais sobre isto.&lt;/p&gt;

&lt;h3 id=&quot;sorteio-e-finalizao-do-evento&quot;&gt;Sorteio e finalização do evento&lt;/h3&gt;

&lt;p&gt;Para finalizar o evento foram sorteados 2 livros, um para os presentes e um para os palestrantes, cedidos pela &lt;a href=&quot;http://www.novatec.com.br/&quot;&gt;novatec&lt;/a&gt;. Uns mousepads cedidos pelo Alganet em nome do &lt;a href=&quot;http://br.yahoo.com/&quot;&gt;Yahoo!&lt;/a&gt; e uma garrafa térmica da &lt;a href=&quot;http://www.microsoft.com/pt-br/default.aspx&quot;&gt;microsoft&lt;/a&gt; que não sei quem cedeu.&lt;/p&gt;

&lt;p&gt;O &lt;a href=&quot;https://twitter.com/filaruina&quot;&gt;Filipe&lt;/a&gt; ganhou o livro &lt;a href=&quot;http://www.novatec.com.br/livros/scrum/&quot;&gt;Scrum em Ação&lt;/a&gt; e eu ganhei o livro &lt;a href=&quot;http://www.novatec.com.br/livros/expressoesregulares/&quot;&gt;Expressões Regulares - Uma abordagem divertida 3ª edição&lt;/a&gt;. Como o Filipe queria mais o livro que ganhei e eu queria mais o que ele ganhou trocamos, pois eu já possuía o de expressões regulares. Ganhei um mousepad de “caridade” também =)&lt;/p&gt;

&lt;p&gt;O Raphael também distribuiu camisas do PHP n’rio 11, eu ganhei uma, ele falou que foi distribuído no evento ano passado, eu devo ter saído um pouco antes do fim pois não tinha a camisa.&lt;/p&gt;

&lt;p&gt;E assim acabou o PHP HackDay que ocorreu em 03/03/2012 na íparos.&lt;/p&gt;

&lt;h2 id=&quot;phpinga&quot;&gt;PHPinga&lt;/h2&gt;

&lt;p&gt;Finalizado o evento, uns foram embora, eu fui um desses, e o pessoal partiu para o PHPinga. Infelizmente não tenho muito o que dizer pois não fui =)&lt;/p&gt;

&lt;h2 id=&quot;palestras&quot;&gt;Palestras&lt;/h2&gt;

&lt;p&gt;Abaixo as palestras que encontrei que aconteceu no evento, se tiver mais pode mandar que eu incluo.&lt;/p&gt;

&lt;h3 id=&quot;git-para-iniciantes&quot;&gt;Git para iniciantes&lt;/h3&gt;

&lt;div style=&quot;width:425px&quot; id=&quot;__ss_11845714&quot;&gt; &lt;strong style=&quot;display:block;margin:12px 0 4px&quot;&gt;&lt;a href=&quot;http://www.slideshare.net/maurogeorge/git-para-iniciantes&quot; title=&quot;Git para iniciantes&quot; target=&quot;_blank&quot;&gt;Git para iniciantes&lt;/a&gt;&lt;/strong&gt; &lt;iframe src=&quot;http://www.slideshare.net/slideshow/embed_code/11845714&quot; width=&quot;425&quot; height=&quot;355&quot; frameborder=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt; &lt;div style=&quot;padding:5px 0 12px&quot;&gt; View more &lt;a href=&quot;http://www.slideshare.net/&quot; target=&quot;_blank&quot;&gt;presentations&lt;/a&gt; from &lt;a href=&quot;http://www.slideshare.net/maurogeorge&quot; target=&quot;_blank&quot;&gt;maurogeorge&lt;/a&gt; &lt;/div&gt; &lt;/div&gt;

&lt;h3 id=&quot;arquitetura-de-aplicaes-web-modernas-1&quot;&gt;Arquitetura de Aplicações Web Modernas&lt;/h3&gt;

&lt;script src=&quot;http://speakerdeck.com/embed/4f54a9f42b27ce001f007dea.js&quot;&gt;&lt;/script&gt;

&lt;h3 id=&quot;tcnicas-para-ser-escalvel-com-php-1&quot;&gt;Técnicas para ser escalável com PHP&lt;/h3&gt;

&lt;div style=&quot;width:425px&quot; id=&quot;__ss_10048946&quot;&gt; &lt;strong style=&quot;display:block;margin:12px 0 4px&quot;&gt;&lt;a href=&quot;http://www.slideshare.net/filaruina/tcnicas-para-ser-escalvel-com-php&quot; title=&quot;Técnicas para ser escalável com PHP&quot; target=&quot;_blank&quot;&gt;Técnicas para ser escalável com PHP&lt;/a&gt;&lt;/strong&gt; &lt;iframe src=&quot;http://www.slideshare.net/slideshow/embed_code/10048946&quot; width=&quot;425&quot; height=&quot;355&quot; frameborder=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt; &lt;div style=&quot;padding:5px 0 12px&quot;&gt; View more &lt;a href=&quot;http://www.slideshare.net/&quot; target=&quot;_blank&quot;&gt;presentations&lt;/a&gt; from &lt;a href=&quot;http://www.slideshare.net/filaruina&quot; target=&quot;_blank&quot;&gt;Filipe La Ruina&lt;/a&gt; &lt;/div&gt; &lt;/div&gt;

&lt;h2 id=&quot;vdeo&quot;&gt;Vídeo&lt;/h2&gt;

&lt;p&gt;O André tentou fazer o streaming mais não ficou legal o som, &lt;a href=&quot;http://pt-br.justin.tv/andrepfeiffer/b/310461480&quot;&gt;ta ae o link do vídeo&lt;/a&gt;, acho que ele deletou os demais vídeos só achei este.&lt;/p&gt;

&lt;h2 id=&quot;agradecimentos&quot;&gt;Agradecimentos&lt;/h2&gt;

&lt;p&gt;Acho legal agradecer aqui a Íparos e ao André pelo espaço e novatec pelos livros cedidos, ao Alganet por ter vindo de São Paulo, sem patrócinio do evento para palestrar e a todos os que estavam presentes no evento.&lt;/p&gt;

&lt;h2 id=&quot;para-refletir-um-pouco&quot;&gt;Para refletir um pouco&lt;/h2&gt;

&lt;p&gt;Não entendo o pessoal que trabalha com tecnologia e não aparece nos eventos por &lt;strong&gt;algum motivo bobo ou desculpa&lt;/strong&gt; ou apenas aparece apenas nos eventos “grandes”. Acredito que se você trabalha com tecnologia ou qualquer outra coisa, mais não curte, deveria rever sua vida em relação a isto. Deixo um trecho de um &lt;a href=&quot;http://dojorio.org/2010/04/10/forkinrio2/#comment-148&quot;&gt;comentário meu no blog do dojo rio&lt;/a&gt; em que fui icentivado pelo &lt;a href=&quot;http://twitter.com/henriquebastos&quot;&gt;Henrique Bastos&lt;/a&gt; no primeiro evento de tecnologia que eu fui:&lt;/p&gt;
&lt;blockquote&gt;
Resumindo depois de ter me alongado muito, valeu mais a pena ver uma palestra “humana” para 30 pessoas do que uma para mais de 200 em que provavelmente o conteúdo se perderia e seria muito superficial. Então é isso quem quiser se juntar ao grupo vale muito a pena devido a amizade e de aprender todos juntos, e se morar longe tenta aparecer pelo menos nos que ocorrem de dia, afinal para eu chegar a casa do Bernardo tive que acordar 6:20, começava as 9:00, e pegar 3 ônibus, mais valeu a pena.
&lt;/blockquote&gt;

&lt;p&gt;Para ler o comentário completo pode acessar o link &lt;a href=&quot;http://dojorio.org/2010/04/10/forkinrio2/#comment-148&quot;&gt;http://dojorio.org/2010/04/10/forkinrio2/#comment-148&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Deixo aqui a proposta de que se foi o primeiro evento que foi ou se de algum modo foi importante para você, escreva um post num blog, pode colar o link aqui nos comentário, ou simplesmente comente aqui.&lt;/p&gt;

&lt;p&gt;Grande abraço pessoal!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/testando-no-internet-explorer-6-7-8-e-9-no-mac-os-e-linux-utilizando-maquinas-virtuais</id>
   <title>Testando no Internet explorer 6, 7, 8 e 9 no Mac Os e Linux utilizando máquinas virtuais</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/testando-no-internet-explorer-6-7-8-e-9-no-mac-os-e-linux-utilizando-maquinas-virtuais.html"/>
   <updated>2012-02-11T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;A Microsft disponibiliza vários &lt;a href=&quot;http://www.microsoft.com/download/en/details.aspx?id=11575&quot;&gt;VHDs com Windows&lt;/a&gt; para os desenvolvedores poderem testar suas aplicações nos internet explorer’s 6, 7, 8 e 9 no entanto estes VHDs foram feitos para ser usado no Microsoft’s VirtualPC e fazer ele funcionar fora deste ambiente pode ser bastante irritante. No entanto para facilitar a nossa vida &lt;a href=&quot;https://github.com/xdissent&quot;&gt;Greg Thornton&lt;/a&gt; criou um &lt;a href=&quot;https://github.com/xdissent/ievms/blob/master/ievms.sh&quot;&gt;script shell&lt;/a&gt; que resolve tudo para nós.&lt;/p&gt;

&lt;h2 id=&quot;requisitos&quot;&gt;Requisitos&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://virtualbox.org&quot;&gt;VirtualBox&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Curl (Ubuntu: &lt;code&gt;sudo apt-get install curl&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;No Linux apenas: unar (Ubuntu: &lt;code&gt;sudo apt-get install unar&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;Paciência&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;instalao&quot;&gt;Instalação&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.virtualbox.org/wiki/Downloads&quot;&gt;Instalar o VirtualBox&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Baixar e descompactar o as maquinas virtuais
    &lt;ul&gt;
      &lt;li&gt;Instala o IE versões 6, 7, 8 e 9.
    $ curl -s https://raw.github.com/xdissent/ievms/master/ievms.sh | bash&lt;/li&gt;
      &lt;li&gt;Instala versões especificas do IE (IE7 e IE9 por exemplo): 
    $ curl -s https://raw.github.com/xdissent/ievms/master/ievms.sh | IEVMS_VERSIONS=”7 9” bash&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Inicie a máquina virtual&lt;/li&gt;
  &lt;li&gt;Acesse a máquina virtual da versão do internet explorer que quiser utilizar&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A instalação pode demorar muito dependendo de sua conexão, tenha isto em mente.&lt;/p&gt;

&lt;p&gt;Uma vez instalada a &lt;strong&gt;senha de cada uma das máquinas virtuais é “Password1”&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Mais informações podem ser encontradas na &lt;a href=&quot;https://github.com/xdissent/ievms&quot;&gt;página do ievms no github&lt;/a&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/instalando-o-postgresql-no-mac-os-com-o-homebrew</id>
   <title>Instalando o PostgreSQL no Mac OS com o homebrew</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/instalando-o-postgresql-no-mac-os-com-o-homebrew.html"/>
   <updated>2011-12-31T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Para o pessoal que usa Mac deve conhecer o gerenciador de pacotes &lt;a href=&quot;http://mxcl.github.com/homebrew/&quot;&gt;Homebrew&lt;/a&gt;, caso não conheça acesse o &lt;a href=&quot;http://pedromenezes.com/conheca-o-homebrew-o-melhor-gerenciador-de-pacotes-para-mac-os&quot;&gt;post do Pedro Menezes sobre o assunto&lt;/a&gt; e instale o Homebrew.&lt;/p&gt;

&lt;p&gt;Tendo devidamente o homebrew instalado, execute o seguinte comando:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;brew update&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;para atualizar o homebrew e suas formulas.&lt;/p&gt;

&lt;h2 id=&quot;instalando-o-postgresql&quot;&gt;Instalando o PostgreSQL&lt;/h2&gt;

&lt;p&gt;Apenas execute o seguinte comando&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;brew install postgresql&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;e aguarde o homebrew fazer todo o processo de instalação para você. Depois de instalado ainda temos algumas pequenas coisas para fazer.&lt;/p&gt;

&lt;h2 id=&quot;caveats&quot;&gt;&lt;em&gt;Caveats&lt;/em&gt;&lt;/h2&gt;

&lt;p&gt;Depois de instalado o PostgreSQL o homebrew nos informa sobre as ressalvas, ou &lt;em&gt;caveats&lt;/em&gt; em inglês, recomendo a leitura do mesmo para seu conhecimento. Nestas ressalvas ele nos informa alguns passos que devemos seguir.&lt;/p&gt;

&lt;h3 id=&quot;iniciando-o-banco-de-dados&quot;&gt;Iniciando o banco de dados&lt;/h3&gt;

&lt;p&gt;Depois de instalado o PostgreSQL devemos iniciar o banco de dados com o simples comando:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;initdb /usr/local/var/postgres&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;apenas aguarde a execução do comando.&lt;/p&gt;

&lt;h4 id=&quot;problemas-com-encoding&quot;&gt;Problemas com encoding&lt;/h4&gt;

&lt;p&gt;Caso apresente algum problema de encoding no template de banco de dados, pode utilizar o comando a seguir para forçar o PostgreSQL a criar o template em UTF-8 por exemplo:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;initdb /usr/local/var/postgres --locale&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;en_US.UTF-8 --encoding&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;UNICODE&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;mais informações sobre os comandos passados ao initdb no &lt;a href=&quot;http://www.postgresql.org/docs/9.1/static/app-initdb.html&quot;&gt;manual do PostregesSQL&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;iniciando-o-postgresql-aps-realizar-o-login-na-mquina&quot;&gt;Iniciando o PostgreSQL após realizar o login na máquina&lt;/h3&gt;

&lt;p&gt;Caso você queira, o que acredito que seja o seu caso, iniciar o PostgreSQL após realizar o login em sua máquina execute o seguinte comando abaixo:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;mkdir -p ~/Library/LaunchAgents
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;cp /usr/local/Cellar/postgresql/9.1.2/org.postgresql.postgres.plist ~/Library/LaunchAgents/
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;launchctl load -w ~/Library/LaunchAgents/org.postgresql.postgres.plist&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Observe que aqui estamos usando o PostgreSQL 9.1.2 sendo assim a sua instalação mudará o path no comando acima dependendo da versão do PostgreSQL, por isso é importante ler as mensagens que o homebrew lhe informar para inserir o comando acima corretamente.&lt;/p&gt;

&lt;h3 id=&quot;iniciando-e-parando-o-postgresql-manualmente&quot;&gt;Iniciando e parando o PostgreSQL manualmente&lt;/h3&gt;

&lt;p&gt;Caso queira iniciar o PostgreSQL manualmente utilize o comando abaixo:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;e para parar a execução do PostgreSQL utilize o comando abaixo:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;pg_ctl -D /usr/local/var/postgres stop -s -m fast&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;criando-o-super-usurio-postgres&quot;&gt;Criando o super usuário postgres&lt;/h3&gt;

&lt;p&gt;Para criar o super usuário postgres devemos primeiro entrar no psql com&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;psql postgres&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;caso ele reclame de não existir a database postgres utilize o seguinte comando para criar a mesma, em seguida acesse o psql como indicado acima.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;createdb postgres&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Dentro do psql execute o seguinte comando para criar o super usuário postgres e depois para sair do psql utilize &lt;code&gt;\q&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sql&quot; data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;USER&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;postgres&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SUPERUSER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Assim teremos criado o super usuário postgres sem senha para o PostgreSQL.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/git-config-configurando-o-git</id>
   <title>Git config - configurando o git</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/git-config-configurando-o-git.html"/>
   <updated>2011-12-09T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Para quem está usando o git diariamente sabe que tem comandos que digitamos freqüentemente como &lt;code&gt;git status&lt;/code&gt;, &lt;code&gt;git commit&lt;/code&gt;, &lt;code&gt;git checkout&lt;/code&gt; entre outros. Iremos ver como digitar menos e mais algumas configurações legais no git.&lt;/p&gt;

&lt;h2 id=&quot;git-config&quot;&gt;Git config&lt;/h2&gt;

&lt;p&gt;É onde você define configurações do git que podem ser globais que serão válidas para todos os seus repositórios ou configurações de um repositório em especifico.&lt;/p&gt;

&lt;h3 id=&quot;configuraes-globais&quot;&gt;Configurações globais&lt;/h3&gt;

&lt;p&gt;Para inserir alguma configuração com o git usamos o comando &lt;code&gt;git config&lt;/code&gt; e caso queiramos que nossa configuração seja valida para todos os repositórios que criarmos passamos o parâmetro &lt;code&gt;--global&lt;/code&gt; ficando &lt;code&gt;git config --global&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Provavelmente você já executou o seguinte comando, passando seus dados obviamente, ao instalar o git:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config --global user.name &lt;span class=&quot;s2&quot;&gt;&quot;Seu nome&quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config --global user.email &lt;span class=&quot;s2&quot;&gt;&quot;email@example.com&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;caso tenha seguido algum tutorial e não saiba o que esta acontecendo aqui, o que você está fazendo é definir seu nome e email para o git que será usado em &lt;strong&gt;todos&lt;/strong&gt; os seus repositórios.&lt;/p&gt;

&lt;h3 id=&quot;configuraes-por-repositrio&quot;&gt;Configurações por repositório&lt;/h3&gt;

&lt;p&gt;Se ao passarmos o parâmetro &lt;code&gt;--global&lt;/code&gt; definimos a informação para todos os repositórios, ao omitirmos o parâmetro definimos a informação para apenas um de nossos repositórios.&lt;/p&gt;

&lt;p&gt;Lembrando de executar o comando estando &lt;strong&gt;dentro do diretório onde encontra se o repositório que quer definir as configurações&lt;/strong&gt;. Exemplo:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config user.email &lt;span class=&quot;s2&quot;&gt;&quot;email@empresa.com&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Assim você pode definir o email para o email de sua empresa por exemplo enquanto nos demais repositórios o email usado seria o seu pessoal.&lt;/p&gt;

&lt;p&gt;Lembrando que o git é esperto o suficiente e só sobrescreve o que você redefinir e as demais configurações ele mantém. Ou seja no exemplo anterior ainda teriamos o valor nome definido como “Seu nome” em que definimos usando as configurações globais.&lt;/p&gt;

&lt;h2 id=&quot;git-alias&quot;&gt;Git alias&lt;/h2&gt;

&lt;p&gt;Agora que entendemos como definimos as configurações no git, iremos ver como podemos definir alias, um apelido, para os comandos que digitamos freqüentemente. Veja abaixo os alias que costumo definir como global.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config --global alias.co &lt;span class=&quot;s2&quot;&gt;&quot;checkout&quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config --global alias.ci &lt;span class=&quot;s2&quot;&gt;&quot;commit&quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config --global alias.st &lt;span class=&quot;s2&quot;&gt;&quot;status -sb&quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config --global alias.br &lt;span class=&quot;s2&quot;&gt;&quot;branch&quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config --global alias.wdiff &lt;span class=&quot;s2&quot;&gt;&quot;diff --word-diff&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Agora com os alias definidos podemos fazer &lt;code&gt;git ci&lt;/code&gt; ao invés de &lt;code&gt;git commit&lt;/code&gt; quando formos realizar um commit. Além dos demais alias que definimos. Lembrando que você pode definir outros alias que julgar interessante.&lt;/p&gt;

&lt;p&gt;Detalhe que defino como global pois quero isto válido em todos os meus repositórios.&lt;/p&gt;

&lt;h3 id=&quot;um-log-bem-mais-poderoso&quot;&gt;Um log bem mais poderoso&lt;/h3&gt;

&lt;p&gt;Ao executarmos &lt;code&gt;git log&lt;/code&gt; obtemos o log de nossos commits. No entanto vem bastante informação e em um formato não muito agradável de se ler. Podemos melhorar o nosso log adicionando o seguinte alias.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config --global alias.lg &lt;span class=&quot;s2&quot;&gt;&quot;log --graph --pretty=format:&#39;%Cred%h%Creset %Cblue[%an]%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)%Creset&#39; --abbrev-commit&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Agora ao executarmos o comando &lt;code&gt;git lg&lt;/code&gt; teremos um log com mais informações úteis do que o log padrão, lembrando que ainda poderá usar o &lt;code&gt;git log&lt;/code&gt; normalmente.
Não se esqueça que podemos ainda usar o &lt;code&gt;git lg -p&lt;/code&gt; para vermos o diff do que foi alterado nos commits.&lt;/p&gt;

&lt;h2 id=&quot;mais-configuraes&quot;&gt;Mais configurações&lt;/h2&gt;

&lt;h3 id=&quot;editor-de-texto&quot;&gt;Editor de texto&lt;/h3&gt;

&lt;p&gt;Em alguns momentos um editor de texto é chamado pelo git, como ao darmos um commit sem mensagem com o comando &lt;code&gt;git commit&lt;/code&gt;. Para escolhermos o nosso editor de preferencia podemos definir a configuração com o comando:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config --global core.editor &lt;span class=&quot;s2&quot;&gt;&quot;mate -wl1&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Usei aqui o comando para chamar o textmate, e como está em seu &lt;a href=&quot;http://blog.macromates.com/2005/textmate-shell-utility-tmmate/&quot;&gt;blog&lt;/a&gt; devemos passar o parâmetro &lt;code&gt;-w&lt;/code&gt; e o parâmetro adicional &lt;code&gt;l1&lt;/code&gt; que passei é para o cursor se posicionar na primeira linha do arquivo.&lt;/p&gt;

&lt;p&gt;Para o pessoal de linux, que não quiser o Vim, poderíamos definir o gedit por exemplo usando o comando:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config --global core.editor &lt;span class=&quot;s2&quot;&gt;&quot;gedit&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;colorindo-o-terminal&quot;&gt;Colorindo o terminal&lt;/h3&gt;

&lt;p&gt;Se ao executar um &lt;code&gt;git status&lt;/code&gt; por exemplo e não vermos colorido o que foi alterado, ou os novos arquivo por exemplo. É bom definir a configuração abaixo.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config --global color.ui &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;que como você deve imaginar, colore as informações que o git lhe enviar no terminal.&lt;/p&gt;

&lt;h3 id=&quot;o-git-te-corrigindo-ao-digitar-errado&quot;&gt;O git te corrigindo ao digitar errado&lt;/h3&gt;

&lt;p&gt;Em alguns momentos pode acontecer de digitarmos errado como por exemplo digitar &lt;code&gt;git lg&lt;/code&gt; ao invés de &lt;code&gt;git log&lt;/code&gt;. Para não tomarmos um aviso de comando errado simplesmeste, podemos deixar o git definir por nos o que ele acha que tentamos executar, para isso habilitamos a seguinte configuração:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config --global help.autocorrect 1&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Assim ele nos dará um aviso e executará o comando que ele acredita que tentamos digitar.&lt;/p&gt;

&lt;h3 id=&quot;evitando-tiro-de-shotgun-com-o-git-ao-dermos-push&quot;&gt;Evitando tiro de shotgun com o git ao dermos push&lt;/h3&gt;

&lt;p&gt;Como o &lt;a href=&quot;http://twitter.com/argentinomota&quot;&gt;Argentino&lt;/a&gt; diz o git da um tiro de shotgun ao executarmos o &lt;code&gt;git push&lt;/code&gt;, isso por que os commits de outros branches são enviados, mesmo estando em um branch especifico.&lt;/p&gt;

&lt;p&gt;Imagine que tenhamos 3 branches master, feature/awesome-thing e feature/other-thing, ambos feature branches tem commits locais que ainda não foram enviados, estando no branch feature/awesome-thing e executar um &lt;code&gt;git push&lt;/code&gt; &lt;strong&gt;os commits dos 2 feature branches&lt;/strong&gt; serão enviados, pode não ser o comportamento esperado no momento.&lt;/p&gt;

&lt;p&gt;Utilizando o:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config --global push.default current&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;dizemos para o git que no &lt;code&gt;git push&lt;/code&gt; ele deve enviar o conteúdo do branch atual para um branch de mesmo nome. Sendo assim se executassemos o &lt;code&gt;git push&lt;/code&gt; no exemplo anterior, apenas o branch feature/awesome-thing seria enviado, o que faz sentido pois é o branch que estamos no momento. Mais informações e outras configurações possiveis podem ser encontradas no &lt;a href=&quot;http://schacon.github.com/git/git-config.html&quot;&gt;manual do git&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;no-precisando-resolver-conflitos-j-resolvidos&quot;&gt;Não precisando resolver conflitos já resolvidos&lt;/h3&gt;

&lt;p&gt;É comum quando estamos em um feature branch que tenha uma vida relativamente longa, fazermos merge do branch master em nosso feature branch. Em algum destes merges talvez tenhamos que resolver algum conflito. O problema ocorre quando formos fazer merge do nosso feature branch no master, pois teremos que resolver os mesmos conflitos. Para resolvermos isto podemos ativar o &lt;code class=&quot;highlighter-rouge&quot;&gt;rerere&lt;/code&gt;(Reuse recorded resolution of conflicted merges) com o seguinte comando.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config --global rerere.enabled &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;documentao-em-html&quot;&gt;Documentação em HTML&lt;/h3&gt;

&lt;p&gt;Caso queira que a documentação, ao digitar &lt;code&gt;git help comando&lt;/code&gt; seja em HTML pode usar a seguinte configuração:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config --global help.format web&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Assim ao digitar por exemplo &lt;code&gt;git help config&lt;/code&gt; será aberto o browser e poderá ver a documentação do comando digitado em HTML.&lt;/p&gt;

&lt;p&gt;Lembrando que para ver a documentação em HTML a mesma deve ser instalada, &lt;a href=&quot;http://help.github.com/install-git-html-help/&quot;&gt;mais informações de como instalar aqui&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;listando-as-configuraes&quot;&gt;Listando as configurações&lt;/h2&gt;

&lt;p&gt;Agora que você já sabe definir configurações tem que ter um lugar onde seja possível ver o que esta configurado, e para isso usamos o comando&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config -l&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;que executado fora de qualquer repositório listará nossas configurações globais. E ao estar dentro de algum repositório, listará as configurações do repositório em especifico.&lt;/p&gt;

&lt;p&gt;E se ainda assim dentro do diretório do repositório quiser listar as configurações globais. Podemos usar o comando:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git config --global -l&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;shell&quot;&gt;Shell&lt;/h2&gt;

&lt;p&gt;Caso goste de definir seus alias no shell, pode usar o mesmo para definir comandos do git. No mac utilizaríamos o ~/.bash_profile ou o ~/.bash_profile no linux, exemplo:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;alias &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;git checkout &#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;alias &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;gc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;git commit&#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;alias &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;gs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;git status &#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;alias &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;gb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;git branch &#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
</content>
 </entry>
 
 <entry>
   <id>http://groselhas.maurogeorge.com.br/hello-world</id>
   <title>Hello World</title>
   <link type="text/html" href="http://groselhas.maurogeorge.com.br/hello-world.html"/>
   <updated>2011-11-28T00:00:00+00:00</updated>
   <content type="html">&lt;p&gt;Como está em &lt;a href=&quot;/sobre.html&quot; title=&quot;sobre o groselhas&quot;&gt;sobre&lt;/a&gt; falei que o conteúdo aqui seria também sobre o que fosse aprendendo. Inclusive o próprio blog surgiu de um aprendizado.&lt;/p&gt;

&lt;p&gt;Há algum tempo pensava em criar um blog, exatamente com a mesma proposta do groselhas, no entanto ficava adiando isso devido a estar estudando algo, ocupado com outras coisas etc. Até que conheci o &lt;a href=&quot;https://github.com/mojombo/jekyll&quot; title=&quot;github do jekyll&quot;&gt;jekyll&lt;/a&gt;, e como estou iniciando os estudos em ruby e rails resolvi usar o mesmo, já que é desenvolvido em ruby e também como desculpas para agitar um pouco as coisas aqui no github, já que o meu está bastante parado.&lt;/p&gt;

&lt;p&gt;Sendo assim das coisas que nunca havia utilizado e resolvi usar no desenvolvimento do projeto foram:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/mojombo/jekyll&quot; title=&quot;github do jekyll&quot;&gt;Jekyll&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://pages.github.com/&quot; title=&quot;crie páginas para seus repósitorios&quot;&gt;GitHub pages&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://twitter.github.com/bootstrap/&quot; title=&quot;css e JavaScript para ajudar no desenvolvimento de seus projetos&quot;&gt;Twitter bootstrap&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://scr.im/&quot; title=&quot;protege seu email de spammers&quot;&gt;scr.im&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.google.com/recaptcha/mailhide/&quot; title=&quot;este também protege seu email de spammers&quot;&gt;reCaptcha Mailhide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E outras que já utilizei anteriormente, mais que acho legal mencionar foram o&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://beginrescueend.com/&quot; title=&quot;gerencie multiplas versões de Ruby e sets de Gems&quot;&gt;RVM&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://git-scm.com/&quot; title=&quot;excelente sistema de controle de versão, se não o melhor&quot;&gt;Git&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://daringfireball.net/projects/markdown/&quot; title=&quot;escreva markdown e transforme em HTML&quot;&gt;Markdown&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://disqus.com/&quot; title=&quot;plataforma de comentários&quot;&gt;Disqus&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quem sabe em breve não falo um pouco sobre cada uma dessas ferramentas.&lt;/p&gt;
</content>
 </entry>
 

</feed>
