<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Fernando Luizão</title>
	<atom:link href="http://fernandoluizao.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://fernandoluizao.wordpress.com</link>
	<description>Desenvolvimento de software e nerdices em geral</description>
	<lastBuildDate>Sat, 30 Jul 2011 12:08:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='fernandoluizao.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Fernando Luizão</title>
		<link>http://fernandoluizao.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://fernandoluizao.wordpress.com/osd.xml" title="Fernando Luizão" />
	<atom:link rel='hub' href='http://fernandoluizao.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Organizando seus projetos Ruby com RVM</title>
		<link>http://fernandoluizao.wordpress.com/2010/08/26/organizando-seus-projetos-ruby-com-rvm/</link>
		<comments>http://fernandoluizao.wordpress.com/2010/08/26/organizando-seus-projetos-ruby-com-rvm/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 00:34:00 +0000</pubDate>
		<dc:creator>fernandoluizao</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Shell Script]]></category>
		<category><![CDATA[ambiente]]></category>
		<category><![CDATA[rvm]]></category>
		<category><![CDATA[setup]]></category>

		<guid isPermaLink="false">http://fernandoluizao.wordpress.com/?p=233</guid>
		<description><![CDATA[O RVM (Ruby Version Manager) é uma ótima ferramenta para gerenciar versões de ruby diferentes, mantendo todas as versões instaladas dentro do seu home, sem necessidade de uma conta de superusuário. Além de permitir instalar e usar várias versões, ele tem outros recursos interessantes que podem ser usados para manter organização entre projetos com gems [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=233&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>O RVM (Ruby Version Manager) é uma ótima ferramenta para gerenciar versões de ruby diferentes, mantendo todas as versões instaladas dentro do seu home, sem necessidade de uma conta de superusuário. Além de permitir instalar e usar várias versões, ele tem outros recursos interessantes que podem ser usados para manter organização entre projetos com gems diferentes. Vou explicar como eu costumo trabalhar, meu workflow básico e também algumas dicas de uso do RVM. Se você nunca ouviu falar nele, recomendo uma visita ao <a href="http://rvm.beginrescueend.com/">site do projeto</a>.</p>
<h2>Instalando</h2>
<p>Para instalar o RVM é necessário o <strong>curl</strong>, <strong>git</strong> e <strong>bash</strong> (nunca testei em outros shell&#8217;s), e você também<br />
vai precisar de ferramentas de desenvolvimento para compilar os rubis (gcc, make, etc). Depois de instalar as dependências, instale o RVM com o comando:</p>
<pre class="brush: plain;">
bash &lt; &lt;( curl http://rvm.beginrescueend.com/releases/rvm-install-head )
</pre>
<p>Depois de instalado, edite (ou crie) seu <strong>~/.bashrc</strong> e adicione o seguinte ao fim dele:</p>
<pre class="brush: plain;">
if [[ -s ~/.rvm/scripts/rvm ]]
then
    source ~/.rvm/scripts/rvm
    source ~/.rvm/scripts/completion
    rvm reload
fi
</pre>
<p>Com isso o RVM será carregado e também será possível completar comandos do RVM usando o TAB. Agora regarregue seu bashrc:</p>
<pre class="brush: plain;">
source ~/.bashrc
</pre>
<p>Pronto, já podemos instalar nossos rubies, porém, antes de instalar qualquer coisa quero explicar o conceito de gemset do RVM. Gemsets permitem manter conjuntos de gems separados, dentro de uma mesma versão de Ruby. Quando você está usando um gemset, tem acesso apenas às gems instaladas nele, em um ambiente isolado. (isso é muito bom para evitar conflitos de versões de gems entre projetos diferentes). Sempre que uma versão do Ruby é instalada o RVM cria automaticamente dois gemsets, <strong>default</strong> e <strong>global</strong>. O gemset default é usado sempre que não for especificado qual gemset deseja-se utilizar. O gemset global é compartilhado entre todos os gemsets, ou seja, todas as gems instaladas no gemset global são visíveis nos outros gemsets da versão. Ao instalar uma versão de Ruby, o RVM verifica nos arquivos <em>~/.rvm/gemsets/global.gems</em> e <em>~/.rvm/gemsets/default.gems</em> quais gems devem ser instaladas nos respectivos gemsets, junto com o interpretador. Eu altero o arquivo <em>~/.rvm/gemsets/global.gems</em> e adiciono as seguintes gems:</p>
<pre class="brush: plain;">

rake
bundler
pg
sqlite3-ruby
mysql
rspec
</pre>
<p>Assim, sempre que eu instalar um novo Ruby essas gems também serão instaladas automaticamente no gemset global, me poupando algum tempo <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Se você não quiser fazer isso não precisa, é só um truque que eu uso para agilizar um pouco <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p>Agora podemos instalar nossos rubis. Para ver uma lista dos rubies que podem ser instalados, digite:</p>
<pre class="brush: plain;">
rvm list known
</pre>
<p>Instalar uma versão do Ruby é simples:</p>
<pre class="brush: plain;">
rvm install versao # ou versões separadas por vírgula
</pre>
<p>Eu instalo os seguintes:</p>
<pre class="brush: plain;">
rvm install 1.8.6,1.8.7,1.9.1,1.9.2,ree
</pre>
<p>O RVM vai baixar e compilar as versões selecionadas. Para usar alguma versão:</p>
<pre class="brush: plain;">
rvm use 1.9.1
# ou
rvm 1.9.1
</pre>
<p>Conferindo a versão do ruby:</p>
<pre class="brush: plain;">
ruby -v
</pre>
<p>Recomendo que vc escolha alguma versão como a default, eu deixo a 1.8.7 como default:</p>
<pre class="brush: plain;">
rvm 1.8.7 --default
</pre>
<p>Sempre que você abrir um novo shell a versão default já será usada. Se vc estiver usando outra versão e<br />
quiser mudar para a versão default é só usar</p>
<pre class="brush: plain;">
rvm use default
</pre>
<p>Para ver qual é o ruby default:</p>
<pre class="brush: plain;">
rvm list default
</pre>
<p>Para listar todas versões instaladas:</p>
<pre class="brush: plain;">
rvm list
</pre>
<p>Para ver informações sobre uma versão (paths, variáveis de ambiente):</p>
<pre class="brush: plain;">
rvm info versao
</pre>
<p>Para remover totalmente uma versão:</p>
<pre class="brush: plain;">
rvm remove versao --gems --archive
</pre>
<h2>Trabalhando com gemsets</h2>
<p>Como dito anteriormente, gemsets permitem isolar gems dentro de uma mesma versão. Para criar um gemset:</p>
<pre class="brush: plain;">
rvm gemset create nome_gemset
</pre>
<p>Usando um gemset:</p>
<pre class="brush: plain;">
rvm gemset nome_gemset
# ou
rvm gemset versao@nome_gemset
</pre>
<p>Para criar um gemset e já usá-lo:</p>
<pre class="brush: plain;">
rvm --create use versao@nome_gemset
</pre>
<p>Todas as gems que você instalar quando estiver usando o gemset ficarão confinadas a ele.<br />
Na listagem de gems aparecerão apenas as gems do gemset <strong>e as do gemset global</strong>.<br />
Se vc quiser instalar uma nova gem ao gemset global, use:</p>
<pre class="brush: plain;">
rvm gemset use global
gem install nome_da_gem
</pre>
<p>Para ver qual gemset está sendo usado:</p>
<pre class="brush: plain;">
rvm gemset name
</pre>
<p>Listando todos os gemsets disponíveis para a versão:</p>
<pre class="brush: plain;">
rvm gemset list
</pre>
<p>Apagando um gemset e as gems contidas nele (<strong>&#8211;force</strong> serve para não pedir confirmação):</p>
<pre class="brush: plain;">
rvm --force gemset delete nome_gemset
</pre>
<h2>Como manter gems separadas por projeto</h2>
<p>Sempre que vc muda para um diretório (<em>cd diretorio</em>), o RVM verifica se existe um <strong>.rvmrc</strong> dentro dele.<br />
Esse arquivo é um shell script que pode conter qualquer código necessário para inicializar o ambiente do projeto. Por exemplo, se vc quiser que um gemset <strong>xuxu</strong> seja carregado com a versão <strong>default</strong> sempre que você entrar no diretório do projeto, bastaria criar um <strong>.rvmrc</strong> com o conteúdo:</p>
<pre class="brush: plain;">
rvm default@xuxu
</pre>
<p>Com isso em mente, padronizei o setup dos meus projetos para:</p>
<pre class="brush: plain;">
mkdir nome_projeto
cd nome_projeto
rvm --create --rvmrc use default@nome_projeto
</pre>
<p>O último comando vai criar um gemset para o projeto, e também o <strong>.rvmrc</strong> para carregar o gemset correto.<br />
Como eu também estou usando o <a href="http://github.com/carlhuda/bundler">bundler</a>, eu crio um Gemfile, listando as dependências do projeto, (mesmo em projetos antigos, com Rails 1.2.6). Depois é só instalá-las com:</p>
<pre class="brush: plain;">
bundle install
</pre>
<p>Assim, tenho um ambiente de gems isolado para cada projeto, e o melhor, toda vez que eu mudar para o diretório de um projeto, o RVM já vai carregar o gemset correto com base no .rvmrc!</p>
<h2>Rodando seus testes com RVM</h2>
<p>Uma das coisas mais úteis do RVM é facilitar a execução testes em várias versões de Ruby diferentes. Por exemplo, para rodar sua suíte de testes em todas as versões de ruby instaladas:</p>
<pre class="brush: plain;">
# no caso de Rspec
rvm specs
# caso use Test::Unit
rvm tests
</pre>
<p>Também dá pra limitar a apenas algumas versões</p>
<pre class="brush: plain;">
rvm 1.8.6,1.8.7,1.9.1 specs
</pre>
<p>Se for necessário carregar um gemset específico para o projeto, pode ser feito da seguinte maneira</p>
<pre class="brush: plain;">
rvm 1.8.7@nome_gemset,1.9.1@nome_gemset specs
</pre>
<h2>Finalizando</h2>
<p>O RVM mudou muito meu jeito de trabalhar, essa é a forma que <strong>eu</strong> atualmente uso para manter meus projetos. Não quer dizer que é a melhor maneira, ou que você deve fazer da mesma forma. Esse post serve mais para dar uma idéia das possibilidades de uso do RVM, e servir como uma referência pra mim mesmo, pra consolidar meu workflow <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Se alguém quiser compartilhar outras dicas para organização de projetos sinta-se livre!</p>
<p>Referências:</p>
<p><a href="http://rvm.beginrescueend.com/">http://rvm.beginrescueend.com/</a><br />
<a href="http://bcardarella.com/post/699582642/rvm-gemsets-bundler-awesome">http://bcardarella.com/post/699582642/rvm-gemsets-bundler-awesome</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoluizao.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoluizao.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoluizao.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoluizao.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/fernandoluizao.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/fernandoluizao.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/fernandoluizao.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/fernandoluizao.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoluizao.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoluizao.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoluizao.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoluizao.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoluizao.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoluizao.wordpress.com/233/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=233&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fernandoluizao.wordpress.com/2010/08/26/organizando-seus-projetos-ruby-com-rvm/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c8838aa29a4289dd42a2b92fe5490d7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fernandoluizao</media:title>
		</media:content>
	</item>
		<item>
		<title>Tornando dependências opcionais com autoload</title>
		<link>http://fernandoluizao.wordpress.com/2010/05/11/tornando-dependencias-opcionais-com-autoload/</link>
		<comments>http://fernandoluizao.wordpress.com/2010/05/11/tornando-dependencias-opcionais-com-autoload/#comments</comments>
		<pubDate>Tue, 11 May 2010 22:11:10 +0000</pubDate>
		<dc:creator>fernandoluizao</dc:creator>
				<category><![CDATA[Gems]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[autoload]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[modularidade]]></category>
		<category><![CDATA[require]]></category>

		<guid isPermaLink="false">http://fernandoluizao.wordpress.com/?p=216</guid>
		<description><![CDATA[Uma técnica bacana e que pouca gente conhece é usar o autoload para carregar classes. A função do autoload é a mesma do require (por baixo dos panos, o autoload usa o require), a diferença é que o autoload carregará o arquivo apenas quando for necessário. A idéia é que as constantes sejam registradas e [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=216&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Uma técnica bacana e que pouca gente conhece é usar o <strong>autoload</strong> para carregar classes. A função do autoload é a mesma do <strong>require</strong> (por baixo dos panos, o autoload usa o require), a diferença é que o autoload carregará o arquivo apenas quando for necessário. A idéia é que as constantes sejam registradas e associandas ao arquivo que deve ser requerido, por exemplo:</p>
<pre class="brush: ruby;">
autoload :MinhaLib, 'minha_lib'
</pre>
<p>Note que o primeiro argumento é um símbolo, e não a classe. Com módulos é a mesma coisa:</p>
<pre class="brush: ruby;">
module MeuModulo
  autoload :MinhaLib, 'meu_modulo/minha_lib'
end
</pre>
<p>Ou ainda:</p>
<pre class="brush: ruby;">
module MeuModulo
  # coisas do meu modulo
end
MeuModulo.autoload :MinhaLib, 'meu_modulo/minha_lib'
</pre>
<p>Dessa forma, quando a constante <strong>MinhaLib</strong> (ou <strong>MeuModulo::MinhaLib</strong>, no caso do módulo) for usada, o arquivo &#8216;<em>minha_lib</em>&#8216; será carregado automaticamente. Qual a utilidade disso? Bem, se a constante não for usada, o arquivo não será carregado, o que nos trás duas vantagens:</p>
<ul>
<li>Como as classes desnecessárias não serão carregadas, a biblioteca será carregada mais rapidamente</li>
<li>Conseguimos um mecanismo para tornar dependências opcionais</li>
</ul>
<p>A primeira vantagem é óbvia, mas a segunda é meio implícita e depende de como o projeto está estruturado.<br />
Por exemplo digamos que temos uma gem, que dependa da gem <a href="http://github.com/mikel/mail">mail</a>, mas apenas se o usuário desejar notificações. Se declararmos a <strong>mail</strong> como dependência na gemspec, quando alguém for instalar nossa gem, a <strong>mail</strong> será instalada mesmo que o usuário não precise dela.</p>
<p>O que podemos fazer para relaxar as dependências é usar o autoload para registrar a constante <strong>Mail</strong>,<br />
e deixar a cargo do usuário instalar a dependência caso ele precise. Um exemplo de como seria o esqueleto da nossa gem:</p>
<pre class="brush: ruby;">
# minha_gem.rb
autoload :Mail, 'mail'

# faz o que precisa ser feito

# a gem será carregada apenas se o usuário desejar notificações
# as notificações poderiam ser configuradas por um arquivo *.yml por exemplo
if user_wants_notification?
  Mail.new ...
end
</pre>
<p>Um exmplo de uso dessa técnica pode ser visto na gem <a href="http://github.com/meskyanichi/backup">backup</a>, que antes especificava várias dependências na gemspec, e após uma pequena reestruturação, deixaram de ser obrigatórias. Veja <a href="http://github.com/fernandoluizao/backup/commit/3d1c1077e469d17675994be30de86e01c8c8a8d8">aqui</a> como foi feito. Outro exemplo de gem que usa essa técnica é a <a href="http://github.com/plataformatec/devise/">devise</a>, vale a pena dar uma olhada no código <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Se você desenvolve alguma gem que usa <a href="http://en.wikipedia.org/wiki/Adapter_pattern">adaptadores</a>, e esses adaptadores dependem de outras gems, você encontrou um bom uso para o autoload, e vai deixar seus usuários mais felizes por não precisarem instalar o que não usarem <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Referências:</p>
<p><a href="http://www.rubyinside.com/ruby-techniques-revealed-autoload-1652.html">http://www.rubyinside.com/ruby-techniques-revealed-autoload-1652.html</a><br />
<a href="http://ruby-doc.org/core/classes/Module.html">http://ruby-doc.org/core/classes/Module.html</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoluizao.wordpress.com/216/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoluizao.wordpress.com/216/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoluizao.wordpress.com/216/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoluizao.wordpress.com/216/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/fernandoluizao.wordpress.com/216/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/fernandoluizao.wordpress.com/216/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/fernandoluizao.wordpress.com/216/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/fernandoluizao.wordpress.com/216/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoluizao.wordpress.com/216/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoluizao.wordpress.com/216/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoluizao.wordpress.com/216/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoluizao.wordpress.com/216/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoluizao.wordpress.com/216/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoluizao.wordpress.com/216/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=216&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fernandoluizao.wordpress.com/2010/05/11/tornando-dependencias-opcionais-com-autoload/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c8838aa29a4289dd42a2b92fe5490d7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fernandoluizao</media:title>
		</media:content>
	</item>
		<item>
		<title>Migrando o Brazilian Rails para Ruby 1.9</title>
		<link>http://fernandoluizao.wordpress.com/2009/09/12/migrando-o-brazilian-rails-para-ruby-1-9/</link>
		<comments>http://fernandoluizao.wordpress.com/2009/09/12/migrando-o-brazilian-rails-para-ruby-1-9/#comments</comments>
		<pubDate>Sat, 12 Sep 2009 13:13:07 +0000</pubDate>
		<dc:creator>fernandoluizao</dc:creator>
				<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[brazilian rails]]></category>
		<category><![CDATA[migração]]></category>
		<category><![CDATA[ruby 1.9]]></category>

		<guid isPermaLink="false">http://fernandoluizao.wordpress.com/?p=197</guid>
		<description><![CDATA[Relato passo a passo das alteraçoẽs para migrar o Brazilian Rails: Adicionados comentários de encoding. commit commit : (dois pontos) não são mais válidos como separador de instruções. Deve-se trocar por ; ou then, ambas funcionam no 1.8 e 1.9. commit ParseDate foi removido, Date#parse faz grande parte do que fazia o ParseDate. commit O [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=197&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Relato passo a passo das alteraçoẽs para migrar o Brazilian Rails:</p>
<p>Adicionados <a href="http://fernandoluizao.wordpress.com/2009/08/28/dica-adicionando-comentarios-de-codificacao-num-projeto-rails/">comentários de encoding</a>. <a href="http://github.com/tapajos/brazilian-rails/commit/9eaa0a09cf21b283330e9771497c2d1025a12eab">commit</a> <a href="http://github.com/tapajos/brazilian-rails/commit/e19e4eb7600c47864fe00339d65e86972fbc46dc">commit</a></p>
<p><strong>:</strong> (dois pontos) não são mais válidos como separador de instruções. Deve-se trocar por <strong>;</strong> ou <strong>then</strong>, ambas funcionam no 1.8 e 1.9. <a href="http://github.com/tapajos/brazilian-rails/commit/9eaa0a09cf21b283330e9771497c2d1025a12eab#diff-5">commit</a></p>
<p>ParseDate foi removido, <strong>Date#parse</strong> faz grande parte do que fazia o ParseDate. <a href="http://github.com/tapajos/brazilian-rails/commit/1ebb82ac2efad832a8b0362f0af0075b55c7856e">commit</a></p>
<p>O 1.9 introduziu o método <strong>Numeric#real</strong>, e estava sobrescrevendo um alias. <a href="http://github.com/tapajos/brazilian-rails/commit/2687f3825cb2df7645fae64b0745fc4d2acc9da3">commit</a></p>
<p>Variável <strong>$KCODE</strong> não tem mais efeito no 1.9, será setada apenas se a versão for anterior a 1.9. <a href="http://github.com/tapajos/brazilian-rails/commit/056411858a0b2d617a6c4eb5d851f3d888e5ec29">commit</a></p>
<p>A parte mais chata foi relacionada ao parser datas. O Date#parse no 1.9 se comporta de maneira diferente do 1.8, foram introduzidos outros formatos para parseamento, e o parse tenta converter a data com os novos formatos. Exemplo do novo comportamento:</p>
<pre class="brush: ruby;">
# ruby 1.8.7
Date.parse(&quot;13/12/200A&quot;)
ArgumentError: invalid date
    from /usr/lib/ruby/1.8/date.rb:956:in `new_by_frags'
    from /usr/lib/ruby/1.8/date.rb:1000:in `parse'
    from (irb):7
    from /usr/lib/ruby/1.8/date.rb:811

# ruby 1.9.1
Date.parse(&quot;13/12/200A&quot;)
=&gt; #&lt;date: 0200-12-13&gt;
</pre>
<p>Outra mudança foi que o formato padrão do parse passou a ser dd/mm/yyyy em vez de mm/dd/yyyy:</p>
<pre class="brush: ruby;">
# ruby 1.8.7
Date.parse(&quot;10/12/2009&quot;)
=&gt; Seg, 12 Out 2009

# ruby 1.9.1
Date.parse(&quot;10/12/2009&quot;)
=&gt; Qui, 10 Dez 2009
</pre>
<p>Levando em conta essas mudanças, alterei o formado de algumas datas <a href="http://github.com/tapajos/brazilian-rails/commit/13d7368d2ab3ce8a16054ec7f45389a143b41c81">nesse</a> teste. <a href="http://github.com/tapajos/brazilian-rails/commit/50da3ac4a55867fa663aad771b2b78ba7523dc1f">Esse</a> outro teste, não está sendo executado no 1.9, justamente pelas diferenças do parse. </p>
<p>Sim, sei que essa solução está longe da ideal, mas para manter o mesmo comportamento seria necessário sobrescrever o parser do 1.9, e não gosto dessa solução&#8230; Para quem usa apenas datas no formato brasileiro, não vejo problemas, o <strong>Date#valid?</strong> continua funcionando (afinal, o propósito da brdata é trabalhar com datas no formato brasileiro <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ). O problema é se forem usadas datas em outros formatos, pois aí quem se encarrega de fazer a conversão é o parser do Ruby. Então, se você escolheu usar uby 1.9, esteja ciente das mudanças na classe <strong>Date</strong>.</p>
<p>Talvez no futuro seja interessante repensar a forma como o método <strong>Date#valid?</strong> é implementado, mas por hora, creio que deixar a cargo do usuário é razoável, já que é dele a decisão e sobre qual versão do Ruby usar. O suporte da brdata no 1.9 ainda é experimental, então se algém tiver idéias melhores, se pronuncie =).</p>
<p>Finalizando, destaco o papel dos testes na migração. Por sorte o Brazilian Rails tem uma boa cobertura, o que facilitou bastante. A cada alteração feita eu rodava os testes no 1.9 e no 1.8 para ver se estava tudo certo <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . </p>
<p><strong>PS:</strong> para mudar a versão do Ruby eu uso o <a href="http://blog.thinkrelevance.com/2009/7/29/ruby-switcher-working-with-multiple-ruby-versions-has-never-been-this-easy">ruby_switcher</a>. Também tem o <a href="http://rvm.beginrescueend.com/">rvm</a>, mas acho o ruby_switcher mais simples.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoluizao.wordpress.com/197/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoluizao.wordpress.com/197/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoluizao.wordpress.com/197/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoluizao.wordpress.com/197/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/fernandoluizao.wordpress.com/197/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/fernandoluizao.wordpress.com/197/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/fernandoluizao.wordpress.com/197/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/fernandoluizao.wordpress.com/197/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoluizao.wordpress.com/197/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoluizao.wordpress.com/197/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoluizao.wordpress.com/197/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoluizao.wordpress.com/197/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoluizao.wordpress.com/197/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoluizao.wordpress.com/197/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=197&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fernandoluizao.wordpress.com/2009/09/12/migrando-o-brazilian-rails-para-ruby-1-9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c8838aa29a4289dd42a2b92fe5490d7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fernandoluizao</media:title>
		</media:content>
	</item>
		<item>
		<title>Dica: adicionando comentários de codificação num projeto Rails</title>
		<link>http://fernandoluizao.wordpress.com/2009/08/28/dica-adicionando-comentarios-de-codificacao-num-projeto-rails/</link>
		<comments>http://fernandoluizao.wordpress.com/2009/08/28/dica-adicionando-comentarios-de-codificacao-num-projeto-rails/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 23:55:49 +0000</pubDate>
		<dc:creator>fernandoluizao</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[encoding]]></category>
		<category><![CDATA[ruby 1.9]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://fernandoluizao.wordpress.com/?p=187</guid>
		<description><![CDATA[O Ruby 1.9 agora leva em consideração o encoding das strings nos arquivos, então caso algum arquivo ruby tenha algum caracter não ASCII (caracteres acentuados por exemplo), será exibido o erro: Para que o erro não ocorra, basta adicionar o comentário abaixo na primeira linha do arquivo *.rb: Ao migrar um projeto Rails para Ruby [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=187&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>O Ruby 1.9 agora leva em consideração o encoding das strings nos arquivos, então caso algum arquivo ruby tenha algum caracter não ASCII (caracteres acentuados por exemplo), será exibido o erro:</p>
<pre class="brush: ruby;">
invalid multibyte char (US-ASCII)
</pre>
<p>Para que o erro não ocorra, basta adicionar o comentário abaixo na primeira linha do arquivo *.rb:</p>
<pre class="brush: ruby;">
# encoding: UTF-8
</pre>
<p>Ao migrar um projeto Rails para Ruby 1.9, esse erro acontecia em vários arquivos, então nada melhor que deixar o computador resolver o problema por você <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . O comando abaixo vai colocar esse comentário em todos os controllers, helpers e models do seu projeto Rails:</p>
<pre class="brush: ruby;">
cd seu_projeto
find app/{controllers,models,helpers} -type f -name \*.rb | xargs sed -i '1i # encoding: UTF-8'
</pre>
<p>Para quem usa windows, pode usar o seguinte script Ruby para fazer o mesmo:</p>
<pre class="brush: ruby;">
# utf_comment.rb
Dir[&quot;app/{controllers,models,helpers}/**/*.rb&quot;].each do |filename|
  content = File.read(filename).sub(/^/, &quot;# encoding: UTF-8\n&quot;)
  File.open(filename, &quot;r+&quot;) { |f| f.write(content) }
end
</pre>
<p>Execute com</p>
<pre class="brush: ruby;">
cd seu_projeto
ruby utf_comment.rb
</pre>
<p>Para mais informações sobre codificação de strings, <a href="http://blog.grayproductions.net/articles/understanding_m17n">aqui</a> tem vários artigos abordando as mudanças. Recomendo a leitura!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoluizao.wordpress.com/187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoluizao.wordpress.com/187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoluizao.wordpress.com/187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoluizao.wordpress.com/187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/fernandoluizao.wordpress.com/187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/fernandoluizao.wordpress.com/187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/fernandoluizao.wordpress.com/187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/fernandoluizao.wordpress.com/187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoluizao.wordpress.com/187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoluizao.wordpress.com/187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoluizao.wordpress.com/187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoluizao.wordpress.com/187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoluizao.wordpress.com/187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoluizao.wordpress.com/187/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=187&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fernandoluizao.wordpress.com/2009/08/28/dica-adicionando-comentarios-de-codificacao-num-projeto-rails/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c8838aa29a4289dd42a2b92fe5490d7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fernandoluizao</media:title>
		</media:content>
	</item>
		<item>
		<title>Rails: Otimizando STI com default_scope</title>
		<link>http://fernandoluizao.wordpress.com/2009/08/12/rails-otimizando-sti-com-default_scope/</link>
		<comments>http://fernandoluizao.wordpress.com/2009/08/12/rails-otimizando-sti-com-default_scope/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 01:28:24 +0000</pubDate>
		<dc:creator>fernandoluizao</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[default_scope]]></category>
		<category><![CDATA[single table inheritance]]></category>
		<category><![CDATA[STI]]></category>

		<guid isPermaLink="false">http://fernandoluizao.wordpress.com/?p=143</guid>
		<description><![CDATA[NOTA: se vc não faz idéia do que é STI, veja esse link. Não dá pra negar que STI (Single Table Inheritance) é um recurso bacana do Rails. Claro que não é bom abusar, mas em alguns casos, ela se encaixa muito bem. No rails, quando queremos usar STI, basta ter uma coluna type do [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=143&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>NOTA: se vc não faz idéia do que é STI, veja <a href="http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html">esse link</a>.</p>
<p>Não dá pra negar que STI (Single Table Inheritance) é um recurso bacana do Rails. Claro que não é bom abusar, mas em alguns casos, ela se encaixa muito bem. No rails, quando queremos usar STI, basta ter uma coluna <strong>type</strong> do tipo <em>string</em> na tabela &#8220;mãe&#8221;, e nessa coluna o Rails se encarrega de gravar o nome da classe do registro, e a partir daí tudo funciona normalmente (para mais detalhes sobre como funciona STI no Rails, veja a <a href="http://api.rubyonrails.org/classes/ActiveRecord/Base.html">api</a>). Porém, apesar da implementação do Rails ser muito elegante e funcionar bem, ela tem alguns problemas:</p>
<ul>
<li>Comparações entre strings são lentas. Mesmo que haja um índice na coluna &#8220;type&#8221;, comparações entre strings ainda são bem mais lentas que comparações entre inteiros.</li>
<li>Caso o model seja renomeado, os dados da coluna &#8220;type&#8221; terão que ser atualizados, ou ficaremos com dados incorretos na tabela. Para corrigir podemos criar uma migration, mas é mais uma coisa para se preocupar <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </li>
</ul>
<p>Vamos tentar melhorar isso!</p>
<p>Criando um projetinho de exemplo (<strong>NOTA:</strong> estou usando <strong>Rails 2.3.3</strong>. Se usa uma versão mais antiga, veja algumas considerações mais abaixo):</p>
<pre class="brush: ruby;">
rails sti
cd sti
script/generate model pessoa nome:string documento:string tipo:integer
</pre>
<p>Estamos criando nossa tabela base, e em vez de usar uma coluna <strong>type</strong> do tipo <em>string</em>, vamos usar uma coluna chamada <strong>tipo</strong> (o nome da coluna poderia ser qualquer um), do tipo <em>inteiro</em>.</p>
<p>Vamos editar nossa migração e adicionar um índice na migration para melhorar a performance nas buscas:</p>
<pre class="brush: ruby;">
class CreatePessoas &lt; ActiveRecord::Migration
  def self.up
    create_table :pessoas do |t|
      t.string :nome
      t.string :documento
      t.integer :tipo
      t.timestamps
    end

    #adicionando o indice
    add_index :pessoas, [:id, :tipo]
  end

  def self.down
    drop_table :pessoas
  end
end
</pre>
<p>Criando o banco e nossa tabela de testes:</p>
<pre class="brush: ruby;">
rake db:create
rake db:migrate
</pre>
<p>Alterando o model <strong>Pessoa</strong> para adicionar algumas constantes com os tipos de pessoas:</p>
<pre class="brush: ruby;">
#app/models/pessoa.rb
class Pessoa &lt; ActiveRecord::Base
  # tipos de pessoa
  JURIDICA = 1
  FISICA   = 2
end
</pre>
<p>Agora, vamos criar dois models que herdam de <strong>Pessoa</strong>, <strong>PessoaFisica</strong> e <strong>PessoaJuridica</strong>, e definir os seus <em>default_scope</em>s:</p>
<pre class="brush: ruby;">
#app/models/pessoa_fisica.rb
class PessoaFisica &lt; Pessoa
  default_scope :conditions =&gt; {:tipo =&gt; FISICA}
end
</pre>
<pre class="brush: ruby;">
#app/models/pessoa_juridica.rb
class PessoaJuridica &lt; Pessoa
  default_scope :conditions =&gt; {:tipo =&gt; JURIDICA}
end
</pre>
<p>Só isso? Só <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Aparentemente, o Rails está bem espertinho, e quando instânciamos um objeto ele já se encarrega de colocar o valor correto na coluna <strong>tipo</strong>, da mesma forma que STI faz:</p>
<pre class="brush: ruby;">
Pessoa.new
#&lt;Pessoa id: nil, nome: nil, documento: nil, tipo: nil&gt;
PessoaJuridica.new
#&lt;PessoaJuridica id: nil, nome: nil, documento: nil, tipo: 1&gt;
PessoaFisica.new
#&lt;PessoaFisica id: nil, nome: nil, documento: nil, tipo: 2&gt;
</pre>
<p>Criando algumas pessoas:</p>
<pre class="brush: ruby;">
Pessoa.create(:nome =&gt; &quot;Pessoa indefinida&quot;)
PessoaFisica.create(:nome =&gt; &quot;João da Silva&quot;, :documento =&gt; &quot;123.456.789-10&quot;)
PessoaFisica.create(:nome =&gt; &quot;José Oliveira&quot;, :documento =&gt; &quot;000.111.222-33&quot;)
PessoaJuridica.create(:nome =&gt; &quot;Padaria pão quentinho&quot;, :documento =&gt; &quot;26.721.163/0001-52&quot;)
PessoaJuridica.create(:nome =&gt; &quot;Transportadora Leva e Traz&quot;, :documento =&gt; &quot;70.562.197/0001-31&quot;)
</pre>
<p>Buscando:</p>
<pre class="brush: ruby;">
&gt;&gt; Pessoa.all
# SELECT * FROM &quot;pessoas&quot;
=&gt; [#&lt;Pessoa id: 1, nome: &quot;Pessoa indefinida&quot;, documento: nil, tipo: nil, created_at: &quot;2009-08-12 01:08:29&quot;, updated_at: &quot;2009-08-12 01:08:29&quot;&gt;, #&lt;Pessoa id: 2, nome: &quot;João da Silva&quot;, documento: &quot;123.456.789-10&quot;, tipo: 2, created_at: &quot;2009-08-12 01:08:29&quot;, updated_at: &quot;2009-08-12 01:08:29&quot;&gt;, #&lt;Pessoa id: 3, nome: &quot;José Oliveira&quot;, documento: &quot;000.111.222-33&quot;, tipo: 2, created_at: &quot;2009-08-12 01:08:29&quot;, updated_at: &quot;2009-08-12 01:08:29&quot;&gt;, #&lt;Pessoa id: 4, nome: &quot;Padaria pão quentinho&quot;, documento: &quot;26.721.163/0001-52&quot;, tipo: 1, created_at: &quot;2009-08-12 01:08:29&quot;, updated_at: &quot;2009-08-12 01:08:29&quot;&gt;, #&lt;Pessoa id: 5, nome: &quot;Transportadora Leva e Traz&quot;, documento: &quot;70.562.197/0001-31&quot;, tipo: 1, created_at: &quot;2009-08-12 01:08:29&quot;, updated_at: &quot;2009-08-12 01:08:29&quot;&gt;]

&gt;&gt; PessoaJuridica.all
# SELECT * FROM &quot;pessoas&quot; WHERE (&quot;pessoas&quot;.&quot;tipo&quot; = 1)
=&gt; [#&lt;PessoaJuridica id: 4, nome: &quot;Padaria pão quentinho&quot;, documento: &quot;26.721.163/0001-52&quot;, tipo: 1, created_at: &quot;2009-08-12 01:08:29&quot;, updated_at: &quot;2009-08-12 01:08:29&quot;&gt;, #&lt;PessoaJuridica id: 5, nome: &quot;Transportadora Leva e Traz&quot;, documento: &quot;70.562.197/0001-31&quot;, tipo: 1, created_at: &quot;2009-08-12 01:08:29&quot;, updated_at: &quot;2009-08-12 01:08:29&quot;&gt;]

&gt;&gt; PessoaFisica.all
# SELECT * FROM &quot;pessoas&quot; WHERE (&quot;pessoas&quot;.&quot;tipo&quot; = 2)
=&gt; [#&lt;PessoaFisica id: 2, nome: &quot;João da Silva&quot;, documento: &quot;123.456.789-10&quot;, tipo: 2, created_at: &quot;2009-08-12 01:08:29&quot;, updated_at: &quot;2009-08-12 01:08:29&quot;&gt;, #&lt;PessoaFisica id: 3, nome: &quot;José Oliveira&quot;, documento: &quot;000.111.222-33&quot;, tipo: 2, created_at: &quot;2009-08-12 01:08:29&quot;, updated_at: &quot;2009-08-12 01:08:29&quot;&gt;]
</pre>
<p>Para quem ainda usa uma versão do Rails menor que 2.3 e maior que 2.0, uma solução é instalar o plugin com o backport do default_scope:</p>
<pre class="brush: ruby;">
script/plugin install git://github.com/duncanbeevers/default_scope.git
</pre>
<p>Além disso, será necessário usar uma callback para setar a coluna <strong>tipo</strong> com o valor correto. Por exemplo:</p>
<pre class="brush: ruby;">
class PessoaFisica &lt; Pessoa
  default_scope :conditions =&gt; {:tipo =&gt; FISICA}
  before_save { |p| p.tipo = FISICA }
end
</pre>
<p>Para quem usa uma versão do mais antiga que a 2, já passou da hora de atualizar hem <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p><strong>Finalizando</strong></p>
<p>Conseguimos o mesmo comportamento da STI, sem as desvantagens citadas anteriormente, usando apenas algumas linhas de código a mais (os default_scopes e as constantes que definimos, no total 4 linhas). Espero que essa dica seja útil, e lembre-se, aprecie STI com moderação <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoluizao.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoluizao.wordpress.com/143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoluizao.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoluizao.wordpress.com/143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/fernandoluizao.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/fernandoluizao.wordpress.com/143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/fernandoluizao.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/fernandoluizao.wordpress.com/143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoluizao.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoluizao.wordpress.com/143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoluizao.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoluizao.wordpress.com/143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoluizao.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoluizao.wordpress.com/143/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=143&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fernandoluizao.wordpress.com/2009/08/12/rails-otimizando-sti-com-default_scope/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c8838aa29a4289dd42a2b92fe5490d7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fernandoluizao</media:title>
		</media:content>
	</item>
		<item>
		<title>Deslocalizando datas e números usando o i18n do Rails</title>
		<link>http://fernandoluizao.wordpress.com/2009/06/18/deslocalizando-datas-e-numeros-usando-o-i18n-do-rails/</link>
		<comments>http://fernandoluizao.wordpress.com/2009/06/18/deslocalizando-datas-e-numeros-usando-o-i18n-do-rails/#comments</comments>
		<pubDate>Thu, 18 Jun 2009 00:50:19 +0000</pubDate>
		<dc:creator>fernandoluizao</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[delocalize]]></category>
		<category><![CDATA[conversão]]></category>
		<category><![CDATA[datas]]></category>
		<category><![CDATA[números]]></category>

		<guid isPermaLink="false">http://fernandoluizao.wordpress.com/?p=122</guid>
		<description><![CDATA[NOTA: Antes de começar, se você não sabe o que é ou não tem uma noção básica sobre o i18n do Rails, leia esse guia. Fazer conversões de datas e números localizados sempre foi uma tarefa chata em Rails (e em outras linguagens/frameworks também). O usuário digita uma data no formato brasileiro (por exemplo, dd/mm/yyyy), [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=122&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>NOTA:</strong> Antes de começar, se você não sabe o que é ou não tem uma noção básica sobre o i18n do Rails, leia <a href="http://guias.rubyonrails.pro.br/i18n.html">esse guia</a>.</p>
<p>Fazer conversões de datas e números localizados sempre foi uma tarefa chata em Rails (e em outras linguagens/frameworks também). O usuário digita uma data no formato brasileiro (por exemplo, dd/mm/yyyy), e o Ruby não consegue converter a data corretamente. A maneira mais usada por aí é criar atributos virtuais (ou mesmo sobrecrever o setter padrão do atributo) no model para fazer a conversão, por exemplo:</p>
<pre class="brush: ruby;">
class Model &lt; ActiveRecord::Base

  #recebe uma data no formato dd/mm/yyyy e converte para yyyy-mm-dd
  def data_vencimento=value
    self[:data_vencimento] = value.split(&quot;/&quot;).reverse.join(&quot;-&quot;)
  end

end
</pre>
<p>Isso funciona, mas quando eu usava isso não ficava satisfeito, queria algo mais &#8220;mágico&#8221; <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Perguntei no <a href="http://forum.rubyonbr.org/forums/1/topics/4020">fórum RubyOnBr</a> se não teria um jeito de fazer a conversão automaticamente, usando o próprio i18n do Rails. Então meu camarada <a href="http://www.rafaelrosafu.com">Rafael Rosa</a> chegou a uma solução, usando o formato padrão de data configurado no aquivo de i18n para fazer o parsing de datas. Eu acrescentei suporte à números, o Rafael organizou tudo, escreveu testes, e surgiu o <a href="http://www.rafaelrosafu.com/2009/2/13/localizando-strings-com-i18n">i18n_localize_core</a>.<br />
O plugin funciona bem, consegue converter datas e números usando as configurações do arquivo de internacionalização. O plugin resolvia bem para mim, inclusive tinha feito alguns hacks no plugin para fazer a conversão nos text_fields, mas não coloquei no meu fork porque estava muito feio <img src='http://s0.wp.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> .<br />
Só que a um tempo atrás, encontrei o plugin <a href="http://github.com/clemens/delocalize">delocalize</a>, escrito por <a href="http://www.railway.at/">Clemens Kofler</a>, que faz basicamente a mesma coisa, mas melhor <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . O i18n_localize_core é meio invasivo, sobrescreve os métodos <strong>Date#_parse</strong>, <strong>String#to_i</strong> e <strong>String#to_f</strong>. No <em>delocalize</em>, o Clemens sobrescreveu apenas onde era necessário, e ainda adicionou suporte à entrada de vários formatos de datas.<br />
Usar o plugin é simples, como tudo na vida deve ser <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Tendo configurado seu arquivo de i18n e instalado o plugin, basta adicionar a chave <strong>:input</strong> no arquivo de i18n com os formatos de data que o usuário poderá digitar e sair pro abraço <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . O plugin se encarrega de fazer o resto de forma transparente.</p>
<p>No README do plugin tem alguns exemplos de uso, dêem uma conferida no projeto:</p>
<p><a href="http://github.com/clemens/delocalize">http://github.com/clemens/delocalize</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoluizao.wordpress.com/122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoluizao.wordpress.com/122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoluizao.wordpress.com/122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoluizao.wordpress.com/122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/fernandoluizao.wordpress.com/122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/fernandoluizao.wordpress.com/122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/fernandoluizao.wordpress.com/122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/fernandoluizao.wordpress.com/122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoluizao.wordpress.com/122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoluizao.wordpress.com/122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoluizao.wordpress.com/122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoluizao.wordpress.com/122/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoluizao.wordpress.com/122/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoluizao.wordpress.com/122/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=122&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fernandoluizao.wordpress.com/2009/06/18/deslocalizando-datas-e-numeros-usando-o-i18n-do-rails/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c8838aa29a4289dd42a2b92fe5490d7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fernandoluizao</media:title>
		</media:content>
	</item>
		<item>
		<title>Tradução: Delegação em Ruby</title>
		<link>http://fernandoluizao.wordpress.com/2009/03/31/traducao-delegacao-em-ruby/</link>
		<comments>http://fernandoluizao.wordpress.com/2009/03/31/traducao-delegacao-em-ruby/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 01:48:26 +0000</pubDate>
		<dc:creator>fernandoluizao</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[composição]]></category>
		<category><![CDATA[delegação de métodos]]></category>
		<category><![CDATA[delegate]]></category>
		<category><![CDATA[forwardable]]></category>
		<category><![CDATA[herança]]></category>

		<guid isPermaLink="false">http://fernandoluizao.wordpress.com/?p=89</guid>
		<description><![CDATA[Hoje li um artigo interessante na primeira edição da Rails Magazine sobre delegação de métodos em Ruby, escrito por Khaled al Habache. Além da delegação, ele também aborda um tema antigo (e que gera muita discussão por aí) em se tratando de POO, Herança X Composição. Como não achei material sobre delegação em português, resolvi [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=89&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Hoje li um artigo interessante na <a href="http://railsmagazine.com/issues/1">primeira edição</a> da <a href="http://railsmagazine.com/">Rails Magazine</a> sobre delegação de métodos em Ruby, escrito por Khaled al Habache.  Além da delegação, ele também aborda um tema antigo (e que gera muita discussão por aí) em se tratando de POO, Herança X Composição. Como não achei material sobre delegação em português, resolvi traduzir o artigo. Espero que gostem <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p><strong>Delegação em Ruby</strong></p>
<p>&#8220;Separar partes mutáveis das partes que não mudam&#8221; e &#8220;composição é preferível a herança&#8221; são dois princípios de projeto comuns quando você inicia no mundo da Programação Orientada à Objetos. Entretanto, enquanto o primeiro parece lógico, alguém pode pensar porque é preferível usar composição em vez de herança, e é uma questão lógica, então vamos respondê-la com um exemplo.</p>
<p>Vamos supor que temos um robô que possui um sensor de temperatura, representado pelo seguinte diagrama UML:</p>
<div id="attachment_94" class="wp-caption aligncenter" style="width: 269px"><img class="size-full wp-image-94" title="delegation-uml11" src="http://fernandoluizao.files.wordpress.com/2009/03/delegation-uml11.png?w=259&#038;h=144" alt="Robô" width="259" height="144" /><p class="wp-caption-text">Classe Robô</p></div>
<p>Esse projeto tem alguns inconvenientes:</p>
<p>1. Existe grande probabilidade de existir outros tipos de robôs que não possuem sensores de calor (quebra o primeiro princípio de  projeto: separar código mutável do estático)<br />
2. Sempre que eu desejar alterar qualquer coisa relacionada ao sensor de temperatura, terei que alterar a classe Robô (quebra o primeiro princípio de projeto).<br />
3. Exposição dos métodos do sensor de temperatura na classe Robô.</p>
<p>Vamos melhorar essa classe um pouco:</p>
<div id="attachment_95" class="wp-caption aligncenter" style="width: 272px"><img class="size-full wp-image-95" title="delegation-uml21" src="http://fernandoluizao.files.wordpress.com/2009/03/delegation-uml21.png?w=262&#038;h=281" alt="Classe Robô Vulcão" width="262" height="281" /><p class="wp-caption-text">Classe Robô Vulcão</p></div>
<p>Bem, agora esse é um projeto baseado em herança que resolve o primeiro problema, mas ainda é incapaz de resolver os outros dois problemas relacionados ao sensor de calor. Vamos melhorar um pouco mais:</p>
<div id="attachment_96" class="wp-caption aligncenter" style="width: 430px"><img class="size-full wp-image-96" title="delegation-uml31" src="http://fernandoluizao.files.wordpress.com/2009/03/delegation-uml31.png?w=420&#038;h=374" alt="Delegação" width="420" height="374" /><p class="wp-caption-text">Delegação</p></div>
<p>Esse é um típico modelo, baseado em composição em vez de herança. Com ele podemos resolver todos os 3 problemas, e ainda por cima ganhamos uma nova classe: agora podemos abstrair o SensorDeTemperatura para usos futuros.</p>
<p><strong>O que é delegação?</strong></p>
<p>Delegação é o processo de delegar funcionalidade às partes contidas.</p>
<p>Se você olhar cuidadosamente à figura anterior, você notará que o RoboVulcao ainda possui 3 métodos relacionados ao sensor; esses são métodos que apenas chamam os métodos correspondentes do sensor. Isso é exatamente o que delegação é, apenas repassar funcionalidade às partes contidas.</p>
<p>Delegação vem junto com composição para oferecer soluções flexíveis e elegantes como essa que vimos anteriormente, e também respeita o princípio &#8220;separar código mutável de código estático&#8221;, mas também cobra um preço por isso: a necessidade de métodos que &#8220;embrulhem&#8221; as chamadas impõem um tempo extra de processamento por causa das chamadas a esses métodos.</p>
<p><strong>Ruby e delegação</strong></p>
<p>Agora vamos ver um exemplo de código:</p>
<p>Temos um robô de propósito geral que possui um Braço e um SensorDeCalor. O robô é capaz de executar várias tarefas, como empacotar caixas, empilhá-las e medir a temperatura.</p>
<p>Usaremos composição e delegação assim:</p>
<pre class="brush: ruby;">
class Robô

  def initialize
    @sensor_temperatura = SensorDeTemperatura.new
    @braco = BracoDoRobo.new
  end

  def medir_temperatura(escala=&quot;c&quot;)
    @sensor_temperatura.measure(escala)
  end

  def empilhar(quantidade_de_caixas=1)
    @braco.empilhar(quantidade_de_caixas)
  end

  def empacotar
    @braco.empacotar
  end

end

class SensorDeTemperatura

  # Escala Celsius ou Fahrenheit
  def medir(escala=&quot;c&quot;)
    t = rand(100)
    t = escala==&quot;c&quot; ? t : t * (9/5)
    puts &quot;A temperatura é #{t}° #{escala.upcase}&quot;
  end

end

class BracoDoRobo

  def empilhar(quantidade_de_caixas=1)
    puts &quot;Empilhando #{quantidade_de_caixas} caixa(s)&quot;
  end

  def empacotar
    puts &quot;Empacotando&quot;
  end

end

robo = Robo.new #=&gt;#&lt;Robo:0xb75131e8 @arm=#&lt;BracoDoRobo:0xb75131ac&gt;, @sensor_temperatura=#&lt;SensorDeTemperatura:0xb75131c0&gt;&gt;
robo.empilhar 2 #=&gt;Empilhando 2 caixa(s)
robo.empacotar #=&gt;Empacotando
robo.medir_temperatura #=&gt; A temperatura é 59° C
</pre>
<p>Como pode ser visto, temos 3 métodos que &#8220;encapsulam&#8221; chamadas (empilhar, empacotar e medir_temperatura) na classe Robo que não fazem nada a não ser chamar o método correspondente dos componentes (BracoDoRobo e SensorDeTemperatura).</p>
<p>Isso é uma coisa péssima, especialmente quando existem vários objetos contidos no objeto principal.</p>
<p>Entretanto, em Ruby temos duas bibliotecas para nos salvar: <strong>Forwardable</strong> e <strong>Delegate</strong>, Vamos ver cada uma delas.</p>
<p><strong>Biblioteca Forwardable</strong></p>
<p>A biblioteca Forwardable possui dois módulos, <strong>Forwardable</strong> e <strong>SingleForwardable</strong>.</p>
<p><strong>Módulo Forwardable</strong></p>
<p>O módulo Forwardable oferece delegação dos métodos especificados para um objeto designado, usando os métodos <strong>def_delegator</strong> e <strong>def_delegators</strong>.</p>
<p><strong>def_delegator(obj, method, alias = method)</strong>: Define um método &#8220;method&#8221; que delega a chamada ao objeto &#8220;obj&#8221;. Se o alias for fornecido, será usado como o nome do método de delegação.</p>
<p><strong>def_delegators(obj, *methods)</strong>: Atalho para definir múltiplos métodos delegadores, mas sem permitir o uso de um nome diferente.</p>
<p>Vamos refatorar nosso exemplo de robô para utilizar o módulo Forwardable:</p>
<pre class="brush: ruby;">
require 'forwardable'

class Robo

  # Extend fornece métodos de classe
  extend Forwardable

  # Uso do  def_delegators
  def_delegators :@braco, :empacotar, :empilhar

  # Uso do  def_delegator
  def_delegator :@sensor_temperatura, :measure, :medir_temperatura

  def initialize
    @sensor_temperatura = SensorDeTemperatura.new
    @braco = BracoDoRobo.new
  end

end

class SensorDeTemperatura

  # Escala Celsius ou Fahrenheit
  def medir(escala=&quot;c&quot;)
    t = rand(100)
    t = escala==&quot;c&quot; ? t : t * (9/5)
    puts &quot;A temperatura é #{t}° #{escala.upcase}&quot;
  end

end

class BracoDoRobo

  def empilhar(quantidade_de_caixas=1)
    puts &quot;Empilhando #{quantidade_de_caixas} caixa(s)&quot;
  end

  def empacotar
    puts &quot;Empacotando&quot;
  end

end
</pre>
<p>Como pode ser visto, é uma solução mais limpa e consisa.</p>
<p><strong>Módulo SingleForwardable</strong></p>
<p>O módulo SingleForwardable oferece delegação dos métodos especificados para um objeto designado, utilizando os métodos <strong>def_delegator</strong> e <strong>def_delegators</strong>. Esse módulo é similar ao Forwardable, mas trabalha com os próprios objetos, em vez de suas classes que os definem.</p>
<pre class="brush: ruby;">
require &quot;forwardable&quot;
require &quot;date&quot;

date = Date.today #=&gt; #&lt;Date: 4909665/2,0,2299161&gt;
# Prepara o objeto para delegação
date.extend SingleForwardable #=&gt; #&lt;Date: 4909665/2,0,2299161&gt;
# Adiciona delegação para Time.now
date.def_delegator :Time, &quot;now&quot;,&quot;with_time&quot;
puts date.with_time #=&gt;Thu Jan 01 23:03:04 +0200 2009
</pre>
<p><strong>Biblioteca Delegate</strong></p>
<p>Delegate é outra biblioteca que oferece delegação, irei explicar duas formas de usá-la.</p>
<p><strong>Método DelegateClass</strong></p>
<p>Utiliza o método de nível superior <strong>DelegateClass</strong>, que permite inicializar a delegação por meio de herança. No exemplo seguinte, quero criar uma nova classe chamada CurrentDate, que armazene a data corrente e alguns métodos extras, ao mesmo em que delego a objetos data normais:</p>
<pre class="brush: ruby;">
require &quot;delegate&quot;
require &quot;date&quot;

# Note a definição da classe
class CurrentDate &lt; DelegateClass(Date)

  def initialize
    @date = Date.today
    # Passa o objeto a ser delegado à superclasse
    super(@date)
  end

  def to_s
    @date.strftime &quot;%Y/%m/%d&quot;
  end

  def with_time
    Time.now
  end

end

cdate = CurrentDate.new
# Note como funciona a delegação
# Em vez de usar cdate.date.day e definir um
# attr_accessor para date, eu uso c.day
puts cdate.day #=&gt;1
puts cdate.month #=&gt;1
puts cdate.year #=&gt;2009
# Testando métodos adicionados
# to_s
puts cdate #=&gt; 2009/01/01
puts cdate.with_time #=&gt; Thu Jan 01 23:22:20 +0200 2009
</pre>
<p><strong>Classe SimpleDelegator</strong></p>
<p>Use-a para delegar para um objeto que mode ser modificado:</p>
<pre class="brush: ruby;">
require &quot;delegate&quot;
require &quot;date&quot;

today = Date.today #=&gt; #&lt;Date: 4909665/2,0,2299161&gt;
yesterday = today - 1 #=&gt; #&lt;Date: 4909663/2,0,2299161&gt;
date = SimpleDelegator.new(today) #=&gt; #&lt;Date: 4909665/2,0,2299161&gt;
puts date #=&gt;2009-01-01
# Usa __setobj__ para trocar a delegação
date.__setobj__(yesterday)#=&gt; #&lt;Date: 4909663/2,0,2299161&gt;
puts date #=&gt;2008-12-31
</pre>
<p>Como pode ser visto, criamos dois objetos e delegamos a eles.</p>
<p><strong>E o Rails?</strong></p>
<p>Rails adiciona uma nova funcionalidade chamada &#8220;delegate&#8221;, que fornece um método de classe para expor facilmente os metodos dos objetos contidos como se fossem métodos próprios. Passe um ou mais métodos (especificados como símbolos ou strings) e como último parâmetro o nome do objeto alvo na opção <strong>:to</strong> (também como símbolo ou string). Pelo menos um método e a opção :to são exigidos.</p>
<p>Vá para o console, crie um novo projeto e inicie um console do rails:</p>
<pre class="brush: ruby;">
$ rails dummy
$ cd dummy
$ruby script/console
Loading development environment (Rails 2.2.2)
&gt;&gt; Person = Struct.new(:name, :address)
=&gt; Person
&gt;&gt; class Invoice &lt; Struct.new(:client)
&gt;&gt;   delegate :name, :address, :to =&gt; :client
&gt;&gt; end
=&gt; [:name, :address]
&gt;&gt; john_doe = Person.new(&quot;John Doe&quot;, &quot;Vimmersvej 13&quot;)
=&gt; #&lt;struct Person name=&quot;John Doe&quot;, address=&quot;Vimmersvej 13&quot;&gt;
&gt;&gt; invoice = Invoice.new(john_doe)
=&gt; #&lt;struct Invoice client=#&lt;struct Person name=&quot;John Doe&quot;, address=&quot;Vimmersvej 13&quot;&gt;&gt;
&gt;&gt; invoice.name
=&gt; John Doe
&gt;&gt; invoice.address
=&gt;Vimmersvej 13
</pre>
<p>Recomendo fortemente que você verifique todos os exemplos na documentação da API do Rails, para ver como usar esse recurso efetivamente com o ActiveRecord.</p>
<p>Antes de terminar esse artigo, quero compartilhar com você o código do método delegate do Rails. Adicionarei alguns comentários para explicar o que está acontecendo:</p>
<pre class="brush: ruby;">
class Module

  # método delegate
  # Espera um array de argumentos contendo os métodos
  # a serem delegados e um hash de opções
  def delegate(*methods)
    # Desempilha o hash de opções
    options = methods.pop
    # Verifica se o hash de opções foi passado, e se contém a opção :to
    # Lança uma exceção se um dos dois não forem encontrados
    unless options.is_a?(Hash) &amp;&amp; to = options[:to]
      raise ArgumentError, &quot;Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, :to =&gt; :greeter).&quot;
    end

    # Certifica-se de que a opção :to segue algumas
    # regras de sintaxe para nomes de métodos
    if options[:prefix] == true &amp;&amp; options[:to].to_s =~ /^[^a-z_]/
      raise ArgumentError, &quot;Can only automatically set the delegation prefix when delegating to a method.&quot;
    end

    # Atribui o verdadeiro valor do prefixo
    prefix = options[:prefix] &amp;&amp; &quot;#{options[:prefix] == true ? to : options[:prefix]}_&quot;

   # Aqui vem a mágica do Ruby <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
   # Técnicas de reflexão são usadas aqui:
   # module_eval é usado para adicionar novos métodos em tempo de execução, onde:
   # expõe os métodos dos objetos contidos
    methods.each do |method|
      module_eval(&quot;def #{prefix}#{method}(*args, &amp;block)\n#{to}.__send__(#{method.inspect}, *args, &amp;block)\nend\n&quot;, &quot;(__DELEGATION__)&quot;, 1)
    end

  end

end
</pre>
<p>Isso é tudo para esse artigo, foram cobertos 5 pontos:</p>
<p>1. Composição versus Herança.<br />
2. O que é delegação, e porque ela é usada.<br />
3. Biblioteca Forwardable.<br />
4. Biblioteca Delegate.<br />
5. Método delegate do Rails.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoluizao.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoluizao.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoluizao.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoluizao.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/fernandoluizao.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/fernandoluizao.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/fernandoluizao.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/fernandoluizao.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoluizao.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoluizao.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoluizao.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoluizao.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoluizao.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoluizao.wordpress.com/89/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=89&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fernandoluizao.wordpress.com/2009/03/31/traducao-delegacao-em-ruby/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c8838aa29a4289dd42a2b92fe5490d7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fernandoluizao</media:title>
		</media:content>

		<media:content url="http://fernandoluizao.files.wordpress.com/2009/03/delegation-uml11.png" medium="image">
			<media:title type="html">delegation-uml11</media:title>
		</media:content>

		<media:content url="http://fernandoluizao.files.wordpress.com/2009/03/delegation-uml21.png" medium="image">
			<media:title type="html">delegation-uml21</media:title>
		</media:content>

		<media:content url="http://fernandoluizao.files.wordpress.com/2009/03/delegation-uml31.png" medium="image">
			<media:title type="html">delegation-uml31</media:title>
		</media:content>
	</item>
		<item>
		<title>acts_as_active: mais um plugin no estilo acts_as_paranoid</title>
		<link>http://fernandoluizao.wordpress.com/2009/03/06/acts_as_active-mais-um-plugin-no-estilo-acts_as_paranoid/</link>
		<comments>http://fernandoluizao.wordpress.com/2009/03/06/acts_as_active-mais-um-plugin-no-estilo-acts_as_paranoid/#comments</comments>
		<pubDate>Fri, 06 Mar 2009 00:51:29 +0000</pubDate>
		<dc:creator>fernandoluizao</dc:creator>
				<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[acts_as_active]]></category>
		<category><![CDATA[acts_as_paranoid]]></category>
		<category><![CDATA[default_scope]]></category>
		<category><![CDATA[named_scope]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://fernandoluizao.wordpress.com/?p=85</guid>
		<description><![CDATA[Pra quem é do mundo Rails, o acts_as_paranoid já é velho conhecido, ele sobrescreve alguns métodos do ActiveRecord para marcar um registro como excluído em vez de efetivamente excluí-lo. Ele também adiciona um escopo para esconder os registros &#8220;exluídos&#8221; dos finders e outras operações comuns como count, sum, max, etc. Meu novo plugin, acts_as_active, faz [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=85&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Pra quem é do mundo Rails, o <a href="http://github.com/technoweenie/acts_as_paranoid">acts_as_paranoid</a> já é velho conhecido, ele sobrescreve alguns métodos do ActiveRecord para marcar um registro como excluído em vez de efetivamente excluí-lo. Ele também adiciona um escopo para esconder os registros &#8220;exluídos&#8221; dos finders e outras operações comuns como <strong>count</strong>, <strong>sum</strong>, <strong>max</strong>, etc. Meu novo plugin, <a href="http://github.com/fernandoluizao/acts_as_active">acts_as_active</a>, faz basicamente a mesma coisa, porém utiliza um booleano em vez de um timestamp para indicar que o registro está ativo e utiliza um escopo padrão para mostrar apenas os ativos.</p>
<p><strong>Instalando o acts_as_active</strong></p>
<p>Pra instalar, o de sempre:</p>
<pre class="brush: ruby;">
script/plugin install git://github.com/fernandoluizao/acts_as_active.git
</pre>
<p><strong>IMPORTANTE:</strong> Meu plugin depende de um novo recurso adicionado no Rails 2.3 chamado <a href="http://ryandaigle.com/articles/2008/11/18/what-s-new-in-edge-rails-default-scoping">default_scope</a><br />
Para quem usa Rails 2.1 ou 2.2, instale o plugin default_scope.</p>
<pre class="brush: ruby;">
script/plugin install git://github.com/duncanbeevers/default_scope.git
</pre>
<p><strong>Uso</strong></p>
<p>O plugin assume que vc tem um campo booleano com o nome &#8220;active&#8221;, com valor default TRUE. Exemplo de uso:</p>
<pre class="brush: ruby;">
  create_table :users do |t|
    t.string :name
    t.string :last_name
    t.boolean :active, :null =&gt; false, :default =&gt; true
  end

  class User &lt; ActiveRecord::Base
    acts_as_active
  end

  User.first.destroy
  UPDATE users SET active = 'f' WHERE id = 1

  #chama o destroy original e acaba com nosso usuário
  User.first.destroy!
  DELETE FROM users WHERE id = 1

  User.all
  SELECT * FROM users WHERE active = 't'

  User.all :conditions =&gt; {:name =&gt; &quot;joe&quot;}
  SELECT * FROM users WHERE (name = 'joe') AND (active = 't')
</pre>
<p>Se quiser procurar incluindo os inativos:</p>
<pre class="brush: ruby;">
  User.find_with_inactive :conditions =&gt; {:name =&gt; &quot;joe&quot;}
  SELECT * FROM users WHERE (name = 'joe')
</pre>
<p>O nome do campo booleano pode ser configurado da seguinte forma:</p>
<pre class="brush: ruby;">
class User &lt; ActiveRecord::Base
  acts_as_active :with =&gt; :nome_campo
end
</pre>
<p>É isso, um plugin simples, mas que me poupa um bom trabalho. Espero que gostem <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoluizao.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoluizao.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoluizao.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoluizao.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/fernandoluizao.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/fernandoluizao.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/fernandoluizao.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/fernandoluizao.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoluizao.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoluizao.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoluizao.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoluizao.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoluizao.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoluizao.wordpress.com/85/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=85&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fernandoluizao.wordpress.com/2009/03/06/acts_as_active-mais-um-plugin-no-estilo-acts_as_paranoid/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c8838aa29a4289dd42a2b92fe5490d7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fernandoluizao</media:title>
		</media:content>
	</item>
		<item>
		<title>Dica: define_method com parâmetros opcionais</title>
		<link>http://fernandoluizao.wordpress.com/2009/02/11/dica-define_method-com-parametros-opcionais/</link>
		<comments>http://fernandoluizao.wordpress.com/2009/02/11/dica-define_method-com-parametros-opcionais/#comments</comments>
		<pubDate>Wed, 11 Feb 2009 21:26:03 +0000</pubDate>
		<dc:creator>fernandoluizao</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://fernandoluizao.wordpress.com/?p=81</guid>
		<description><![CDATA[Quando estamos definindo um método com define_method, passamos os parâmetros nas variáveis do bloco, por exemplo: Porém, se tentarmos definir um parâmetro opcional (com valor default), da forma que estamos acostumados, temos um erro de sintaxe: Para contornar isso, podemos utilizar o splat (*), para colocar os parâmetros opcionais em um array: Dessa forma podemos [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=81&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Quando estamos definindo um método com <strong>define_method</strong>, passamos os parâmetros nas variáveis do bloco, por exemplo:</p>
<pre class="brush: ruby;">
class Teste
  define_method &quot;meu_metodo&quot; do |foo, bar|
    puts &quot;foo: #{foo}, bar: #{bar}&quot;
  end
end

t = Teste.new
t.meu_metodo &quot;param1&quot;, &quot;param2&quot;
#foo: param1, bar: param2
</pre>
<p>Porém, se tentarmos definir um parâmetro opcional (com valor default), da forma que estamos acostumados,  temos um erro de sintaxe:</p>
<pre class="brush: ruby;">
define_method &quot;meu_metodo&quot; do |foo, bar, options = {}|
#syntax error, unexpected tSTRING_BEG, expecting kDO or '{' or '('
</pre>
<p>Para contornar isso, podemos utilizar o splat (*), para colocar os parâmetros opcionais em um array:</p>
<pre class="brush: ruby;">
class Teste
  define_method &quot;meu_metodo&quot; do |foo, bar, *options|
    #se o parametro opcional não for passado, inicializamos com um hash vazio
    options = options.first || {}
    puts &quot;foo: #{foo}, bar: #{bar}&quot;
    puts options.inspect
  end
end

t = Teste.new
t.meu_metodo &quot;param1&quot;, &quot;param2&quot;, :foo =&gt; &quot;foo&quot;, :bar =&gt; &quot;bar&quot;
#foo: param1, bar: param2
#{:bar=&gt;&quot;bar&quot;, :foo=&gt;&quot;foo&quot;}
t.meu_metodo &quot;primeiro&quot;, &quot;segundo&quot;
#foo: primeiro, bar: segundo
#{}
</pre>
<p>Dessa forma podemos passar quantos parâmetros opcionais quisermos <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoluizao.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoluizao.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoluizao.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoluizao.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/fernandoluizao.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/fernandoluizao.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/fernandoluizao.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/fernandoluizao.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoluizao.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoluizao.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoluizao.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoluizao.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoluizao.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoluizao.wordpress.com/81/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=81&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fernandoluizao.wordpress.com/2009/02/11/dica-define_method-com-parametros-opcionais/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c8838aa29a4289dd42a2b92fe5490d7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fernandoluizao</media:title>
		</media:content>
	</item>
		<item>
		<title>Insensitivity: O plugin insensível</title>
		<link>http://fernandoluizao.wordpress.com/2009/02/10/insensitivity-o-plugin-insensivel/</link>
		<comments>http://fernandoluizao.wordpress.com/2009/02/10/insensitivity-o-plugin-insensivel/#comments</comments>
		<pubDate>Tue, 10 Feb 2009 23:25:07 +0000</pubDate>
		<dc:creator>fernandoluizao</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[active record]]></category>
		<category><![CDATA[case insensitive]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://fernandoluizao.wordpress.com/?p=73</guid>
		<description><![CDATA[Consultas case insensitive e independentes de acentos que funcionem em qualquer SGBD são difíceis de conseguir, pois cada banco possui sua maneira específica de fazer isso. Se forem tomados alguns cuidados, é possível usar a sintaxe correta de acordo com o adaptador que estamos usando. No PostgreSQL por exemplo, para conseguir uma consulta case insensitive [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=73&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Consultas case insensitive e independentes de acentos que funcionem em qualquer SGBD são difíceis de conseguir, pois cada banco possui sua maneira específica de fazer isso. Se forem tomados alguns cuidados, é possível usar a sintaxe correta de acordo com o adaptador que estamos usando. No PostgreSQL por exemplo, para conseguir uma consulta case insensitive e independente de acentos, temos que fazer coisas <a href="http://www.bragil.net/2008/03/20/consultas-case-insensitive-no-postgresql/">assim</a> ou <a href="http://www.dicas-l.com.br/dicas-l/20061229.php">assim</a>.</p>
<p>O problema em usar conversões nas colunas é que, além delas não fazerem parte padrão SQL, perdemos os índices na coluna, o que vai fazer nossa consulta demorar um pouco mais (dependendo da quatidade de registros, usar ou não um índice pode fazer uma grande diferença). Para resolver esse problema, criei o plugin &#8220;<a href="http://github.com/fernandoluizao/insensitivity">Insensitivity</a>&#8220;, que usa uma coluna extra para armazenar o valor sem acentos e em minúsculas. Assim, durante as consultas, o ActiveRecord irá utilizar essa coluna em vez da coluna com o valor real.</p>
<p><strong>Vantagens dessa abordagem</strong></p>
<p>Independente de banco<br />
Se hover índices, serão usados</p>
<p><strong>Desvantagens</strong></p>
<p>Utiliza o dobro de espaço.</p>
<p><strong>Instalando e usando o plugin</strong></p>
<pre class="brush: ruby;">
script/plugin install git://github.com/fernandoluizao/insensitivity.git
</pre>
<p>No seu model, você deve indicar quais campos usarão a pesquisa case insensitive:</p>
<pre class="brush: ruby;">
class User &lt; ActiveRecord:Base
  insensible :name, :email
end
</pre>
<p>Depois, você <strong>DEVE</strong> adicionar à tabela, os campos com o mesmo nome dos que foram indicados e com o sufixo &#8220;_search&#8221;. Se desejar, também coloque índices para melhorar a performance. Por exemplo:</p>
<pre class="brush: ruby;">
script/generate migration add_search_fields

def self.up
  change_table :users do |t|
    t.string :name_search
    t.string :email_search
  end

  add_index :users, :name_search
  add_index :users, :email_search

  #Se sua tabela ja tiver dados, vc pode usar
  #User.make_insensible!
  #Isso vai inicializar os novos campos nos registros já existentes
end

def self.down
  change_table :users do |t|
    t.remove :name_search
    t.remove :email_search
  end
end
</pre>
<p>Para fazer as buscas, não muda nada. Veja as consultas geradas:</p>
<pre class="brush: ruby;">
User.find_by_name('bla')
SELECT * FROM users WHERE name_search = 'bla'
</pre>
<pre class="brush: ruby;">
User.find(:first, :conditions =&gt; ['name = ?', 'bla'], <img src='http://s1.wp.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> rder =&gt; 'name')
SELECT * FROM users WHERE name_search = 'bla' ORDER BY name LIMIT 1
</pre>
<p>Tudo funciona de forma transparente, sem vc precisar se preocupar =). Sua única preocupação deve ser passar o valor nas conditions sem acentos e em minusculas, para isso pode usar o método &#8220;insensible&#8221;, adicionado à classe String:</p>
<pre class="brush: ruby;">
User.find(:first, :conditions =&gt; ['name LIKE ?', &quot;%#{params[:name].insensible}%&quot;])
SELECT * FROM users WHERE name_search LIKE '%bla%'
</pre>
<p>Bom, é isso, pesquisa sem sentimentos <img src='http://s2.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Quem quiser colaborar:</p>
<p><a href="http://github.com/fernandoluizao/insensitivity/">http://github.com/fernandoluizao/insensitivity/</a></p>
<p>PS: Testei apenas com rails 2.2.2. Pode não funcionar com versões mais antigas (&lt; 2.0)</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoluizao.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoluizao.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoluizao.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoluizao.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/fernandoluizao.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/fernandoluizao.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/fernandoluizao.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/fernandoluizao.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoluizao.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoluizao.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoluizao.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoluizao.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoluizao.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoluizao.wordpress.com/73/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoluizao.wordpress.com&amp;blog=5578172&amp;post=73&amp;subd=fernandoluizao&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fernandoluizao.wordpress.com/2009/02/10/insensitivity-o-plugin-insensivel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c8838aa29a4289dd42a2b92fe5490d7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fernandoluizao</media:title>
		</media:content>
	</item>
	</channel>
</rss>
