<!DOCTYPE html>
<html class="no-js" lang="en-US" prefix="og: http://ogp.me/ns#">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Posts &#124; Ideia Cabeluda</title>
  <link rel="profile" href="https://gmpg.org/xfn/11">
  <link rel="pingback" href="/xmlrpc.php">
  <link rel="canonical" href="/">
  <link rel="author" href="https://plus.google.com/117356233024012611530?rel=author">
  <meta property="og:locale" content="en_US">
  <meta property="og:type" content="website">
  <meta property="og:title" content="Posts - Ideia Cabeluda">
  <meta property="og:url" content="http://davidpaniz.com/">
  <meta property="og:site_name" content="Ideia Cabeluda">
  <link rel="alternate" type="application/rss+xml" title="Ideia Cabeluda &raquo; Feed" href="/feed/">
  <link rel="alternate" type="application/rss+xml" title="Ideia Cabeluda &raquo; Comments Feed" href="/comments/feed/">
  <link rel='stylesheet' id='responsive-style-css' href='/wp-content/themes/responsive/style.css?ver=1.9.3.4' type='text/css' media='all'>
  <link rel='stylesheet' id='responsive-media-queries-css' href='/wp-content/themes/responsive/core/css/style.css?ver=1.9.3.4' type='text/css' media='all'>
  <link rel='stylesheet' id='wp-paginate-css' href='/wp-content/plugins/wp-paginate/wp-paginate.css?ver=1.2.4' type='text/css' media='screen'>
  <script type='text/javascript' src='/wp-includes/js/jquery/jquery.js?ver=1.10.2'></script>
  <script type='text/javascript' src='/wp-includes/js/jquery/jquery-migrate.min.js?ver=1.2.1'></script>
  <script type='text/javascript' src='/wp-content/themes/responsive/core/js/responsive-modernizr.js?ver=2.6.1'></script>
  <script type='text/javascript' src='/wp-content/plugins/google-analyticator/external-tracking.min.js?ver=6.4.5'></script>
  <link rel="EditURI" type="application/rsd+xml" title="RSD" href="/xmlrpc.php?rsd">
  <link rel="wlwmanifest" type="application/wlwmanifest+xml" href="/wp-includes/wlwmanifest.xml">
  <style type="text/css" id="syntaxhighlighteranchor"></style>
  <script type="text/javascript">
        var analyticsFileTypes = [''];
        var analyticsEventTracking = 'enabled';
  </script>
</head>
<body class="home page page-id-630 page-template page-template-blog-php">
  <div id="container" class="hfeed">
    <div id="header">
      <div id="logo">
        <span class="site-name"><a href="/" title="Ideia Cabeluda" rel="home">Ideia Cabeluda</a></span> <span class="site-description">David Paniz</span>
      </div>
      <div class="main-nav">
        <ul class="menu">
          <li class="current_page_item">
            <a href="/">Home</a>
          </li>
          <li class="page_item page-item-355">
            <a href="/palestras/">Palestras</a>
          </li>
          <li class="page_item page-item-5">
            <a href="/about/">Sobre David Paniz</a>
          </li>
        </ul>
      </div>
    </div>
    <div id="wrapper" class="clearfix">
      <div id="content-blog" class="grid col-620">
        <div id="post-697" class="post-697 post type-post status-publish format-standard hentry category-jogos category-matematica">
          <h2 class="entry-title post-title"><a href="/2012/10/03/matematica-para-jogos-parte-2-a-fisica-da-colisao/" rel="bookmark">Matemática para jogos – Parte 2 – A física da colisão</a></h2>
          <div class="post-meta">
            <span class="meta-prep meta-prep-author posted">Posted on</span> <a href="/2012/10/03/matematica-para-jogos-parte-2-a-fisica-da-colisao/" title="9:43 am" rel="bookmark"><span class="timestamp updated">3 October 2012</span></a> <span class="byline">by</span> <span class="author vcard"><a class="url fn n" href="/author/david-paniz/" title="View all posts by David Paniz">David Paniz</a></span> <span class="comments-link"><span class="mdash">&mdash;</span> <a href="/2012/10/03/matematica-para-jogos-parte-2-a-fisica-da-colisao/#respond" title="Comment on Matemática para jogos – Parte 2 – A física da colisão">No Comments &darr;</a></span>
          </div>
          <div class="post-entry">
            <p>Continuando a série sobre desenvolvimento de jogos, após <a href="/2012/09/13/matematica-para-jogos-parte-1-colisao-de-circulos/">verificar a colisão</a>, o próximo passo é entender o que acontece no mundo real durante uma colisão. Como praticamente todos os simuladores de colisão que achei são feitos em java e tem um applet nojento na página, para poder escrever esse post eu criei um simulador de colisão em html usando canvas e javascript, o jscolisao que também tem código aberto.</p>
            <p><strong>Disclaimer: Não sou físico e posso escrever alguma besteira aqui, então não use esse material para escola, faculdade e afins, mas use à vontade para seus jogos.</strong></p>
            <p>Colisão é um estudo sobre troca de energia e movimento, portanto, quando dizemos que houve uma colisão estamos dizendo que houve uma troca de energia e movimento entre os corpos envolvidos.Voltando ao exemplo do meu jogo, sempre que a bolinha se choca com algum jogador ou parede temos que simular essa troca de velocidade. Neste post vou comentar apenas sobre a colisão na parede, que é mais simples.</p>
            <p>Antes de começar a usar o simulador vamos lembrar um detalhe importante sobre colisões, o tipo de colisão. Existem aquelas colisões onde não existe perda de energia e toda a energia do momento da colisão é mantido, como no famoso Pêndulo de Newton, que num mundo ideal funcionaria eternamente, esse tipo de colisão é chamado colisão elástica. O fator fundamental para esse tipo de colisão é o chamado coeficiente de restituição. Imagine a colisão entre o seu pé e uma bola de futebol, no momento que você a chuta ela visivelmente se deforma, acumulando energia, e depois ela volta à forma original de bola, liberando esta energia. Independente de quão visível é a deformação, a energia sempre é transmitida e cada material tem o seu proprio coeficiente de restituição, que nada mais é do que a quantidade de energia que ele consegue propagar. Para descobrir o coeficiente de restituição de um elemento, basta pegar a soma das velocidades após a colisão e dividir pela soma das velocidades no instante da colisão, ou seja, caso não haja perda de velocidade, os números serão iguais antes e depois, resultando num coeficiente de restituição igual a 1.<br>
            Para as colisões que o coeficiente de restituição são menores do que 1, significa que houve perda de energia, e pode resultar numa colisão parcialmente elástica, que seria igual a anterior, mas com perda de energia ou uma colisão perfeitamente inelástica, que é quando os corpos se juntam durante a colisão e seguem como um único corpo com a soma das massas após a colisão.<br>
            Só por curiosidade, caso o coeficiente seja maior que 1, significa que houve um ganho de energia durante a colisão, o que até onde eu saiba não existe, mas foi retratado no filme infantil Flubber, e pode ser testado no simulador sem problemas.</p>
            <p>Além do coeficiente de restituição os outros dados importantes para serem analisados durante a colisão são a massa e a velocidade dos corpos&nbsp;no instante da colisão. Com esses dados na mão basta usar a seguinte fórmula: v1f = (1+e)m2v2i/(m1 + m2) + v1i(m1 &#8211; m2 e)/(m1 + m2) onde:<br>
            e = coeficiente e restituição<br>
            m1 = massa do corpo 1<br>
            m2 = massa do corpo 2<br>
            v1i = velocidade do corpo 1 no momento da colisão<br>
            v2i = velocidade do corpo 2 no momento da colisão<br>
            * Como não quero que essa série passe de 3 ou 4 posts, eu vou deixar os detalhes por trás da fórmula da colisão nesse excelente material que encontrei.</p>
            <p>Neste instante o foco é na colisão da bolinha com as paredes, então vamos rever esta fórmula. Como estamos trabalhando num mundo ideal vou considerar que o coeficiente de restituição é 1. Além disso, reparem que a primeira parte da fórmula é (1+e)m2v2i/(m1 + m2). Como a velocidade da parede é zero e qualquer coisa multiplicado por zero vai resultar em zero, e zero divido por qualquer coisa também vai ser zero, sempre que o segundo corpo não estiver em movimento antes da colisão, essa primeira parte da fórmula vai ser sempre zero. O que sobra pra nos preocuparmos então é v1i(m1 &#8211; m2 e)/(m1 + m2). Mas agora vem um problema, quanto pesa a bolinha? E a parede? Vamos fazer uma simulação simples, imagine que a massa da bolinha é 1 e da parede é 1000. Lembrando que estamos trabalhando com e=1, então vamos ter:<br>
            v1f = v1i(1 &#8211; 1000 *1) / (1 + 1000) -&gt; v1f = v1i * -999/1001.<br>
            Agora vamos imaginar que a bolinha pesa 0.1 e a parede pesa 1000000. Teremos:<br>
            v1f = v1i(0.1 &#8211; 1000000 *1) / (0.1 + 1000000) -&gt; v1f = v1i * -999999.9/1000000.1.<br>
            Na primeira simulação teríamos vf = vi * -999/1001 -&gt; vf = vi * -0.998001998. E na segunda simulação teríamos vf = vi * -0.9999998.<br>
            Reparem que quanto maior a diferença entre as massas mais próximo de -1 será este último termo. Logo, quando a massa do corpo 1 é desconsiderável comparada a do corpo 2 teremos que vf = vi * -e. Como estamos trabalhando com e = 1, teremos uma velocidade final que será igual a velocidade do instante da colisão multiplicado por -1. Lembrando que no jogo, eu sempre guardo a velocidade em 2 variáveis diferentes, 1 para o eixo x e uma para o eixo y. Quando bato nas paredes verticais, eu mantenho a velocidade vertical e multiplico a horizontal por -1, e nas paredes horizontais o oposto.</p>
            <p>Acho que muita gente que já brincou com este tipo de problema sempre fez a multiplicação por -1, mas poucos realmente entendiam o porquê. Espero que este post tenha esclarecido este outro mistério e não deixem de conferir o material que citei acima, e aguardem o próximo post onde vou resolver o problema da colisão com os jogadores.</p>
          </div>
          <div class="post-data">
            Posted in <a href="/category/jogos/" title="View all posts in Jogos">Jogos</a>, <a href="/category/matematica/" title="View all posts in Matemática">Matemática</a>
            <h2>Integrando Soluções Tecnológicas com Opções Binárias: Uma Nova Era para Desenvolvedores</h2>

<p>No mundo em constante evolução da tecnologia, os desenvolvedores estão sempre buscando novas formas de expandir seus horizontes e aplicar suas habilidades em diferentes setores. Uma área que tem ganhado destaque recentemente é a integração de soluções tecnológicas com plataformas de trading, especialmente no mercado de opções binárias. Uma das plataformas que tem se destacado nesse cenário é a <a href="https://trading-option.com.br/">opções binárias pocket option</a>, que oferece oportunidades interessantes para desenvolvedores.</p>

<h3>Desafios e Oportunidades para Desenvolvedores</h3>

<p>A crescente demanda por soluções personalizadas no mercado financeiro abre portas para desenvolvedores que desejam aplicar suas habilidades em Ruby, Rails e outras tecnologias web modernas. A criação de interfaces intuitivas, sistemas de análise de dados em tempo real e ferramentas de gestão de risco são apenas algumas das áreas onde os desenvolvedores podem contribuir significativamente.</p>

<p>Além disso, a integração de APIs de plataformas de trading com aplicações web personalizadas representa um campo fértil para inovação. Desenvolvedores podem criar soluções que ajudem traders a tomar decisões mais informadas, automatizar estratégias de trading e melhorar a gestão de portfólio.</p>

<h3>O Futuro da Colaboração entre Tecnologia e Trading</h3>

<p>À medida que o mercado de opções binárias continua a evoluir, a demanda por soluções tecnológicas avançadas só tende a crescer. Para os desenvolvedores, isso significa uma oportunidade de expandir seu conhecimento, trabalhar em projetos desafiadores e possivelmente até mesmo criar suas próprias ferramentas inovadoras para o mercado financeiro.</p>
          </div>
          <div class="post-edit"></div>
        </div>
        <div id="post-653" class="post-653 post type-post status-publish format-standard hentry category-jogos category-matematica">
          <h2 class="entry-title post-title"><a href="/2012/09/13/matematica-para-jogos-parte-1-colisao-de-circulos/" rel="bookmark">Matemática para jogos &#8211; Parte 1 &#8211; Colisão de círculos</a></h2>
          <div class="post-meta">
            <span class="meta-prep meta-prep-author posted">Posted on</span> <a href="/2012/09/13/matematica-para-jogos-parte-1-colisao-de-circulos/" title="3:17 pm" rel="bookmark"><span class="timestamp updated">13 September 2012</span></a> <span class="byline">by</span> <span class="author vcard"><a class="url fn n" href="/author/david-paniz/" title="View all posts by David Paniz">David Paniz</a></span> <span class="comments-link"><span class="mdash">&mdash;</span> <a href="/2012/09/13/matematica-para-jogos-parte-1-colisao-de-circulos/#respond" title="Comment on Matemática para jogos &#8211; Parte 1 &#8211; Colisão de círculos">No Comments &darr;</a></span>
          </div>
          <div class="post-entry">
            <p>Por uma incrível coincidência, assim como alguns dos meus amigos ex-caelum, recentemente voltei a estudar sobre o desenvolvimento de jogos. Há algumas semanas fiz um quase jogo para aprender um pouco sobre o canvas do HTML5 e WebSockets. O código está no meu github.</p>
            <p>Óbvio que desenvolver jogos tem os seus desafios de programação, mas o que mais me surpreendeu na minha experiência foi como um jogo tão estupidamente simples me exigiu tamanho conhecimento sobre física e matemática, então nessa primeira série de posts sobre desenvolvimento de jogos, decidi focar nesta parte do problema.</p>
            <p>O jogo em questão é alguma coisa parecida com um &#8220;Air Hockey&#8221; onde existem 2 jogadores representados por 1 disco grande cada, e um puck (bolinha) representado por um disco menor. O jogo todo é desenhado em um canvas 2D, então cada um dos 3 elementos é representado por 3 números: um raio e uma coordenada (X, Y).<br>
            Durante o game loop tenho que verificar se o puck colidiu com alguma parede ou jogador para mudar a sua rota, e aí vem o primeiro problema que vou abordar aqui. Para verificar se o puck colidiu com algum jogador temos que verificar a distância entre os 2 pontos, como na imagem abaixo.</p>
            <div id="attachment_663" style="width: 310px" class="wp-caption alignnone">
              <img class="size-medium wp-image-663" title="pontos" src="http://blog-paniz.rhcloud.com/wp-content/uploads/2012/09/pontos-300x192.png" alt="Imagem 1" width="300" height="192">
              <p class="wp-caption-text">Imagem 1</p>
            </div>
            <p>Existe uma formula &#8220;mágica&#8221; para calcular a distância entre pontos, mas como não sou muito fã de coisas obscuras, aqui vai uma explicação detalhada do problema. Se imaginarmos um retângulo com os pontos como vértices opostos, vamos ver que se traçarmos a linha que une esses pontos, temos 2 triângulos retângulos e que a distância entre os pontos nada mais é do que a hipotenusa deles.</p>
            <div id="attachment_664" style="width: 310px" class="wp-caption alignnone">
              <img class="size-medium wp-image-664" title="retangulo com coordenadas" src="http://blog-paniz.rhcloud.com/wp-content/uploads/2012/09/retangulo-com-coordenadas-300x220.png" alt="Imagem 2" width="300" height="220">
              <p class="wp-caption-text">Imagem 2</p>
            </div>
            <p>Considerando que os pontos são A(20, 30) e B(50, 40) conseguimos descobrir o tamanho do nosso retângulo com um lado igual a Bx &#8211; Ax (50 &#8211; 20 =&gt;; 30) e outro com By &#8211; Ay (40 &#8211; 30 =&gt;; 10). Temos um retângulo de 30 por 10.</p>
            <div id="attachment_665" style="width: 310px" class="wp-caption alignnone">
              <img class="size-medium wp-image-665" title="retangulo preenchido" src="http://blog-paniz.rhcloud.com/wp-content/uploads/2012/09/retangulo-preenchido-300x155.png" alt="Imagem 3" width="300" height="155">
              <p class="wp-caption-text">Imagem 3</p>
            </div>
            <p>Agora basta considerar o triângulo com lados 10, 30 e X, onde X é a hipotenusa deste triângulo retângulo e finalmente a distância entre nossos pontos. Para quem não lembra, a hipotenusa é calculada com a famosa fórmula &#8220;Raiz da soma dos catetos ao quadrado&#8221; =&gt;; √(10² + 30²) =&gt;; √(1000) =&gt;; 31.6227766017.</p>
            <p>Para finalizar faltou considerar o tamanho dos círculos inteiros e não somente seus pontos centrais, então para saber se ocorreu a colisão basta verificar se a soma dos raios é maior ou igual a distância entre os pontos.</p>
            <div id="attachment_672" style="width: 310px" class="wp-caption alignnone">
              <img class="size-medium wp-image-672" title="Com circulos" src="http://blog-paniz.rhcloud.com/wp-content/uploads/2012/09/Screen-Shot-2012-09-13-at-2.21.24-PM-300x213.png" alt="Image 4" width="300" height="213">
              <p class="wp-caption-text">Image 4</p>
            </div>
            <p>Considerando que tenho um objeto &#8220;bola&#8221; e um &#8220;jogador&#8221;, a fórmula final para saber se teve colisão seria algo como</p>
            <pre class="brush: plain; title: ; notranslate" title="">
distancia = sqrt((jogador.x - bola.x)^2 + (jogador.y - bola.y)^2)
bola.raio + jogador.raio &gt;= distancia
</pre>
            <p>PS: As imagens não estão com a proporção correta, fiz tudo a mão livre apenas para ilustrar.<br>
            PPS: Simplifiquei a questão do módulo entre os pontos para formar o retângulo porque não são relavantes no resultado final, dado que sempre vamos usar o quadrado do número e, neste caso, sempre vai resultar em valor positivo.</p>
          </div>
          <div class="post-data">
            Posted in <a href="/category/jogos/" title="View all posts in Jogos">Jogos</a>, <a href="/category/matematica/" title="View all posts in Matemática">Matemática</a>
          </div>
          <div class="post-edit"></div>
        </div>
        <div id="post-634" class="post-634 post type-post status-publish format-standard hentry category-dica-rapida tag-activerecord tag-bulk-delete tag-bulk-update tag-rails">
          <h2 class="entry-title post-title"><a href="/2012/07/11/dica-rapida-bulk-update-atualizacao-em-massa-no-rails/" rel="bookmark">[Dica Rápida] Bulk update (atualização em massa) no Rails</a></h2>
          <div class="post-meta">
            <span class="meta-prep meta-prep-author posted">Posted on</span> <a href="/2012/07/11/dica-rapida-bulk-update-atualizacao-em-massa-no-rails/" title="5:32 pm" rel="bookmark"><span class="timestamp updated">11 July 2012</span></a> <span class="byline">by</span> <span class="author vcard"><a class="url fn n" href="/author/david-paniz/" title="View all posts by David Paniz">David Paniz</a></span> <span class="comments-link"><span class="mdash">&mdash;</span> <a href="/2012/07/11/dica-rapida-bulk-update-atualizacao-em-massa-no-rails/#comments" title="Comment on [Dica Rápida] Bulk update (atualização em massa) no Rails">1 Comment &darr;</a></span>
          </div>
          <div class="post-entry">
            <p>Depois de muito tempo sem postar nenhuma dica rápida, estou escrevendo uma de Rails agora.<br>
            É relativamente comum precisarmos fazer uma atualização em mais de uma linha da mesma tabela e quando se está usando o ActiverRecord é muito comum pensar em fazer um where e depois, usando um update_attribute, atualizar os registros. Algo como:</p>
            <pre class="brush: ruby; title: ; notranslate" title="">
Usuario.where('login in (?)', ['a', 'b', 'c']).each do|u|
 u.update_attribute :status, :bloqueado
end
</pre>
            <p>O grande problema desse código é que ele irá executar 4 comandos SQL diferentes, mas seria fácilmente resolvido com apenas 1. Para que o ActiverRecord execute um único comando update com a cláusula where basta usar o método <strong>update_all</strong>:</p>
            <pre class="brush: ruby; title: ; notranslate" title="">
Usuario.where('login in (?)', ['a', 'b', 'c']).update_all( status: :bloqueado )
</pre>
            <p>Dica rápida parte 2: Além do <strong>update_all</strong> também existe o <strong>delete_all</strong>.</p>
          </div>
          <div class="post-data">
            Tagged with: <a href="/tag/activerecord/" rel="tag">activerecord</a>, <a href="/tag/bulk-delete/" rel="tag">bulk delete</a>, <a href="/tag/bulk-update/" rel="tag">bulk update</a>, <a href="/tag/rails/" rel="tag">Rails</a><br>
            Posted in <a href="/category/dica-rapida/" title="View all posts in dica rapida">dica rapida</a>
          </div>
          <div class="post-edit"></div>
        </div>
        <div id="post-613" class="post-613 post type-post status-publish format-standard hentry category-uncategorized">
          <h2 class="entry-title post-title"><a href="/2012/06/21/da-ide-ao-editor-de-texto-do-editor-de-volta-a-ide-e-de-volta-de-novo-ao-editor/" rel="bookmark">Da IDE ao editor de texto, do editor de volta a IDE e de volta de novo ao editor</a></h2>
          <div class="post-meta">
            <span class="meta-prep meta-prep-author posted">Posted on</span> <a href="/2012/06/21/da-ide-ao-editor-de-texto-do-editor-de-volta-a-ide-e-de-volta-de-novo-ao-editor/" title="8:52 am" rel="bookmark"><span class="timestamp updated">21 June 2012</span></a> <span class="byline">by</span> <span class="author vcard"><a class="url fn n" href="/author/david-paniz/" title="View all posts by David Paniz">David Paniz</a></span> <span class="comments-link"><span class="mdash">&mdash;</span> <a href="/2012/06/21/da-ide-ao-editor-de-texto-do-editor-de-volta-a-ide-e-de-volta-de-novo-ao-editor/#respond" title="Comment on Da IDE ao editor de texto, do editor de volta a IDE e de volta de novo ao editor">No Comments &darr;</a></span>
          </div>
          <div class="post-entry">
            <p>Infelizmente estou escrevendo bem menos do que gostaria, especialmente nestes últimos meses que nem se quer passei aqui no blog e praticamente não usei nem o twitter. Estou preparando um post offtopic onde vou comentar melhor sobre tudo o que passei nestes últimos meses e o que estou preparando para os próximos, mas pra &#8220;tirar a poeira&#8221; daqui vou comentar um pouco sobre meu ambiente de novo.<br>
            No final de 2010 escrevi sobre <a href="/2010/12/29/meu-ambiente-de-desenvolvimento-em-7-itens/">meu ambiente de desenvolvimento</a> e naquele momento finalmente estava me adaptando de vez ao vim e largando completamente o TextMate. O &#8220;grande problema&#8221; é qua meses depois disso acabei trabalhando num projeto scala na Caelum e o ambiente que o pessoal que iniciou o projeto estava usando era o IntelliJ IDEA. Como eu não sabia nada nem de scala nem do projeto, entrei na onda do pessoal e instalei a IDE. Até aí nada de mais, porem eu ainda trabalhava com java e ruby e o IntelliJ IDEA é uma IDE fantástica com suporte para todas essas e muitas outra linguagens com plugins muito mais maduros e estáveis do que os para eclipse, então resolvi dar uma chance e tentar concentrar tudo nesta IDE. Apenas 1 set de atalhos independente da linguagem e projeto sempre foi um sonho pra mim que vivia fazendo shift de ambiente dependendo do projeto, então por que não tentar? Tentei, e por incrível que pareça passei muito perto de conseguir, mas uma pequeno detalhe me incomodava muito&#8230; o preço. Pra quem não sabe eu sou radical contra a pirataria (de software) e embora o IntelliJ seja muito bom, não foi bom o bastate pra me convencer a pagar U$199,00 por ele. Uma alternativa seria usar a versão gratuita que da suporte a java e scala e comprar apenas o RubyMine que é o equivalente ao plugin de ruby do intelliJ mas em versão standalone, o que baixaria o preço da licença para apenas U$ 69,00. Sem dúvidas valeria mais a pena do que comprar o TextMate, mas fui tentar outras alternativas antes de gastar dinheiro com outra ferramenta que, assim como o meu TextMate, um dia poderia se revelar um grande desperdício.<br>
            Resolvi então voltar as origens de quando estava aprendendo ruby, dado que estava querendo um ambiente completo e unificado nada melhor do que dar uma chance a minha IDE java que mais usei, o eclipse. Instalei o famoso RadRails e comecei a trabalhar com ele, trabalhei nuns exemplos de java 7, desenvolvi meus projetos ruby do dia-a-dia, dei uma olhada num projeto python que precisei e embora as coisas estivessem mais ou menos boas os constantes erros bizarros e eventuais crashs me incomodam muito. Eu sei que parte disso é porque sempre uso as versões beta do eclipse, mas num dos updates que aconteceram eu simplesmente &#8220;crashei&#8221; meu workspace e perdi todas as customizações que costumo fazer. Mesmo assim reconfigurei o eclipse inteiro, mas com menos plugins, apenas o Eclim e o já citado Aptana RadRails. Mesmo com um ambiente relativamente enxuto comparado ao monstro que meu eclipse costumava ser, ele continuou se mostrando um ambiente bom o bastante para conseguir trabalhar, mas não pra me deixar completamente satisfeito, sem contar que consumo de memória começou a me incomodar. Estou começando a estudar sobre desenvolvimento de jogos e as ferramentas são bem pesadas e mesmo com meus 8GB de RAM não estava conseguindo &#8220;brincar um pouco&#8221; sem ter que fechar minhas coisas de trabalho, logo tomei a mesma decisão que tinha tomado em 2010 e desisti do ambiente único integrado e usar a melhor ferramenta para cada atividade. Provavelmente nunca vou programar java num editor de texto então porque querer tanto usar uma IDE pra programar ruby?<br>
            Observação importante: O IntelliJ/RubyMine consegue sim te dar boas sugestões no autocomplete e na maior parte das vezes ele acerta perfeitamente a implementação dos métodos no &#8220;control click&#8221;, inclusive para métodos declarados em gems, métodos sobrescritos e etc, mas tem seu preço. O Aptana ainda está muito longe disso!!</p>
            <p>Já que era pra usar um editor de texto de novo e não estava nem se quer considerando o TextMate, poderia testar o Sublime, testar o Emacs ou simplesmente voltar a usar o VIM.<br>
            Por pura preguiça e falta de tempo tomei a decisão mais fácil e fui direto ao VIM, mas para não passar raiva de novo ao invés de simplesmente pegar o bundle de alguém desta vez fiz a coisa com um pouco mais de carinho e fui entender e aprender a usar os plugins que eram importantes para mim. Cheguei a conclusão que as funcionalidades que não consigo viver sem são:</p>
            <ul>
              <li>Busca no projeto. Muitas vezes queremos fazer uma busca não apenas no arquivo aberto, mas em todos os arquivos do projeto e me irritava ter que abrir outra aba/split para fazer um grep e depois ter que ficar olhando um por um. Pra este problema temos o Ack</li>
              <li>Árvore de diretórios. Funcionalidade que faz parte de quem está acostumado com ides, mas não são essencial aos editores de texto. No vim basta colocar o NERDTree. Como tenho o hábito de usar tabs ao invés de splits coloquei também o NERDTreeTabs que melhora a usabilidade</li>
              <li>Abrir arquivos pelo nome com busca inteligente. Quando você já sabe o nome do arquivo, ou pelo menos parte dele e quer apenas digitar esse nome e abrir o arquivo. Estou usando o <a hre="http://www.vim.org/scripts/script.php?script_id=3025">Command-T</a>
              </li>
              <li>Toggle de comentário. Parece um funcionalidade idiota, mas me irrita muito ter que editar várias linhas para comentar um bloco. NERDCommenter é a melhor ferramenta que existe pra isso. &#8217;5,ci&#8217; vai comentar 5 linhas e pronto, não precisa nem marcar antes nem nada.</li>
              <li>Feedback rápido para erros. Sabe quando você faz aquele método bizarro, salva o arquivo, vai pro browser, atualiza e &#8220;pã!&#8221;. Vai olhar a stacktrace e foi porque você trocou 2 letras na digitação ou esqueceu o &#8216;;&#8217; ou qualquer outro erro idiota desses? Syntastic mostra um erro claro assim que você salva o arquivo. Algo parecido com um erro de compilação mesmo para linguagens dinâmicas como Ruby</li>
            </ul>
            <p>Além desses ainda tem os não tão importantes mas que ajudam muito durante o dia como o Endwise, Rails, vim-ruby e alguns outros. Acabei pegando o bundle do scrooloose como base que tem praticamente todos esses que decidi que precisava e mais alguns outros desses utilitários e ainda assim é um bundle bem enxuto. Acabei criando meu fork e fazendo algumas poucas configurações extras basicamente por causa do meu hábito de usar abas.</p>
          </div>
          <div class="post-data">
            Posted in <a href="/category/uncategorized/" title="View all posts in Uncategorized">Uncategorized</a>
          </div>
          <div class="post-edit"></div>
        </div>
        <div id="post-575" class="post-575 post type-post status-publish format-standard hentry category-dica-rapida category-ruby tag-arquivo tag-renomear tag-ruby">
          <h2 class="entry-title post-title"><a href="/2012/01/10/renomeando-arquivos-em-ruby/" rel="bookmark">Renomeando arquivos em ruby</a></h2>
          <div class="post-meta">
            <span class="meta-prep meta-prep-author posted">Posted on</span> <a href="/2012/01/10/renomeando-arquivos-em-ruby/" title="6:19 pm" rel="bookmark"><span class="timestamp updated">10 January 2012</span></a> <span class="byline">by</span> <span class="author vcard"><a class="url fn n" href="/author/david-paniz/" title="View all posts by David Paniz">David Paniz</a></span> <span class="comments-link"><span class="mdash">&mdash;</span> <a href="/2012/01/10/renomeando-arquivos-em-ruby/#comments" title="Comment on Renomeando arquivos em ruby">4 Comments &darr;</a></span>
          </div>
          <div class="post-entry">
            <p>Primeiro post do ano ressuscitando a categoria dica rápida.<br>
            Há uma ou duas semanas o PotHix me passou umas músicas, mas na hora de copiar, todos os arquivos vieram sem extensão. Depois de perder um tempo tentando resolver com bash, eu desisti e resolvi o problema em 10 min usando ruby. Se alguém puder postar nos comentários a solução em bash eu agradeço!</p>
            <p>Para a minha solução usei apenas os seguintes métodos:</p>
            <pre class="brush: ruby; title: ; notranslate" title="">
#Retorna um array de strings com todos os arquivos do diretório.
Dir.entries(&quot;dir&quot;)
</pre>
            <pre class="brush: ruby; title: ; notranslate" title="">
#Retorna se o arquivo é um diretório ou não.
File.directory?(&quot;arquivo&quot;)
</pre>
            <pre class="brush: ruby; title: ; notranslate" title="">
#Renomeia o arquivo.
File.rename(&quot;nome_antigo&quot;, &quot;nome_novo&quot;)
</pre>
            <p>Minha solução final ficou assim:</p>
            <pre class="brush: ruby; title: ; notranslate" title="">
def rename_in_dir(dir)
  files = Dir.entries(dir)
  files.each do |f|
    # Usei esse if para ignorar os arquivos que já tinham
    # extensão e as referências '.' e '..'
    next if f == &quot;.&quot; or f == &quot;..&quot; or f =~ /.*..{2,4}$/

    # é importante sempre usar o diretório junto, se não ele vai
    # procurar sempre no diretório onde o script está sendo executado
    if File.directory?(&quot;#{dir}/#{f}&quot;)
      # Se for um diretório faz a chamada recursiva
      puts &quot;DIR: #{dir}/#{f}&quot;
      rename_in_dir(&quot;#{dir}/#{f}&quot;)
    else
      puts &quot;renaming: #{dir}/#{f}&quot;
      # Adiciona a extensão .mp3 no arquivo
      File.rename(&quot;#{dir}/#{f}&quot;, &quot;#{dir}/#{f}.mp3&quot;)
    end
  end
end

# Começa a partir do diretório onde o arquivo está
rename_in_dir(&quot;.&quot;)
</pre>
          </div>
          <div class="post-data">
            Tagged with: <a href="/tag/arquivo/" rel="tag">arquivo</a>, <a href="/tag/renomear/" rel="tag">renomear</a>, <a href="/tag/ruby/" rel="tag">Ruby</a><br>
            Posted in <a href="/category/dica-rapida/" title="View all posts in dica rapida">dica rapida</a>, <a href="/category/ruby/" title="View all posts in Ruby">Ruby</a>
          </div>
          <div class="post-edit"></div>
        </div>
        <div id="post-546" class="post-546 post type-post status-publish format-standard hentry category-agile tag-agile tag-ambiente tag-baia tag-mesas">
          <h2 class="entry-title post-title"><a href="/2011/10/31/minha-opiniao-sobre-ambiente-de-trabalho/" rel="bookmark">Minha opinião sobre ambiente de trabalho</a></h2>
          <div class="post-meta">
            <span class="meta-prep meta-prep-author posted">Posted on</span> <a href="/2011/10/31/minha-opiniao-sobre-ambiente-de-trabalho/" title="11:50 am" rel="bookmark"><span class="timestamp updated">31 October 2011</span></a> <span class="byline">by</span> <span class="author vcard"><a class="url fn n" href="/author/david-paniz/" title="View all posts by David Paniz">David Paniz</a></span> <span class="comments-link"><span class="mdash">&mdash;</span> <a href="/2011/10/31/minha-opiniao-sobre-ambiente-de-trabalho/#comments" title="Comment on Minha opinião sobre ambiente de trabalho">2 Comments &darr;</a></span>
          </div>
          <div class="post-entry">
            <p>Muito palpite e pouco estudo na nossa área acabam gerando grandes discussões sobre o ambiente de trabalho. Afinal, baias são ruins, mesões geram barulho e distrações, as pessoas precisam ter o seu espaço, e tantas outras questões sempre são levadas aos pobres tomadores de decisão sobre a montagem da área de trabalho dos funcionários.<br>
            Estou prestes a completar meu primeiro mês de Locaweb e tive vontade de escrever sobre assunto já que, embora tão parecido com a Caelum, minhas sensações são completamente diferentes, o que me fez refletir sobre o que realmente gosto e não gosto no assunto. Infelizmente esse post é apenas a opinião de mais um e nada além disso.</p>
            <p>Eu adorava o ambiente que tinha na DClick e na Caelum e também estou gostando muito das coisas aqui na Locaweb, com regras apenas de bom senso: vista o que quiser, chegue na hora que quiser, apenas faça suas horas semanais e cumpra seus deveres não importa como. Na minha opinião isso deveria ser regra para área de desenvolvimento, mas na hora de comprar os móveis é que as dúvidas começam, então vou listar alguns itens que considero importantes e comentar sobre os prós e contras que vivi nesses últimos anos.</p>
            <h3>Mesas</h3>
            <p>Sempre fui defensor dos mesões. Sempre achei que o ganho em comunicação vale mais do que as eventuais distrações que podem gerar, porém tanto a DClick quanto a Caelum são empresas relativamente pequenas, em ambas a nossa &#8220;salona&#8221; tinha no máximo 20 devs. A experiência das mesonas aqui na Locaweb está sendo bem menos produtiva pra mim. Na minha primeira semana aqui tive dias de produtividade MUITO baixas que atribuí ao barulho na sala. Não sei qual seria o número máximo de pessoas, ou se o problema não é quantidade e sim o bom senso, mas a questão é que hoje preciso me controlar bem mais para render o que gostaria num dia de trabalho. Aqui, além das mesonas existe outro fator que talvez seja o real &#8220;vilão&#8221;, que são as brincadeiras. Na Caelum era comum ver uma pessoa ou outra brincando com os dardos ou fazendo malabares, mas aqui na Loca é comum ver pessoas fazendo &#8220;guerrinha&#8221; com suas NERFs. Embora seja óbvio que &#8220;guerrinha&#8221; seja uma distração muito grande, nas outras empresas também tínhamos momentos de &#8220;distração coletiva&#8221; ou simplesmente barulho intenso, por isso não tiro a &#8220;culpa&#8221; dos mesões para esse tipo de bagunça.<br>
            Veredito: Use com bom senso. Claro que é mais fácil &#8220;controlar&#8221; 20 do que 500, mas mesmo para times grandes acho que vale a pena a utilização dos mesões, mas é necessário um pouco mais de responsabilidade dos funcionários.</p>
            <h3>Lugares fixos</h3>
            <p>Uma das coisas que mais senti falta quando fui para a Caelum era de ter o MEU lugar. Sempre gostei de ter a minha bagunça, fotos, planta (na DClick eu tínha um cactus na mesa, aqui na Loca ainda não), enfim, personalizar o lugar como você preferir. Tanto na DClick quanto aqui na Loca tenho essa possibilidade, mas na época de Caelum não tínhamos, e embora sentisse falta disso, lá faz muito sentido ser da maneira que é. Mais importante do que trazer a foto da familia é sentar próximo do seu time de trabalho. Aqui na Loca os time são bem definidos e pelo o que entendi, existe uma baixa rotatividade de pessoas entre times, na Caelum é exatamente o oposto. Lá não existe uma separação muito clara entre os times e a rotatividade é MUITO grande. Não faz o menor sentido você customizar seu lugar se vai trocar de lugar toda semana. Um ponto curioso sobre o assunto é que na DClick era mais ou menos o meio do caminho. Existem (pelo menos existiam) times bem definidos por projeto, mas a rotatividade era média e fazer a mudança eventualmente valia a pena. Durante o ano que trabalhei lá me lembro de ter remanejado minhas coisas pelo menos umas 3 ou 4 vezes.<br>
            Veredito: Dê preferência por manter os times juntos e, se as mudanças não forem frequentes, vale a pena deixá-los fixos.</p>
            <h3>Cadeiras</h3>
            <p>Compre cadeiras boas para seus funcionários! Eu sei que não é barato, mas além de lei, faz toda a diferença chegar em casa após um dia de trabalho numa cadeirinha vagabunda ou numa cadeira que você pode configurar altura, encosto e etc.<br>
            Veredito: Não precisa ser cadeira de presidente, mas compre pelo menos uma de rodinha com regulagem de altura, encosto e braços.</p>
            <h3>Monitores</h3>
            <p>Desde que usei dois monitores pela primera vez na DClick me apaixonei pela experiência. Poder ver o código e browser ao mesmo tempo ajuda MUITO no dia-a-dia. Se for optante pelos lugares fixos, compre 2 monitores pra todo mundo! (vai sair mais barato do que a cadeira), se não, deixe alguns espalhados pelas mesas para que as pessoas usem. Uma observação importante sobre essa opção é: quanto mais difícil for de usar, menos eles serão usados, então tente deixar tudo prontinho para apenas espetar o computador e sair usando.<br>
            Veredito: Eu me sinto bem mais produtivo usando outro monitor. Acredito que vale o investimento.</p>
            <h3>Copa/Cozinha/Banheiro</h3>
            <p>Essa parte é bem mais difícil de gerenciar pois na maior parte dos casos não temos como colocar um banheiro a mais onde queremos, mas é um fator que não deveria ser completamente ignorado. Na DClick a copa era pra um lado e o banheiro pra o outro, mas ambos bem próximos da maioria. Na pior da hipóteses ou você sentaria bem perto de um e um pouco longe do outro. Na Caelum, na última configuração de sala que tínhamos quando saí de lá, a &#8220;copa&#8221; estava integrada à nossa sala o que era ótimo. O único problema que tivemos com isso foi a facilidade que as pessoas tinham em comer nas mesonas e acabava sujando um espaço coletivo. Bastou uma conversa e tudo se resolveu. Quanto aos banheiros lá, usavamos os da área comum do prédio. Relativamente próximos com a desvantagem de ter que levar uma chave com você, além de ser só um por andar (relativamente comum tentar ir ao banheiro e estar ocupado). Aqui na Loca, tanto o banheiro quanto a copa ficam nos cantos do prédio e em apenas 2 cantos. Pra piorar, o banheiro masculino é de um lado e o feminino é do outro, ou seja, dependendo de onde você se sente pode ser uma longa jornada até você se aliviar ou conseguir o seu café. Porém, se sentar perto do banheiro vai acabar vendo um grande fluxo de pessoas por perto. Embora veja isso como um desperdício (pra que já leu um pouco sobre lean sabe do que estou falando) não vejo uma solução plausível para esse caso.<br>
            Veredito: Definitivamente comportar 500 pessoas é BEM mais difícil do que 20, mas tente se preocupar com esses detalhes na hora de escolher o prédio. Sem dúvidas seus funcionários precisão ir ao banheiro e quanto menos tempo eles demorarem, melhor pra todos! Prefira os ambientes com banheiros e copas (café) acessíveis e de preferência que sejam iguais para todos, independente de onde sentam.</p>
            <p>Esses são os principais fatores físicos que acredito afetar a minha produtividade durante o dia-a-dia. Em nenhuma das 3 empresas que citei no post tive 100% dos itens que mais gosto e fui/sou muito feliz como funcionário de todas, então não se preocupe se não conseguir todos, mas tente fornecer o máximo desses itens para seus funcionários.<br>
            Lembre-se do princípio ágil:<br>
            &#8220;Construa projetos em torno de indivíduos motivados.<br>
            Dê a eles o ambiente e o suporte necessário e confie neles para fazer o trabalho.&#8221;</p>
            <p>Pra finalizar, fotos da minha mesa aqui na Locaweb:<br>
            <img src="http://blog-paniz.rhcloud.com/wp-content/uploads/2011/10/IMG_20111031_095502.jpg" alt="" title="IMG_20111031_095502" class="alignleft size-full wp-image-572"></p>
            <p><img src="http://blog-paniz.rhcloud.com/wp-content/uploads/2011/10/IMG_20111031_082209.jpg" alt="" title="IMG_20111031_082209" class="alignright size-full wp-image-571"></p>
          </div>
          <div class="post-data">
            Tagged with: <a href="/tag/agile/" rel="tag">Agile</a>, <a href="/tag/ambiente/" rel="tag">ambiente</a>, <a href="/tag/baia/" rel="tag">baia</a>, <a href="/tag/mesas/" rel="tag">mesas</a><br>
            Posted in <a href="/category/agile/" title="View all posts in Agile">Agile</a>
          </div>
          <div class="post-edit"></div>
        </div>
        <div id="post-496" class="post-496 post type-post status-publish format-standard hentry category-arquitetura category-palestras-apresentacoes">
          <h2 class="entry-title post-title"><a href="/2011/09/13/qconsp-2011/" rel="bookmark">QConSP 2011</a></h2>
          <div class="post-meta">
            <span class="meta-prep meta-prep-author posted">Posted on</span> <a href="/2011/09/13/qconsp-2011/" title="12:39 pm" rel="bookmark"><span class="timestamp updated">13 September 2011</span></a> <span class="byline">by</span> <span class="author vcard"><a class="url fn n" href="/author/david-paniz/" title="View all posts by David Paniz">David Paniz</a></span> <span class="comments-link"><span class="mdash">&mdash;</span> <a href="/2011/09/13/qconsp-2011/#respond" title="Comment on QConSP 2011">No Comments &darr;</a></span>
          </div>
          <div class="post-entry">
            <p>No final de semana passado aconteceu a segunda edição da QConSP e, novamente, tive a grande honra de ajudar na organização das Lightning talks (LT) no final do primeiro dia do evento como Host da track.</p>
            <p>Mais um evento organizado pela Caelum, obviamente com seus altos e baixos, mas muito mais altos do que baixos.</p>
            <p>Questões como espaço, horário e lanches foram praticamente perfeitos e g<span style="color: #000000;">randes a</span>presentações como as do Jim Webber, Rebecca Parsons e o muito simpático Khawaja Shams com seus robôs dançantes e seu knob (botão) que cria máquinas na Amazon foram momentos de destaque do evento. Infelizmente alguns palestrantes acabaram decepcionando um pouco, mas este é o tipo de problema que não temos como prever e sempre vão acontecer em qualquer evento do mundo.</p>
            <p>Outra grande vantagem desse tipo de evento é poder rever alguns amigos e ex-colegas de trabalho e matar a saudade do pessoal, além de conhecer novas pessoas e em alguns casos conhecer fisicamente algum grande amigo de internet (Acreditem, isso acontece! E muito!).</p>
            <p>Gostaria de agradecer todos que participaram da organização do evento, os hosts das tracks e o Luiz Bassi da Caelum, que foram as principais pessoas por trás deste grande evento. Além disso um agradecimento especial para todos que apresentaram LT comigo:<br>
            Christian Reichel, que apresentou &#8220;Por um Java mais funcional&#8221;, onde mostrou exemplos de funções como <em>map</em> e <em>reduce</em> em java usando o Guava;</p>
            <p>Diego Chohfi, que agora também faz parte do time da Caelum, mostrou um pouco do dinamismo não muito comentado do Objective-C;</p>
            <p>E 3 grandes colaboradores do VRaptor falando sobre algumas funcionalidades extras do framework:</p>
            <p>Washington Botelho que mostrou como implementar um controle de permissões baseado em perfis;</p>
            <p>Rodolfo Liviero, autor do Vraptor-scaffold, mostrou como criar e &#8220;deployar&#8221; uma aplicação VRaptor no heroku em menos de 5 min usando seu projeto;</p>
            <p>Guilherme Silveira que comentou sobre os vários plugins já criados para o VRaptor e ainda deu um &#8220;puxão de orelha&#8221; no pessoal presente para que extraiam plugins e colaborem com o projeto.</p>
            <p>A minha apresentação foi mais abstrata e basicamente questionei sobre a integração de sistemas usando frameworks MVC em vários pontos diferentes sobe o título &#8220;MVC além do MVC&#8221;. Slides:</p>
            <div id="__ss_9241778" style="width: 425px;">
              <p><strong style="display: block; margin: 12px 0 4px;">MVC além do MVC (LT at qconsp2011)</strong> <iframe src="https://www.slideshare.net/slideshow/embed_code/9241778" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" width="425" height="355"></iframe></p>
              <div style="padding: 5px 0 12px;">
                View more presentations from David Paniz
              </div>
            </div>
          </div>
          <div class="post-data">
            Posted in <a href="/category/arquitetura/" title="View all posts in Arquitetura">Arquitetura</a>, <a href="/category/palestras-apresentacoes/" title="View all posts in Palestras / Apresentações">Palestras / Apresentações</a>
          </div>
          <div class="post-edit"></div>
        </div>
        <div id="post-434" class="post-434 post type-post status-publish format-standard hentry category-flex category-java category-ruby tag-amf tag-bean-validation tag-blazeds tag-flex-2 tag-graniteds tag-jsf2 tag-static_server tag-stella tag-vraptor">
          <h2 class="entry-title post-title"><a href="/2011/05/30/alguns-projetos-open-source/" rel="bookmark">Alguns projetos Open Source</a></h2>
          <div class="post-meta">
            <span class="meta-prep meta-prep-author posted">Posted on</span> <a href="/2011/05/30/alguns-projetos-open-source/" title="3:34 pm" rel="bookmark"><span class="timestamp updated">30 May 2011</span></a> <span class="byline">by</span> <span class="author vcard"><a class="url fn n" href="/author/david-paniz/" title="View all posts by David Paniz">David Paniz</a></span> <span class="comments-link"><span class="mdash">&mdash;</span> <a href="/2011/05/30/alguns-projetos-open-source/#comments" title="Comment on Alguns projetos Open Source">3 Comments &darr;</a></span>
          </div>
          <div class="post-entry">
            <p>Antes de mais nada, me desculpem pelos meses que o blog anda sem atualizações, um dos motivos é justamente o que vou comentar neste post. Desde o começo do ano passei a contribuir um pouco mais com projetos Open Source e neste post vou falar um pouco sobre 3 colaborações que gostei muito de ter participado e que o resultado final me agradou muito também.</p>
            <h3>VRaptor Flex Plugin</h3>
            <p>Em ordem cronológica o primeiro &#8220;grande&#8221; feito ao Open Source neste ano foi ter criado, com a ajuda do Lucas Cavalcanti e do <a>Erich Egert</a> um plugin para o VRaptor que possibilita as chamadas remotas usando o protocolo AMF. Na verdade não fizemos todo o trabalho de (de)serialização, mas assim como o suporte para Spring, EJB, etc.&nbsp; O que fizemos foi criar uma factory que você deve registrar no framework que realmente sabe fazer a serialização para AMF. Por enquanto estamos suportanto o BlazeDS e o GraniteDS.</p>
            <p>Para saber um pouco mais sobre o plugin e como configurar e usar veja o página no próprio github para issues podem usar a mesma página de issues do VRaptor.</p>
            <h3>Stella 2.0</h3>
            <p>Alguns de vocês já deve ter ouvido falar no Stella. Um projeto com um monte de utilidades para desenvolvedores brasileiros, como validadores de CPF e CNPJ, gerador de boleto, conversor de números por extenso e um pouco mais. Embora muito útil, o projeto andava meio parado e recentemente eu, o Mario Amaral e o Paulo Silveira, além de outras contribuições da comunidade, atualizamos o projeto para suportar as &#8220;novas&#8221; especificações do JEE6 como o JSF2 e Bean Validation, além de muita refatoração e algumas melhorias na API.</p>
            <p>Acabamos de liberar um release beta e em breve devemos ter uma versão 2.0 final disponível.</p>
            <h3>Static Server</h3>
            <p>O último projeto que trabalhei recentemente surgiu no momento de subir o site do Stella. Na Caelum estamos numa tendência de cada vez mais tirar a responsabilidade de infra das nossas mãos, então mesmo com um site estático a gente queria subir no Heroku ou Google App Engine. Pensamos em criar uma aplicação rails e deixar todos os arquivos no public, mas não fazia o menor sentido, então comecei a fazer usando apenas Rack, mas ficamos com o problema da home, aí comecei uma dsl pra configurar forward e redirect, fui refatorando até que surgiu o StaticServer que já está no rubygems como static_server.</p>
            <p>Em breve vou colocar uma documentação melhor, mas por enquanto vocês podem ver os exemplos nos testes de integração.</p>
            <h3>Ajude você também</h3>
            <p>Esses e tantos outros projetos, brasileiros ou não, sempre precisam de ajuda, seja com código, documentação, exemplos e até mesmo encontrando e registrando bugs. Toda ajuda é bem vinda, sempre!</p>
            <p>Em breve devo colocar mais exemplos e possivelmente escrever posts com mais detalhes da utilização de cada um deles.</p>
          </div>
          <div class="post-data">
            Tagged with: <a href="/tag/amf/" rel="tag">amf</a>, <a href="/tag/bean-validation/" rel="tag">bean validation</a>, <a href="/tag/blazeds/" rel="tag">blazeds</a>, <a href="/tag/flex-2/" rel="tag">flex</a>, <a href="/tag/graniteds/" rel="tag">graniteds</a>, <a href="/tag/jsf2/" rel="tag">jsf2</a>, <a href="/tag/static_server/" rel="tag">static_server</a>, <a href="/tag/stella/" rel="tag">stella</a>, <a href="/tag/vraptor/" rel="tag">vraptor</a><br>
            Posted in <a href="/category/flex/" title="View all posts in Flex">Flex</a>, <a href="/category/java/" title="View all posts in Java">Java</a>, <a href="/category/ruby/" title="View all posts in Ruby">Ruby</a>
          </div>
          <div class="post-edit"></div>
        </div>
        <div id="post-418" class="post-418 post type-post status-publish format-standard hentry category-rails category-testes tag-rails3 tag-remarkable tag-rspec2 tag-shoulda">
          <h2 class="entry-title post-title"><a href="/2011/01/26/melhorando-os-testes-dos-seus-models-do-rails-3-com-rspec-2-e-remarkable-ou-shoulda/" rel="bookmark">Melhorando os testes dos seus models do Rails 3 com RSpec 2 e Remarkable ou Shoulda</a></h2>
          <div class="post-meta">
            <span class="meta-prep meta-prep-author posted">Posted on</span> <a href="/2011/01/26/melhorando-os-testes-dos-seus-models-do-rails-3-com-rspec-2-e-remarkable-ou-shoulda/" title="3:11 pm" rel="bookmark"><span class="timestamp updated">26 January 2011</span></a> <span class="byline">by</span> <span class="author vcard"><a class="url fn n" href="/author/david-paniz/" title="View all posts by David Paniz">David Paniz</a></span> <span class="comments-link"><span class="mdash">&mdash;</span> <a href="/2011/01/26/melhorando-os-testes-dos-seus-models-do-rails-3-com-rspec-2-e-remarkable-ou-shoulda/#comments" title="Comment on Melhorando os testes dos seus models do Rails 3 com RSpec 2 e Remarkable ou Shoulda">3 Comments &darr;</a></span>
          </div>
          <div class="post-entry">
            <p>Uma das coisas que mais me incomoda quando estou fazendo os meus testes,&nbsp; é escrever testes para verificar os campos obrigatórios. Eu gosto muito de usar o RSpec e aqui está um exemplo comum de código que testa um modelo &#8216;Usuario&#8217; que tem os atributos &#8216;nome&#8217; e &#8216;idade&#8217; obrigatórios:</p>
            <pre class="brush: ruby; title: ; notranslate" title="">
describe Usuario do
  before :all do
    @obrigatorios = {nome: 'David Paniz', idade: 25}
  end

  it &quot;deve ter Nome obrigatório&quot; do
    u = Usuario.new(@obrigatorios.merge(nome: nil))
    u.should_not be_valid
    u.should have_at_least(1).error_on(:nome)
  end

  it &quot;deve ter Idade obrigatório&quot; do
    u = Usuario.new(@obrigatorios.merge(idade: nil))
    u.should_not be_valid
    u.should have_at_least(1).error_on(:idade)
  end

  it &quot;Deve ser valido com todos os campos obrigatório&quot; do
    u = Usuario.new(@obrigatorios)
    u.should be_valid
  end
end
</pre>
            <p>Sempre que escrevo um código desses sinto que estou testando o Rails e não o meu model. No fundo a única coisa que tenho que testar é se eu coloquei a linha do <strong>validates_presence_of :atributo</strong>. O resto do trabalho (deixar o valid? falso e criar o error no campo) é problema do Rails e não do meu modelo. Além desse sensação estranha de testar a coisa errada esse é o tipo de código que eu escrevo e na hora percebo que a abordagem não é nada DRY.</p>
            <p>Dei uma olhada em 2 opções para melhorar a abordagem dos testes, o Shoulda e o Remarkable.</p>
            <h2>Remarkable</h2>
            <p>Para instalar o remarkable com o Rails 3 o RSpec 2 precisamos usar a versão 4 que ainda está em alpha, nesse instante 4.0.0.alpha4.<br>
            Adicione ao seu Gemfile as dependências:</p>
            <pre class="brush: ruby; title: ; notranslate" title="">
gem &quot;rspec&quot;
gem &quot;rspec-rails&quot;
gem &quot;remarkable_activerecord&quot;, '4.0.0.alpha4'
</pre>
            <p>Usando o Remakable você ganha alguns matcher especiais para verificar apenas se você realmente colocou a validação do atributo no seu model, por exemplo o matcher <strong>validate_presence_of</strong>. O código de teste equivalente ao de cima ficaria assim:</p>
            <pre class="brush: ruby; title: ; notranslate" title="">
describe Usuario do
  it {should validate_presence_of :nome }
  it {should validate_presence_of :idade }
end
</pre>
            <p>Para que o RSpec reconheça esses matchers do Remakable é preciso um último detalhe de configuração que é adicionar um require do remarkable no seu <strong>spec_helper.rb</strong> logo abaixo do require &#8216;rspec/rails&#8217;</p>
            <pre class="brush: ruby; highlight: [5]; title: ; notranslate" title="">
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV[&quot;RAILS_ENV&quot;] ||= 'test'
require File.expand_path(&quot;../../config/environment&quot;, __FILE__)
require 'rspec/rails'
require 'remarkable/active_record'
</pre>
            <h2>Shoulda</h2>
            <p>O shoulda ficou muito famoso sendo utilizado com o TestUnit, mas existe um sub-projeto dele que é o &#8216;shoulda-matchers&#8217;, atualmente na versão 1.0.0.beta1, que é a gem que vamos usar com o Rails 3 o RSpec 2. Adicione ao seu Gemfile as dependências:</p>
            <pre class="brush: ruby; title: ; notranslate" title="">
gem &quot;rspec&quot;
gem &quot;rspec-rails&quot;
gem &quot;shoulda-matchers&quot;
</pre>
            <p>Curiosamente para esses casos mais básicos o matcher do Shoulda é idêntico ao do Remakable e o código de teste fica idêntico ao dele:</p>
            <pre class="brush: ruby; title: ; notranslate" title="">
describe Usuario do
  it {should validate_presence_of :nome }
  it {should validate_presence_of :idade }
end
</pre>
            <p>Dessa vez não é preciso nenhuma configuração extra, basta apenas executar os testes e:&nbsp; Seja uma pessoa mais feliz!</p>
            <h2>Conclusão</h2>
            <p>Ambas são ótimas opções para dar uma bombada nos seus testes, cada um com suas vantagens e desvantagens. Recomendo uma lida nas respectivas documentações para conhecer mais de cada um deles e escolher o que melhor supre suas necessidades.</p>
          </div>
          <div class="post-data">
            Tagged with: <a href="/tag/rails3/" rel="tag">rails3</a>, <a href="/tag/remarkable/" rel="tag">remarkable</a>, <a href="/tag/rspec2/" rel="tag">rspec2</a>, <a href="/tag/shoulda/" rel="tag">shoulda</a><br>
            Posted in <a href="/category/rails/" title="View all posts in Rails">Rails</a>, <a href="/category/testes/" title="View all posts in Testes">Testes</a>
          </div>
          <div class="post-edit"></div>
        </div>
        <div id="post-409" class="post-409 post type-post status-publish format-standard hentry category-uncategorized">
          <h2 class="entry-title post-title"><a href="/2010/12/29/meu-ambiente-de-desenvolvimento-em-7-itens/" rel="bookmark">Meu ambiente de desenvolvimento em 7 itens</a></h2>
          <div class="post-meta">
            <span class="meta-prep meta-prep-author posted">Posted on</span> <a href="/2010/12/29/meu-ambiente-de-desenvolvimento-em-7-itens/" title="10:28 pm" rel="bookmark"><span class="timestamp updated">29 December 2010</span></a> <span class="byline">by</span> <span class="author vcard"><a class="url fn n" href="/author/david-paniz/" title="View all posts by David Paniz">David Paniz</a></span> <span class="comments-link"><span class="mdash">&mdash;</span> <a href="/2010/12/29/meu-ambiente-de-desenvolvimento-em-7-itens/#comments" title="Comment on Meu ambiente de desenvolvimento em 7 itens">3 Comments &darr;</a></span>
          </div>
          <div class="post-entry">
            <p>Fui convidado para a brincadeira pelo Adriano Almeida e pelo Anderson Leite e aí vamos nós:</p>
            <h3>Máquina / Sistema Operacional</h3>
            <p>Minha máquina &#8220;oficial&#8221; é meu macbook white 13&#8243; que já está comigo desde 2008, mas com 4Gb e com upgrade pro Snow Leopard.</p>
            <h3>Editor</h3>
            <p>Pra arquivos texto no geral e RoR tenho e uso bastante o TextMate. Já dei algumas chances pro Vim, mas ainda não me adaptei perfeitamente, recentemente decidi lhe dar outra e parece que agora vou ficar com ele mesmo. Estou usando as configurações do Akita e o Bundle de afc que o Adriano fez. (afc é o formato que usamos pra escrever as apostilas da Caelum &#8211; Quem já teve curiosidade, conheça o Tubaina).<br>
            Pra programar java não abro mão do Eclipse!</p>
            <h3>Terminal</h3>
            <p>O bom e velho bash mesmo. Algumas poucas frescuras no ~/.bash_profile pra adicionar cores e personalizar o PS1, mas nada de mais. Normalmente meu terminal está uma zona com pelo menos umas 5 ou 6 abas abertas. Costumo ter umas 2 ou 3 por projeto (server, testes e &#8220;outros&#8221;) e quase sempre tenho abas de mais de projeto aberta.</p>
            <h3>Browser</h3>
            <p>Hoje meu browser principal é o Chrome, tanto pro dia-a-dia quanto pra desenvolvimento, mas tenho e uso o FF e o Safari. Assim como meu Terminal, meu browser também é uma salada de abas, mas piorada. Aqui tenho umas abas que ficam semanas abertas aguardando para serem lidas.</p>
            <h3>Software</h3>
            <p>QuickSilver, Adium, Skype, TweetDeck, DropBox e Keynote, além dos indispensáveis serviços do Google: GMail, Calendar e Docs.</p>
            <h3>Source-code</h3>
            <p>Felizmente tenho usado apenas o git hoje em dia.</p>
            <h3>Música</h3>
            <p>Quando preciso de muita concentração coloco meus fones e um bom Power Metal pra me isolar do mundo. Independente disso, gosto bastante de ouvir música enquanto programo, mas dentro da Caelum acabo ficando com o volume mais baixo ou com o fone em apenas 1 dos ouvidos pra ouvir as discussões. Um ponto curioso sobre as músicas comigo é que não posso ouvir uma música que me empolga e eu não conheço ela perfeitamente (saber tocar e/ou cantar). Ou escuto uma música que domino ou uma música neutra, se não ela passa a atrapalhar ao invés de ajudar. Para conhecer meu gosto musical recomendo uma passada no meu perfil no Last.fm</p>
            <p>Os meus convidados são: Todos autores do Vida Geek</p>
          </div>
          <div class="post-data">
            Posted in <a href="/category/uncategorized/" title="View all posts in Uncategorized">Uncategorized</a>
          </div>
          <div class="post-edit"></div>
        </div>
        <div class="navigation">
          <div class="previous">
            <a href="/page/2/">&#8249; Older posts</a>
          </div>
          <div class="next"></div>
        </div>
      </div>
      <div id="widgets" class="grid col-300 fit">
        <div id="search-2" class="widget-wrapper widget_search">
          <div class="widget-title">
            Busca
          </div>
          <form method="get" id="searchform" action="https://davidpaniz.com/" name="searchform">
            <input type="text" class="field" name="s" id="s" placeholder="search here &hellip;"> <input type="submit" class="submit" name="submit" id="searchsubmit" value="Go">
          </form>
        </div>
        <div id="recent-posts-2" class="widget-wrapper widget_recent_entries">
          <div class="widget-title">
            Posts recentes
          </div>
          <ul>
            <li>
              <a href="/2012/10/03/matematica-para-jogos-parte-2-a-fisica-da-colisao/">Matemática para jogos – Parte 2 – A física da colisão</a>
            </li>
            <li>
              <a href="/2012/09/13/matematica-para-jogos-parte-1-colisao-de-circulos/">Matemática para jogos &#8211; Parte 1 &#8211; Colisão de círculos</a>
            </li>
            <li>
              <a href="/2012/07/11/dica-rapida-bulk-update-atualizacao-em-massa-no-rails/">[Dica Rápida] Bulk update (atualização em massa) no Rails</a>
            </li>
            <li>
              <a href="/2012/06/21/da-ide-ao-editor-de-texto-do-editor-de-volta-a-ide-e-de-volta-de-novo-ao-editor/">Da IDE ao editor de texto, do editor de volta a IDE e de volta de novo ao editor</a>
            </li>
            <li>
              <a href="/2012/01/10/renomeando-arquivos-em-ruby/">Renomeando arquivos em ruby</a>
            </li>
          </ul>
        </div>
        <div id="categories-2" class="widget-wrapper widget_categories">
          <div class="widget-title">
            Categorias
          </div>
          <ul>
            <li class="cat-item cat-item-3">
              <a href="/category/agile/" title="View all posts filed under Agile">Agile</a>
            </li>
            <li class="cat-item cat-item-4">
              <a href="/category/air/" title="View all posts filed under AIR">AIR</a>
            </li>
            <li class="cat-item cat-item-5">
              <a href="/category/ant/" title="View all posts filed under ant">ant</a>
            </li>
            <li class="cat-item cat-item-6">
              <a href="/category/arquitetura/" title="View all posts filed under Arquitetura">Arquitetura</a>
              <ul class='children'>
                <li class="cat-item cat-item-7">
                  <a href="/category/arquitetura/ddd/" title="View all posts filed under DDD">DDD</a>
                </li>
              </ul>
            </li>
            <li class="cat-item cat-item-8">
              <a href="/category/dica-rapida/" title="View all posts filed under dica rapida">dica rapida</a>
            </li>
            <li class="cat-item cat-item-9">
              <a href="/category/flex/" title="View all posts filed under Flex">Flex</a>
            </li>
            <li class="cat-item cat-item-10">
              <a href="/category/git/" title="View all posts filed under git">git</a>
            </li>
            <li class="cat-item cat-item-11">
              <a href="/category/hibernate/" title="View all posts filed under Hibernate">Hibernate</a>
            </li>
            <li class="cat-item cat-item-14">
              <a href="/category/ivy/" title="View all posts filed under ivy">ivy</a>
            </li>
            <li class="cat-item cat-item-15">
              <a href="/category/java/" title="View all posts filed under Java">Java</a>
            </li>
            <li class="cat-item cat-item-16">
              <a href="/category/java-me/" title="View all posts filed under Java ME">Java ME</a>
            </li>
            <li class="cat-item cat-item-17">
              <a href="/category/jogos/" title="View all posts filed under Jogos">Jogos</a>
            </li>
            <li class="cat-item cat-item-19">
              <a href="/category/mac/" title="View all posts filed under Mac">Mac</a>
            </li>
            <li class="cat-item cat-item-20">
              <a href="/category/matematica/" title="View all posts filed under Matemática">Matemática</a>
            </li>
            <li class="cat-item cat-item-21">
              <a href="/category/palestras-apresentacoes/" title="View all posts filed under Palestras / Apresentações">Palestras / Apresentações</a>
            </li>
            <li class="cat-item cat-item-22">
              <a href="/category/papyrus/" title="View all posts filed under Papyrus">Papyrus</a>
            </li>
            <li class="cat-item cat-item-24">
              <a href="/category/rails/" title="View all posts filed under Rails">Rails</a>
            </li>
            <li class="cat-item cat-item-25">
              <a href="/category/ruby/" title="View all posts filed under Ruby">Ruby</a>
            </li>
            <li class="cat-item cat-item-26">
              <a href="/category/testes/" title="View all posts filed under Testes">Testes</a>
            </li>
            <li class="cat-item cat-item-1">
              <a href="/category/uncategorized/" title="View all posts filed under Uncategorized">Uncategorized</a>
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
  <div id="footer" class="clearfix">
    <div id="footer-wrapper">
      <div class="grid col-940">
        <div class="grid col-540"></div>
        <div class="grid col-380 fit">
          <ul class="social-icons">
            <li class="twitter-icon"><img src="/wp-content/themes/responsive/core/icons/twitter-icon.png" width="24" height="24" alt="Twitter"></li>
            <li class="linkedin-icon"><img src="/wp-content/themes/responsive/core/icons/linkedin-icon.png" width="24" height="24" alt="LinkedIn"></li>
            <li class="rss-feed-icon"><img src="/wp-content/themes/responsive/core/icons/rss-feed-icon.png" width="24" height="24" alt="RSS Feed"></li>
            <li class="google-plus-icon"><img src="/wp-content/themes/responsive/core/icons/googleplus-icon.png" width="24" height="24" alt="Google Plus"></li>
          </ul>
        </div>
      </div>
      <div class="grid col-300 copyright">
        &copy; 2013 <a href="/" title="Ideia Cabeluda">Ideia Cabeluda</a>
      </div>
      <div class="grid col-300 scroll-top">
        <a href="#scroll-top" title="scroll to top">&uarr;</a>
      </div>
      <div class="grid col-300 fit powered">
        Responsive Theme powered by WordPress
      </div>
    </div>
  </div>
  <script type='text/javascript' src='/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shCore.js?ver=3.0.83c'></script> 
  <script type='text/javascript' src='/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushPlain.js?ver=3.0.83c'></script> 
  <script type='text/javascript' src='/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/scripts/shBrushRuby.js?ver=3.0.83c'></script> 
  <script type='text/javascript'>


        (function(){
                var corecss = document.createElement('link');
                var themecss = document.createElement('link');
                var corecssurl = "http://davidpaniz.com/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/styles/shCore.css?ver=3.0.83c";
                if ( corecss.setAttribute ) {
                                corecss.setAttribute( "rel", "stylesheet" );
                                corecss.setAttribute( "type", "text/css" );
                                corecss.setAttribute( "href", corecssurl );
                } else {
                                corecss.rel = "stylesheet";
                                corecss.href = corecssurl;
                }
                document.getElementsByTagName("head")[0].insertBefore( corecss, document.getElementById("syntaxhighlighteranchor") );
                var themecssurl = "http://davidpaniz.com/wp-content/plugins/syntaxhighlighter/syntaxhighlighter3/styles/shThemeEclipse.css?ver=3.0.83c";
                if ( themecss.setAttribute ) {
                                themecss.setAttribute( "rel", "stylesheet" );
                                themecss.setAttribute( "type", "text/css" );
                                themecss.setAttribute( "href", themecssurl );
                } else {
                                themecss.rel = "stylesheet";
                                themecss.href = themecssurl;
                }
                //document.getElementById("syntaxhighlighteranchor").appendChild(themecss);
                document.getElementsByTagName("head")[0].insertBefore( themecss, document.getElementById("syntaxhighlighteranchor") );
        })();
        SyntaxHighlighter.config.strings.expandSource = '+ expand source';
        SyntaxHighlighter.config.strings.help = '?';
        SyntaxHighlighter.config.strings.alert = 'SyntaxHighlighter\n\n';
        SyntaxHighlighter.config.strings.noBrush = 'Can\'t find brush for: ';
        SyntaxHighlighter.config.strings.brushNotHtmlScript = 'Brush wasn\'t configured for html-script option: ';
        SyntaxHighlighter.defaults['pad-line-numbers'] = true;
        SyntaxHighlighter.all();
  </script> 
  <script type='text/javascript' src='/wp-content/themes/responsive/core/js/responsive-scripts.js?ver=1.2.4'></script>
</body>
</html>
