<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>codificando.com &#187; rails</title>
	<atom:link href="http://codificando.com/tag/rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://codificando.com</link>
	<description>Desenvolvimento de Software com qualidade</description>
	<lastBuildDate>Tue, 31 Jan 2012 09:49:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Linkedin refaz seu mobile stack com Node.JS</title>
		<link>http://codificando.com/2011/08/linkedin-refaz-seu-mobile-stack-nodejs/</link>
		<comments>http://codificando.com/2011/08/linkedin-refaz-seu-mobile-stack-nodejs/#comments</comments>
		<pubDate>Tue, 16 Aug 2011 20:38:27 +0000</pubDate>
		<dc:creator>Emerson Macedo</dc:creator>
				<category><![CDATA[nodejs]]></category>
		<category><![CDATA[Sem categoria]]></category>
		<category><![CDATA[artigo]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[case]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://codificando.com/?p=993</guid>
		<description><![CDATA[Hoje pela manhã, o likedin lançou a nova versão mobile do software. O líder de desenvolvimento mobile Kiran Prasad, deu uma entrevista sobre o assunto. Um dos grandes destaques técnicos foi a escolha de todas as partes que não necessitam de &#8230; <a href="http://codificando.com/2011/08/linkedin-refaz-seu-mobile-stack-nodejs/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Hoje pela manhã, o likedin lançou a <a href="http://venturebeat.com/2011/08/16/linkedin-mobile-app/" target="_blank">nova versão mobile do software</a>. O líder de desenvolvimento mobile Kiran Prasad, <a href="http://venturebeat.com/2011/08/16/linkedin-node/" target="_blank">deu uma entrevista sobre o assunto</a>.</p>
<p>Um dos grandes destaques técnicos foi a escolha de todas as partes que não necessitam de funções nativas dos aparelhos serem feitas usando HTML5.</p>
<p>O ponto de destaque desse meu post é que todo o stack mobile foi refeito em Node.JS (o antigo era feito em Rails). Eles sairam de 15 servidores com 15 instâncias para apenas 4 instâncias, conseguindo servir o dobro  do tráfego.</p>
<p>Isso é mais um case de sucesso no uso de Node.JS, fazendo com que a plataforma seja promissora para os próximos anos.</p>
<p><strong>Disclaimer: </strong>Um ponto importante para tomar cuidado é não determinar que Node.JS é melhor que Ruby on Rails ou coisa do tipo. Faz pouco tempo que o <a href="http://engineering.twitter.com/2011/04/twitter-search-is-now-3x-faster_1656.html" target="_blank">twitter trocou Rails por Java em partes</a> do seu sistema, mas a maior mudança na verdade foi arquitetural, como o próprio artigo mostra. Portanto, não devemos tomar conclusões precipitadas, até porque existem diversos casos de aplicações com grande volume de acesso que utilizam essa tecnologia muito bem.
<p><font color="#B4B4B4" size="-2">Post Footer automatically generated by <a href="http://www.freetimefoto.com/add_post_footer_plugin_wordpress" style="color: #B4B4B4; text-decoration:underline;">Add Post Footer Plugin</a> for wordpress.</font></p>
]]></content:encoded>
			<wfw:commentRss>http://codificando.com/2011/08/linkedin-refaz-seu-mobile-stack-nodejs/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Volta das férias, RubyConf Brasil e um pouco de NodeJS</title>
		<link>http://codificando.com/2010/11/volta-das-frias-rubyconf-brasil-um-pouco-de-node/</link>
		<comments>http://codificando.com/2010/11/volta-das-frias-rubyconf-brasil-um-pouco-de-node/#comments</comments>
		<pubDate>Tue, 23 Nov 2010 16:07:26 +0000</pubDate>
		<dc:creator>Emerson Macedo</dc:creator>
				<category><![CDATA[eventos]]></category>
		<category><![CDATA[nodejs]]></category>
		<category><![CDATA[palestra]]></category>
		<category><![CDATA[pensamentos]]></category>
		<category><![CDATA[pragmatic]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rubyconf]]></category>

		<guid isPermaLink="false">http://codificando.com/?p=639</guid>
		<description><![CDATA[No final do mês de outubro e no início do mês de novembro tirei um tempo de férias (todo mundo precisa, rs). Nesse tempo eu evitei ao máximo me envolver com trabalho, mas algumas atividades foram inevitáveis até porque já &#8230; <a href="http://codificando.com/2010/11/volta-das-frias-rubyconf-brasil-um-pouco-de-node/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>No final do mês de outubro e no início do mês de novembro tirei um tempo de férias (todo mundo precisa, rs). Nesse tempo eu evitei ao máximo me envolver com trabalho, mas algumas atividades foram inevitáveis até porque já estavam programadas.</p>
<p>Nos dias 26 e 27 de outubro, participei do <a href="http://www.rubyconf.com.br/" target="_blank">RubyConf Brasil</a> e <a href="http://www.rubyconf.com.br/pt-BR/pages/speakers#emerson_macedo" target="_blank">apresentei a palestra &#8220;Beyond Ruby With NodeJS&#8221;</a>, onde basicamente eu falo sobre a repetição do erro em tentar tornar uma tecnologia boa em uma panaceia. Eu sou um rubista convicto e curto muito a tecnologia, mas como já <a href="http://codificando.com/2010/02/nao-se-apaixone-pela-sua-tecnologia/" target="_blank">falei tempos atrás aqui mesno nesse blog</a>, não creio ser Ruby/Rails a <a href="http://en.wikipedia.org/wiki/No_Silver_Bullet" target="_blank">bala de prata</a> que tanto procuramos (e certamente não acharemos). Os slides seguem abaixo e em breve o <a href="http://www.rubyconf.com.br/pt-BR/videos" target="_blank">vídeo estará disponível no site do evento</a>.</p>
<div id="__ss_5584999" style="width: 425px;"><strong><a title="Beyond Ruby with NodeJS - RubyConf Brasil 2010" href="http://www.slideshare.net/emerleite/beyond-ruby-with-nodejs-rubyconf-brasil-2010">Beyond Ruby with NodeJS &#8211; RubyConf Brasil 2010</a></strong><object id="__sse5584999" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=palestrarubyconf-101027130357-phpapp01&amp;stripped_title=beyond-ruby-with-nodejs-rubyconf-brasil-2010&amp;userName=emerleite" /><param name="name" value="__sse5584999" /><param name="allowfullscreen" value="true" /><embed id="__sse5584999" type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=palestrarubyconf-101027130357-phpapp01&amp;stripped_title=beyond-ruby-with-nodejs-rubyconf-brasil-2010&amp;userName=emerleite" name="__sse5584999" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="padding: 5px 0 12px;">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/emerleite">Emerson Macedo</a>.</div>
</div>
<p>Passado alguns dias, lancei o <a href="http://nodecasts.org/#episode-2" target="_blank">segundo episódio</a> do <a href="http://nodecasts.org" target="_blank">NodeCasts</a>, um site de screencasts em <a href="http://en.wikipedia.org/wiki/High-definition_video" target="_blank">HD</a> sobre <a href="http://nodejs.org/" target="_blank">NodeJS</a>. O ritmo ainda está um pouco lento, pois a idéia inicial era fazer um screencast a cada 15 dias, mas acabei percebendo que fazer <a href="http://en.wikipedia.org/wiki/Screencast" target="_blank">screencasts</a> bem produzidos e com qualidade, sem pausas estranhas e outros detalhes mais que geram um resultado legal da um bocado de trabalho e não é uma tarefa tão simples. Estou aprimorando o processo de produção pra eu poder lançar um a cada 15 dias sem problemas. Se quiser curtir o <a href="http://nodecasts.org/#episode-2" target="_blank">episódio 2</a> ou <a href="http://nodecasts.org/#episode-1" target="_blank">episódio 1</a> basta clicar no texto linkado. Os screencasts são todos em inglês e colaboradores para tradução são sempre bem vindos e receberão os devidos créditos.</p>
<p>PS: A partir de hoje o blog retorna das férias <img src='http://codificando.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
<p><font color="#B4B4B4" size="-2">Post Footer automatically generated by <a href="http://www.freetimefoto.com/add_post_footer_plugin_wordpress" style="color: #B4B4B4; text-decoration:underline;">Add Post Footer Plugin</a> for wordpress.</font></p>
]]></content:encoded>
			<wfw:commentRss>http://codificando.com/2010/11/volta-das-frias-rubyconf-brasil-um-pouco-de-node/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>RVM com Passenger e múltiplas instâncias HTTPD</title>
		<link>http://codificando.com/2010/07/rvm-passenger-multiplas-instancias-httpd/</link>
		<comments>http://codificando.com/2010/07/rvm-passenger-multiplas-instancias-httpd/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 19:31:29 +0000</pubDate>
		<dc:creator>Emerson Macedo</dc:creator>
				<category><![CDATA[infra]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[deploy]]></category>
		<category><![CDATA[passenger]]></category>
		<category><![CDATA[rvm]]></category>

		<guid isPermaLink="false">http://codificando.com/?p=500</guid>
		<description><![CDATA[No artigo anterior, falei sobre sobre RVM (Ruby Version Manager), explicando sobre instalação, configuração e seu funcionamento interno. Porém, não mencionei nada sobre seu uso com o Phusion Passenger (A.K.A mod_rails, mod_rack), e algumas pessoas me perguntaram sobre isso. Eu &#8230; <a href="http://codificando.com/2010/07/rvm-passenger-multiplas-instancias-httpd/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>No <a href="http://codificando.com/2010/07/gerencie-ambiente-ruby-rvm/">artigo anterior</a>, falei sobre sobre <a href="http://rvm.beginrescueend.com/" target="_blank">RVM (Ruby Version Manager)</a>, explicando sobre instalação, configuração e seu funcionamento interno. Porém, não mencionei nada sobre seu uso com o <a href="http://www.modrails.com/" target="_blank">Phusion Passenger (A.K.A mod_rails, mod_rack)</a>, e algumas pessoas me perguntaram sobre isso. Eu não abordei essa parte no artigo anterior por duas razões: A primeira é porque já era madrugada e o sono já me dominava <img src='http://codificando.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  e a segunda porque o artigo iria ficar muito grande e o conteúdo inicial já era suficiente para montar um ambiente local na máquina do desenvolvedor.</p>
<p>Esse artigo basea-se no uso do <a href="http://httpd.apache.org/" target="_blank">Apache 2.x</a> e no <a href="http://www.apple.com/macosx/" target="_blank">Sistema Operacional OSX</a>. Porém, as configurações em SOs <a href="http://en.wikipedia.org/wiki/POSIX" target="_blank">POSIX</a> se assemelham, portanto usuários do <a href="http://www.ubuntu.com/" target="_blank">Ubuntu</a> e afins não deverão ter nenhum problema.</p>
<h3><strong>Instalando o Passenger em uma Rubie/Gemset</strong></h3>
<p>Se você já usa RVM ou seguiu os passos do <a href="http://codificando.com/2010/07/gerencie-ambiente-ruby-rvm/">artigo anterior</a>, já deve ter tudo instalado e configurado e já possui uma Rubie com ou sem Gemsets (não faz diferença ter Gemsets para esse artigo). Caso contrário, leia novamente.</p>
<p>Abra o terminal e entre na sua Rubie/Gemset, instale a gem do passenger e o módulo do apache (ou nginx):</p>
<p><strong>$ rvm use rubie@gemset </strong><strong><span style="font-weight: normal;">#ex: rvm use 1.8.7@minhaapp</span><br />
$ gem install passenger<br />
$ rvmsudo passenger-install-apache2-module</strong></p>
<p>Muita atenção nesse momento. A instalação do módulo do apache (ou nginx) deve ser feita usando rvmsudo. Sem isso não funcionou comigo e acho que com ninguém vai funcionar <img src='http://codificando.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Feito isso, no fim da instalação do módulo ele vai mandar você colocar aquelas 3 linhas de configuração do Passenger nas suas configs do apache. Eu sugiro criar um arquivo <strong>passenger.conf</strong> ou similar e colar esse código dentro desse arquivo, pra não misturar com as configs básicas do Servidor Http. Se você estiver usando Mac, as configurações do apache provavelmente estarão em <strong>/etc/apache2</strong> e existe um diretório <strong>other</strong>, onde colocamos as configurações adicionais, como esta que acabamos de criar para o passenger.</p>
<p>Agora precisamos ajustar um detalhe nessas configurações do Passenger. Quando instalamos o Passenger e módulo do apache em uma RVM, a terceira linha da configuração (PassengerRuby) que a instalação sugere, não aponta para o diretório correto, e não funciona. É necessário fazer uma modificação e vou explicar.</p>
<p>Quando instalamos a RMV, ele cria um diretório chamado <strong>~/.rvm/bin</strong>, onde ficam todos os executáveis das rubies (ruby, irb, gem, ri, rdoc). A instalação do Passenger não entende isso e aponta para uma estrutura diferente, formada da seguinte maneira: <strong>~/.rvm/rubies/{Rubie}/bin/ruby</strong>, e isso não funciona. Portanto, precisamos alterar essa linha para que fique da segunte forma:</p>
<p><strong>$ PassengerRuby ~/.rvm/bin/{Rubie}@{Gemset}</strong></p>
<p>A documentação sugere uma forma diferente dessa, nos indicando executar <strong>rvm {Rubie@Gemset} &#8211;passenger</strong> e substituir essa terceira linha da segunte forma:</p>
<p><strong>$ PassengerRuby ~/.rvm/bin/passenger_ruby</strong></p>
<p>O que isso faz é criar um link symbólico de <strong>passenger_ruby</strong> apontando para o <strong>{Rubie}@{Gemset}</strong> que você quer. Eu acho isso desnecessário, principalmente porque você pode querer usar o passenger com várias Rubies diferentes, que é o que vou abordar mais adiante. Portanto, eu prefiro ficar com a primeira opção.</p>
<p>Agora basta configurar o VirtualHost (presumo que você já sabiba fazer isso) e reiniciar o Apache. Nesse momento tudo já deve estar funcionando corretamente e você deve estar conseguindo ver sua aplicação funcionando. Não se esqueça de configurar o <strong>/etc/hosts</strong> (é bastante comum ver gente capotando porque esqueceu essa parte, rs).</p>
<h3><strong>Múltiplas apps em Rubies diferentes</strong></h3>
<p>Segundo a documentação do Passenger, <a href="http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerRuby" target="_blank">a diretiva PassengerRuby deve ser usada apenas uma vez</a>, nos limitando a ter nossas aplicações em uma Rubie/Gemset única. Uma maneira comum de trabalhar com essa limitação é instalar o <a href="http://www.rubyenterpriseedition.com/" target="_blank">Ruby Enterprise Edition (i.e. Ruby EE)</a> ou qualquer versão de Ruby e instalar todas as gems de todos os projetos nessa Rubie. A partir daí, basta criar um VirtualHost para cada Aplicação. Essa era a forma que trabalhavamos sem RVM. Com RVM a idéia e sair dessa limitação, podendo por exemplo rodar uma app usando Ruby 1.8.7 com Rails 2.3 e outra com Ruby 1.9.2 e Rails3. Isso inclusive num ambiente de produção, isolando bem as apps e evitando conflitos. Vamos portanto resolver o problema de outra maneira.</p>
<h3><strong>Criando uma nova configuração para o Apache</strong></h3>
<p>Talvez você não saiba, mas o diretório <strong>/etc/apache2</strong> não é o servidor Apache HTTPD propriamente dito, mas as configurações que esse servidor usa quando você sobe a instância. Por padrão, o <strong>apachectl</strong> procura as configurações nesse diretório, mas é perfeitamente possível indicar o path do arquivo de configuração que você quer usar, e é baseado nisto que vamos usar uma alternativa melhor.</p>
<p>Antes de qualquer coisa, vamos trocar alguns parâmetros na configuração default do Apache, para podermos rodar mais de uma instância sem nenhum tipo de problema acidental. Por padrão, nas configurações em <strong>/etc/apache2/httpd.conf</strong> tem um <strong>Listen</strong> definito para <strong>*:80</strong>. Vamos mudar isso:</p>
<p><strong>Listen 127.0.0.1:80</strong></p>
<p>Mudemos também quaisquer configurações de VirtualHost existentes que estejam usando *:80:</p>
<p><strong>VirtualHost 127.0.0.1:80</strong></p>
<p>Agora chegou a hora de clonar essas configurações para uma nova. Esse trabalho é um pouco chato, portanto resolvi criar um Shell Script para isso chamado <a href="http://gist.github.com/481665">osx-clone-apache.sh</a> que pode ser <a href="http://gist.github.com/raw/481665/63fe90110b0466a186b28d8be05a4e5194ab2db4/osx-clone-apache.sh" target="_blank">baixado aqui</a> e está no <a href="http://gist.github.com/emerleite" target="_blank">meu gist</a>. Já testei no Snow Leopard e Leopard. Se alguém quiser fazer um para ubuntu e outros SOs é bem vindo e eu coloco como update no artigo.</p>
<p>Baixe o Script e execute a seguinte linha no terminal:</p>
<p><strong>$ sudo ./osx-clone-apache.sh http-clone 127.0.0.1:80 127.0.0.2:80</strong></p>
<p>Onde <strong>http-clone</strong> é o nome da nova configuração que será criada dentro de <strong>/etc</strong>, <strong>127.0.0.1:80</strong> é o <strong>Listen</strong> que está configurado em <strong>/etc/apache2</strong> e <strong>127.0.0.2:80</strong> é o novo <strong>Listen</strong>. Essa nova configuração <strong>não leva nada do diretório other nem do passenger_pane_vhosts</strong> se você estiver usando o <a href="http://www.fngtps.com/passenger-preference-pane" target="_blank">Passenger Preference Pane</a>.</p>
<p>Agora que temos uma nova config do apache apontando para 127.0.0.2:80 precisamos configurar nossa interface de rede para passar a responder a esse ip:</p>
<p><strong>$ ifconfig lo0 alias 127.0.0.2/32</strong></p>
<p>Se não me engano, no Ubuntu isso não é necessário, mas no Mac eu não conheço outra forma de fazer isso. Se alguém souber é bem vindo.</p>
<p>Nesse ponto basta repetir os mesmos procedimentos de configuração de Passenger para novas Rubies e Gemsets para essa nova configuração do apache que acabamos de criar. Mais uma vez não esqueça de ajustar suas configurações no <strong>/etc/hosts</strong>.</p>
<p>O último passo é subir uma instância do apache usando as novas configurações criadas.</p>
<p><strong>$ sudo apachectl -f /etc/{novaconfig}/httpd.conf -k start</strong></p>
<p>Pronto, você já tem 2 instâncias do Apache rodando versões de Ruby/Rails diferentes na mesma máquina.</p>
<h3><strong>Conclusão</strong></h3>
<p>O RVM (Ruby Version Manager) trouxe uma nova perspectiva no gerênciamento de ambientes Ruby/Rails. O Deploy de Aplicações com versões de Ruby e Rails usando Phusion Passenger numa mesma máquina se torna trivial, desde que se saiba o que está fazendo. As configurações apresentadas neste artigo podem (e acho que devem) ser usadas também em ambiente de produção, pois a SANDBOX criada é muito mais simples de ser gerênciada do que aquela mistura habitual de VirtualHosts, Gems e afins.</p>
<p>Mãos a obra !!!
<p><font color="#B4B4B4" size="-2">Post Footer automatically generated by <a href="http://www.freetimefoto.com/add_post_footer_plugin_wordpress" style="color: #B4B4B4; text-decoration:underline;">Add Post Footer Plugin</a> for wordpress.</font></p>
]]></content:encoded>
			<wfw:commentRss>http://codificando.com/2010/07/rvm-passenger-multiplas-instancias-httpd/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Law of Demeter simples em Ruby com a gem demeter</title>
		<link>http://codificando.com/2009/11/law-of-demeter-simples-em-ruby-com-a-gem-demeter/</link>
		<comments>http://codificando.com/2009/11/law-of-demeter-simples-em-ruby-com-a-gem-demeter/#comments</comments>
		<pubDate>Thu, 26 Nov 2009 04:17:07 +0000</pubDate>
		<dc:creator>Emerson Macedo</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[demeter]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[dry]]></category>
		<category><![CDATA[lawofdemeter]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://codificando.com/?p=276</guid>
		<description><![CDATA[Depois de programar algum tempo em Ruby, me senti muito incomodado em ter que repetir um determinado código para manter minha estrutura respeitando a Law of Demeter. Pra quem não está familiarizado, segue um simples exemplo em Rails: #models class &#8230; <a href="http://codificando.com/2009/11/law-of-demeter-simples-em-ruby-com-a-gem-demeter/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Depois de programar algum tempo em Ruby, me senti muito incomodado em ter que repetir um determinado código para manter minha estrutura respeitando a <a href="http://en.wikipedia.org/wiki/Law_of_Demeter">Law of Demeter</a>. Pra quem não está familiarizado, segue um simples exemplo em Rails:</p>
<pre class="brush: ruby; title: ;">
#models
class Post &lt; ActiveRecord::Base
  has_many :comments
end

class Comment &lt; ActiveRecord::Base
  belongs_to :post
end

#view - erb|haml
@comment.post.title
@comment.post.name
@comment.post.something_else
</pre>
<p>O exemplo é um pouco forçado, mas o problema claro do exemplo é que estamos conhecendo demais sobre o objeto <strong>post</strong> dentro de <strong>comment</strong>. Se for necessário alguma alteração em algum dos atributos que estamos acessando diretamente, possivelmente isso resultará em modificações em cascata em todo código.</p>
<p>Depois dessa explicação básica para quem ainda não conhecia a <a href="http://en.wikipedia.org/wiki/Law_of_Demeter">Law of Demeter</a>, vamos aplicar algumas soluções:</p>
<p>Segunda tentativa:</p>
<pre class="brush: ruby; title: ;">
#models
class Post &lt; ActiveRecord::Base
  has_many :comments
end

class Comment &lt; ActiveRecord::Base
  belongs_to :post
  def post_title
    post ? post.title : nil #preciso verificar se é nulo, caso contrário terei problemas
  end
  def post_name
    post ? post.name : nil #preciso verificar se é nulo, caso contrário terei problemas
  end
  def post_something_else
    post ? post.something_else : nil #preciso verificar se é nulo, caso contrário terei problemas
  end
end

#view - erb|haml
@comment.post_title
@comment.post_name
@comment.post_something_else
</pre>
<p>Essa mudança resolve o problema. Acontece que isso acaba sendo um pattern para resolver o problema, portanto, precisamos encontrar uma forma de não ficar repetindo esse código.</p>
<p>Quem já leu o livro <a href="http://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X">The Pragmatic Programmer</a>, tem bem na memória o capítulo que apresenta o conceito <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY &#8211; D&#8217;ont Repeat Yourself</a>. Quem programa em Ruby e principalmente já usou o framework Rails sabe bem que <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> é um dos chavões que estão imbutidos na propaganda. Vamos então tentar fazer mais algumas modificações pra tentar alcançar esse objetivo:</p>
<p>Terceira tentativa:</p>
<pre class="brush: ruby; title: ;">
#models
class Post &lt; ActiveRecord::Base
  has_many :comments
end

require 'forwardable'
class Comment &lt; ActiveRecord::Base
  extend Forwardable
  belongs_to :post
  def_delegator :post, :name, :post_name
  def_delegator :post, :title, :post_title
  def_delegator :post, :something_else, :post_something_else
end

#view - erb|haml
@comment.post_title
@comment.post_name
@comment.post_something_else
</pre>
<p>O módulo <a href="http://www.ruby-doc.org/stdlib/libdoc/forwardable/rdoc/index.html">Forwardable</a> já vem com o Ruby. Portanto, a solução mais obvia foi usar esse módulo para melhorar o exemplo anterior. Apesar de escrever menos código, essa alternativa tem o inconveniente de não verificar se o objeto <strong>post</strong> é <strong>nil</strong>, causando assim <strong>NoMethodError</strong> em alguns casos. Sendo assim, a alternativa anterior ainda parece ser mais adequada. Porém, a duplicação de código ainda me incomodava bastante, portanto, resolvi montar uma solução única que deu origem a <a href="http://github.com/emerleite/demeter"><strong>gem demeter</strong></a>.</p>
<p>A solução definitiva:</p>
<pre class="brush: ruby; title: ;">
#no shell
&gt; sudo gem update --system
&gt; sudo gem sources -a http://gemcutter.org
&gt; sudo gem install demeter

#models
class Post &lt; ActiveRecord::Base
  has_many :comments
end

class Comment &lt; ActiveRecord::Base
  extend Demeter     #extends demeter module
  demeter :post      #demeter post object
  belongs_to :post
end

#view
@comment.post_title
@comment.post_name
@comment.post_something_else
</pre>
<p>Basicamente o problema foi resolvido com 2 linhas de código:</p>
<pre class="brush: ruby; title: ;">
  extend Demeter
  demeter :post
</pre>
<p>A vantagens são visíveis porque (1) você escreve bem menos, (2) já existe a verificação de objetos nulos e (3) caso você queira sobrescrever o comportamento padrão, basta criar um método que responda a mesma mensagem que a <a href="http://github.com/emerleite/demeter"><strong>gem demeter</strong></a> responde. Dessa forma, o método criado pelo programador semrpe terá prioridade.</p>
<p>O código fonte do projeto está em <a href="http://github.com/emerleite/demeter">http://github.com/emerleite/demeter</a> com todas as instruções para utilização tanto em Ruby quanto em Ruby on Rails. O código fonte tem todos os testes automatizados que cobrem diversos cenários. O resultado desses testes podem ser vistos em <a href="http://runcoderun.com/emerleite/demeter">http://runcoderun.com/emerleite/demeter</a>. A página da gem fica em <a href="http://gemcutter.org/gems/demeter">http://gemcutter.org/gems/demeter</a></p>
<p>Aguardo o feedback de vocês <img src='http://codificando.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
<p><font color="#B4B4B4" size="-2">Post Footer automatically generated by <a href="http://www.freetimefoto.com/add_post_footer_plugin_wordpress" style="color: #B4B4B4; text-decoration:underline;">Add Post Footer Plugin</a> for wordpress.</font></p>
]]></content:encoded>
			<wfw:commentRss>http://codificando.com/2009/11/law-of-demeter-simples-em-ruby-com-a-gem-demeter/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>

