<?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>Debugando.com &#187; Ruby on Rails</title>
	<atom:link href="http://www.debugando.com/categoria/programacao/ruby-on-rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.debugando.com</link>
	<description>Noticias, dicas e tutorias do mundo da Tecnologia.</description>
	<lastBuildDate>Thu, 01 Dec 2011 23:44:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Twitter, Scala e Ruby</title>
		<link>http://www.debugando.com/twitter-scala-e-ruby/</link>
		<comments>http://www.debugando.com/twitter-scala-e-ruby/#comments</comments>
		<pubDate>Tue, 14 Apr 2009 21:42:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Noticias]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tecnologia]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[Twiter]]></category>

		<guid isPermaLink="false">http://www.debugando.com/?p=541</guid>
		<description><![CDATA[


E lá vamos nós de novo! Houve um zum-zum-zum por aí onde se comentou que o Twitter estava (está, sei lá) trocando Ruby por Scala que o mundo quase acabou. Teve gente que, se estivéssemos na idade média, com certeza iria munida de cruzes e tochas na sede do Twitter para tentar queimar tudo, bando [...]]]></description>
			<content:encoded><![CDATA[<p>E lá vamos nós de novo! Houve um zum-zum-zum por aí onde se comentou que o <a class="ext" href="http://twitter.com/taq">Twitter</a> estava (está, sei lá) trocando <a class="ext" href="http://www.ruby-lang.org/">Ruby</a> por <a class="ext" href="http://www.scala-lang.org/">Scala</a> que o mundo quase acabou. Teve gente que, se estivéssemos na idade média, com certeza iria munida de cruzes e tochas na sede do Twitter para tentar queimar tudo, bando de hereges. Literalmente choveram textos sobre isso na web, que eu acho que nem compensa linkar por causa de todo o ruído que causaram, com exceção notável <a class="ext" href="http://logbr.reflectivesurface.com/2009/04/08/eu-fico-com-a-baleia/">desse aqui do Ronaldo Ferraz</a>, onde, como sempre, ele elabora o tema muito bem, mas eu sou mais tosco (como sempre). Quis fazer esse um pouco mais direto, pois isso já está enchendo o saco.</p>
<h4>Que mal tem o Twitter trocar de Ruby para Scala (ou whatever)?</h4>
<p>Isso vai te afetar? Só se você trabalha no Twitter e não sabe programar em nada além de Ruby e está com preguiça de aprender alguma coisa nova, o que é uma vergonha se você tem a oportunidade. Bom, eu não trabalho no Twitter, e acredito que muita gente que está lendo isso também não, então qual é problema? Precisa de todo esse auê?</p>
<p>&#8220;Ah, mas isso pode queimar o filme da linguagem, dizendo que ela não escala, não aguenta o tranco, consome muitos recursos blá blá blá&#8221;. Ok, vamos lá.</p>
<p>Quem programa na linguagem (ou em qualquer outra) e <strong>gosta</strong> do que ela faz e dos seus recursos não precisa se preocupar em &#8220;queimação de filme&#8221;. Isso é coisa de modinha. Talvez só se precisar entrar em um processo de convencimento da linguagem e/ou tecnologia para o chefe, que pode ser aquele tipo que toca toda a TI da empresa baseado em folders que recebe pelo Correio (sim, esse pessoal investe em papel bem bonito, nada de email), por muita grana e por notícias que ele vê em sites especializados. E talvez essa notícia nem saia lá, então fique tranquilo.</p>
<p>Só fica &#8220;noiado&#8221; quem investe muito em uma &#8220;aura santa&#8221; da dita cuja e pode perder dinheiro e status (ah, esse talvez mande até mais do que o primeiro) se ela deixar de ser &#8220;cool&#8221;, de ficar em evidência, se carregar o mínimo arranhão sobre o que alguém disse sobre ela. Aí se cria todo esse auê, onde o marketing excessivo acaba saturando e remendando a situação. Afinal, mesmo que não se chegue à uma conclusão o ruído foi criado e pode ser utilizado para disfarçar a coisa. Você não vai querer ser superficial desse jeito, vai? Olhe o que aconteceu com toda a aura que o Java tinha nos últimos anos. Na AURA, eu disse, não na tecnologia!</p>
<p>Vejam bem, eu escrevi um livro sobre a linguagem e fico divulgando ela por aí, mas NUNCA vou fazer um barulho desses se alguém disser &#8220;migrei de Ruby pra XYZ&#8221; (ok, eu posso ficar inconformado se você for para ASP ou coisa do tipo, mas aí a discussão é, além de técnica, filosófica, e é outra história) e não vejo necessidade de ficar provando que ela é melhor que as outras. Putz, parece que xingam a mãe quando dizem que vão fazer uma migração, quando dizem que não gostam da linguagem ou que ela tem as suas limitações. TODA linguagem tem suas limitações, qual é o problema?</p>
<p>Apesar de ser grande utilizador e, por que não, &#8220;evangelizador&#8221; da linguagem, eu prefiro, antes de mais nada, ser honesto com quem lê minhas opiniões. Tomara que não chegue o dia em que eu fique sem grana e precise ser pago para dizer &#8220;ei, isso é legal&#8221;, mesmo que a coisa seja uma porcaria. A gente tem visto isso acontecer muito ultimamente, e é algo bem ruim. E eu uso a linguagem <strong>sim</strong> por achar ela muito boa, não porque quero parecer o gostosão da cocada preta de Ruby. Quem me acompanha pode ver que sou bem sossegado em termos de marketing.</p>
<p>Acredito que, se você gosta da linguagem, está se divertindo fazendo com gosto os seus programas nela, não deve ligar para umas notícias dessas. Se a gente ligasse tanto para o que os outros fazem e falam não teríamos um monte de coisas legais que temos por aí.</p>
<p>Agora, você está começando agora a usar Rails, ou está estudando a linguagem, ou pretende migrar a sua aplicação de XYZ para Rails e está preocupado porque o Twitter migrou, sendo que a sua aplicação pode consumir 1/1000 dos recursos que a deles consome??? Benza Deus, hein!!! Se for desistir fácil assim, melhor comprar a revista mais cara que tem na banca de gerentes e escolher a tecnologia mais cara e talvez, mais obscura, onde você nunca precise escutar nada que possa deixar ela menos &#8220;cool&#8221;.</p>
<p><em>Fonte: <a onclick="javascript:urchinTracker ('/outbound/article/www.pplware.com');" href="http://imasters.uol.com.br/artigo/12381/ruby/twitter_scala_e_ruby/" target="_blank">Imasters</a></em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.debugando.com/twitter-scala-e-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Micro-Tutorial de Ruby &#8211; Parte III</title>
		<link>http://www.debugando.com/micro-tutorial-de-ruby-parte-iii/</link>
		<comments>http://www.debugando.com/micro-tutorial-de-ruby-parte-iii/#comments</comments>
		<pubDate>Thu, 18 Dec 2008 12:28:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.debugando.com/?p=263</guid>
		<description><![CDATA[Tipos Básicos
Continuando com os tipos básicos de Ruby (no artigo anterior já falamos de Arrays e Hashes):
Strings
Novamente, nada de muito surpreendente aqui:
&#62;&#62; palavra = "bla bla"
=&#62; "bla bla"
&#62;&#62; palavra.size
=&#62; 7

A operação mais comum em string é a concatenação:

&#62;&#62; nome = "Diego"
=&#62; "Diego"
&#62;&#62; sobrenome = "Moreira"
=&#62; "Moreira"
&#62;&#62; nome + " " + sobrenome
=&#62; "Diego Moreira"

Porém, já [...]]]></description>
			<content:encoded><![CDATA[<h2>Tipos Básicos</h2>
<p>Continuando com os tipos básicos de Ruby (no artigo anterior já falamos de Arrays e Hashes):</p>
<h3>Strings</h3>
<p>Novamente, nada de muito surpreendente aqui:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; palavra = <span class="s"><span class="dl">"</span><span class="k">bla bla</span><span class="dl">"</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">bla bla</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; palavra.size<tt>
</tt>=&gt; <span class="i">7</span></em><tt>

</tt>A operação mais comum em string é a concatenação:
<em>
&gt;&gt; nome = <span class="s"><span class="dl">"</span><span class="k">Diego</span><span class="dl">"</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">Diego</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; sobrenome = <span class="s"><span class="dl">"</span><span class="k">Moreira</span><span class="dl">"</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">Moreira</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; nome + <span class="s"><span class="dl">"</span><span class="k"> </span><span class="dl">"</span></span> + sobrenome<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">Diego Moreira</span><span class="dl">"</span></span></em><tt>

</tt>Porém, já vimos em seções anteriores outra maneira
de fazer a mesma concatenação:

<em>&gt;&gt; <span class="s"><span class="dl">"</span><span class="il"><span class="dl">#{</span>nome<span class="dl">}</span></span><span class="k"> </span><span class="il"><span class="dl">#{</span>sobrenome<span class="dl">}</span></span><span class="dl">"</span></span><tt>
</tt>=&gt; </em><span class="s"><em><span class="dl">"</span><span class="k">Diego Moreira</span></em><span class="dl"><em>"</em>

</span></span>Tudo que estiver dentro de “#{}” é executado e o resultado convertido
em String e concatenado junto com o resto. Isso deve evitar aquele
monte de “+” o tempo todo quando queremos concatenar as coisas. Um dos
lugares onde mais usamos concatenação é quando queremos strings com
quebras de linha. O jeito comum é fazer assim:

<em>&gt;&gt; nome = <span class="s"><span class="dl">"</span><span class="k">F</span><span class="dl">"</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">F</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; query = <span class="s"><span class="dl">"</span><span class="k">SELECT * FROM NOMES </span><span class="ch">\n</span><span class="dl">"</span></span> +<tt>
</tt><span class="i">?&gt;</span>     <span class="s"><span class="dl">"</span><span class="k">WHERE NOME LIKE '%</span><span class="dl">"</span></span> + nome + <span class="s"><span class="dl">"</span><span class="k">%' </span><span class="ch">\n</span><span class="dl">"</span></span> +<tt>
</tt><span class="i">?&gt;</span>     <span class="s"><span class="dl">"</span><span class="k">ORDER BY NOME</span><span class="dl">"</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">SELECT * FROM NOMES </span><span class="ch">\n</span><span class="k">WHERE NOME LIKE '%F%' </span><span class="ch">\n</span><span class="k">ORDER BY NOME</span><span class="dl">"</span></span></em><tt>
</tt>
<tt></tt>Ou algo parecido com isso, o que é bem feio e sabemos o quanto isso se
torna impossível de dar manutenção no futuro. Mas em Ruby podemos fazer
um pouco melhor que isso:

<em>&gt;&gt; nome = <span class="s"><span class="dl">"</span><span class="k">F</span><span class="dl">"</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">F</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; query = <span class="s"><span class="dl">&lt;&lt;-STR</span></span><span class="s"><span class="k"><tt>
</tt>  SELECT * FROM NOMES<tt>
</tt>  WHERE NOME LIKE '%</span><span class="il"><span class="dl">#{</span>nome<span class="dl">}</span></span><span class="k">%'<tt>
</tt>  ORDER BY NOME</span><span class="dl"><tt>
</tt>STR</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">  SELECT * FROM NOMES</span><span class="ch">\n</span><span class="k">  WHERE NOME LIKE '%F%'</span><span class="ch">\n</span><span class="k">  ORDER BY NOME</span><span class="ch">\n</span><span class="dl">"</span></span><tt>
</tt></em>
Onde está “<span class="caps">STR</span>” na realidade pode ser
qualquer palavra em letras maiúsculas, tomando o cuidado para não ter
espaços em branco nem antes nem depois do “<span class="caps">STR</span>” da última linha. 

<em>&gt;&gt; nome = <span class="s"><span class="dl">"</span><span class="k">F</span><span class="dl">"</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">F</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; query = <span class="s"><span class="dl">%{</span><span class="k">SELECT * FROM NOMES<tt>
</tt>  WHERE NOME LIKE '%</span><span class="il"><span class="dl">#{</span>nome<span class="dl">}</span></span><span class="k">%'<tt>
</tt>  ORDER BY NOME</span><span class="dl">}</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">SELECT * FROM NOMES</span><span class="ch">\n</span><span class="k">  WHERE NOME LIKE '%F%'</span><span class="ch">\n</span><span class="k">  ORDER BY NOME</span><span class="dl">"</span></span></em><tt>
</tt>
E também desta maneira:

<em>&gt;&gt; nome = <span class="s"><span class="dl">"</span><span class="k">F</span><span class="dl">"</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">F</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; query = <span class="s"><span class="dl">%Q(</span><span class="k">SELECT * FROM NOMES<tt>
</tt>  WHERE NOME LIKE '%</span><span class="il"><span class="dl">#{</span>nome<span class="dl">}</span></span><span class="k">%'<tt>
</tt>  ORDER BY NOME</span><span class="dl">)</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">SELECT * FROM NOMES</span><span class="ch">\n</span><span class="k">  WHERE NOME LIKE '%F%'</span><span class="ch">\n</span><span class="k">  ORDER BY NOME</span><span class="dl">"</span></span><tt>
</tt></em>
Todas as maneiras acima são jeitos de se criar strings de múltiplas
linhas com a possibilidade de execução e substituição in-place usando
“#{}”. Eu particularmente prefiro fazer alguma coisa do tipo:

<em>&gt;&gt; nome = <span class="s"><span class="dl">"</span><span class="k">F</span><span class="dl">"</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">F</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; query = <span class="s"><span class="dl">%q(</span><span class="k">SELECT * FROM NOMES<tt>
</tt>  WHERE NOME LIKE '%[nome]%'<tt>
</tt>  ORDER BY NOME</span><span class="dl">)</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">SELECT * FROM NOMES</span><span class="ch">\n</span><span class="k">  WHERE NOME LIKE '%[nome]%'</span><span class="ch">\n</span><span class="k">  ORDER BY NOME</span><span class="dl">"</span></span><tt>
</tt><tt>
</tt>&gt;&gt; query.gsub!(<span class="s"><span class="dl">'</span><span class="k">[nome]</span><span class="dl">'</span></span>, nome)<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">SELECT * FROM NOMES</span><span class="ch">\n</span><span class="k">  WHERE NOME LIKE '%F%'</span><span class="ch">\n</span><span class="k">  ORDER BY NOME</span><span class="dl">"</span></span><tt>
</tt></em></pre>
<p>A sintaxe de “%q()” também permite criar strings de múltiplas linhas mas não suporta a execução de código via “#{}”, por isso coloquei algo que possa encontrar depois (um &#8220;placeholder&#8221;) como “[nome]” e no final uso o método “gsub” que faz substituição em Strings. Eu disse que “prefiro” mais para separar explicitamente as substituições fora do String. Mas, novamente, existem diversas maneiras de realizar essa mesma tarefa, depende do que você precisa fazer.</p>
<p><strong>Disclaimer:</strong> nunca crie consultas <span class="caps">SQL</span> da forma como mostrei acima. Se você apenas concatenar o valor que foi passado pelo usuário diretamente no comando <span class="caps">SQL</span> que vai executar, seu código estará automaticamente vulnerável à <a href="http://en.wikipedia.org/wiki/SQL_injection"><span class="caps">SQL</span> Injection</a>. Esse é o erro mais comum que todo desenvolvedor Web novato comete. Então cuidado! Para isso servem pacotes como ActiveRecord, que abstraem o <span class="caps">SQL</span> nativo e realizam as checagens mais comuns antes de criar o <span class="caps">SQL</span>.</p>
<h3>Symbols</h3>
<p>Note que na seção sobre Hashes, criamos um pequeno dicionário ligando uma palavra em inglês à sua tradução em português. Para isso usamos objetos String tanto para os valores quanto para as chaves, por exemplo:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>dic1 = { <span class="s"><span class="dl">"</span><span class="k">leg</span><span class="dl">"</span></span> =&gt; <span class="s"><span class="dl">"</span><span class="k">perna</span><span class="dl">"</span></span> }</em><tt>

</tt>Mas você vai notar que em Ruby e principalmente no Rails, não costumamos
usar Strings como chaves.
Em vez disso usamos Symbols:

<em>dic2 = { <span class="sy">:leg</span> =&gt; <span class="s"><span class="dl">"</span><span class="k">perna</span><span class="dl">"</span></span> }</em><tt>
</tt></pre>
<p>Quero dizer, não é proibido usar Strings, mas se não precisar, prefira usar Symbols. Existem dois motivos para isso: o primeiro é porque symbols são mais legíveis e fáceis de visualizar, a segunda é economia de memória.</p>
<p>Em poucas palavras, um Symbol sempre gera um objeto Singleton imutável. Por exemplo:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; a = <span class="sy">:leg</span><tt>
</tt>=&gt; <span class="sy">:leg</span><tt>
</tt>&gt;&gt; b = <span class="sy">:leg</span><tt>
</tt>=&gt; <span class="sy">:leg</span><tt>
</tt>&gt;&gt; a.object_id<tt>
</tt>=&gt; <span class="i">531778</span><tt>
</tt>&gt;&gt; b.object_id<tt>
</tt>=&gt; <span class="i">531778</span></em><tt>

</tt>Note como atribuímos :leg às variáveis “a” e “b”. Chamando o método
“object_id”, ambas respondem o mesmo ID, denotando que as duas
variáveis estão apontando ao mesmo objeto Symbol. Vejamos o mesmo
exemplo usando Strings:

<em>&gt;&gt; a = <span class="s"><span class="dl">"</span><span class="k">leg</span><span class="dl">"</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">leg</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; b = <span class="s"><span class="dl">"</span><span class="k">leg</span><span class="dl">"</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">leg</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; a.object_id<tt>
</tt>=&gt; <span class="i">11823830</span><tt>
</tt>&gt;&gt; b.object_id<tt>
</tt>=&gt; <span class="i">11820130</span></em><tt>
</tt></pre>
<p>Note como os dois IDs vieram diferentes. Ou seja, apesar do conteúdo ser o mesmo, as variáveis “a” e “b” estão apontando para objetos String diferentes. A primeira impressão é que são o mesmo objeto, mas na realidade são dois objetos distintos que por acaso tem o mesmo conteúdo. Espero que tenha ficado claro porque Symbols consomem menos memória que Strings.</p>
<p>Existem vários outros objetos singleton em Ruby. Números é um deles, afinal não faz sentido existir mais de um número “1”. O mesmo vale para objetos booleanos. Por exemplo:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; a = <span class="i">1</span><tt>
</tt>=&gt; <span class="i">1</span><tt>
</tt>&gt;&gt; b = <span class="i">1</span><tt>
</tt>=&gt; <span class="i">1</span><tt>
</tt>&gt;&gt; c = <span class="pc">true</span><tt>
</tt>=&gt; <span class="pc">true</span><tt>
</tt>&gt;&gt; d = <span class="pc">true</span><tt>
</tt>=&gt; <span class="pc">true</span><tt>
</tt><tt>
</tt>&gt;&gt; a.object_id == b.object_id<tt>
</tt>=&gt; <span class="pc">true</span><tt>
</tt>&gt;&gt; c.object_id == d.object_id<tt>
</tt>=&gt; <span class="pc">true</span><tt>
</tt>&gt;&gt; a = <span class="i">1</span><tt>
</tt>=&gt; <span class="i">1</span><tt>
</tt>&gt;&gt; b = <span class="i">1</span><tt>
</tt>=&gt; <span class="i">1</span><tt>
</tt>&gt;&gt; c = <span class="pc">true</span><tt>
</tt>=&gt; <span class="pc">true</span><tt>
</tt>&gt;&gt; d = <span class="pc">true</span><tt>
</tt>=&gt; <span class="pc">true</span><tt>
</tt><tt>
</tt>&gt;&gt; a.object_id == b.object_id<tt>
</tt>=&gt; <span class="pc">true</span><tt>
</tt>&gt;&gt; c.object_id == d.object_id<tt>
</tt>=&gt; <span class="pc">true</span></em><tt>
</tt></pre>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">Na prática, sempre use Symbols como chaves de Hash. É onde eles são
mais usados. Em Ruby on Rails, o pacote ActiveSupport consegue traduzir
Hashes com chaves em String para Symbols, desta forma:
<em>
&gt;&gt; require <span class="s"><span class="dl">'</span><span class="k">rubygems</span><span class="dl">'</span></span><tt>
</tt>=&gt; []<tt>
</tt>&gt;&gt; require <span class="s"><span class="dl">'</span><span class="k">activesupport</span><span class="dl">'</span></span><tt>
</tt>=&gt; []<tt>
</tt>&gt;&gt; params = { <span class="s"><span class="dl">"</span><span class="k">nome</span><span class="dl">"</span></span> =&gt; <span class="s"><span class="dl">"</span><span class="k">Diego</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">sobrenome</span><span class="dl">"</span></span> =&gt; <span class="s"><span class="dl">"</span><span class="k">Moreira</span><span class="dl">"</span></span> }<tt>
</tt>=&gt; {<span class="s"><span class="dl">"</span><span class="k">nome</span><span class="dl">"</span></span>=&gt;<span class="s"><span class="dl">"</span><span class="k">Diego</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">sobrenome</span><span class="dl">"</span></span>=&gt;<span class="s"><span class="dl">"Moreira</span><span class="dl">"</span></span>}<tt>
</tt>&gt;&gt; params.symbolize_keys!<tt>
</tt>=&gt; {<span class="sy">:nome</span>=&gt;<span class="s"><span class="dl">"</span><span class="k">Diego</span><span class="dl">"</span></span>, <span class="sy">:sobrenome</span>=&gt;<span class="s"><span class="dl">"Moreira</span><span class="dl">"</span></span>}<tt>
</tt>&gt;&gt; params[<span class="sy">:nome</span>]<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">Diego</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; params[<span class="sy">:sobrenome</span>]<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">Moreira</span><span class="dl">"</span></span></em><tt>
</tt></pre>
<h2>Métodos em Ruby</h2>
<p>Depois de tudo isso, podemos ir um pouco além. Em Ruby temos maneiras muito diferentes de se escrever métodos. Em linguagens estáticas, como Java, temos o conceito de <a href="http://en.wikipedia.org/wiki/Method_overloading">overloading</a>. Por exemplo:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>public class Pessoa {<tt>
</tt>  String nome;<tt>
</tt>  String email;<tt>
</tt><tt>
</tt>  public Pessoa(String nome, String email) {<tt>
</tt>    this.nome = nome;<tt>
</tt>    this.email = email;<tt>
</tt>  }<tt>
</tt><tt>
</tt>  public Pessoa(String nome) {<tt>
</tt>  this(nome, "");<tt>
</tt>  }<tt>
</tt>}</em><tt>

</tt>Esse trecho define a classe “Pessoa” com dois construtores.
Dessa forma podemos instanciar uma nova Pessoa da seguinte forma:</pre>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>Pessoa diego = new Pessoa("Diego", "diego@foo.com.br");<tt>
</tt>Pessoa Moreira = new Pessoa("Moreira");</em><tt>
</tt></pre>
<p>Ou seja, o parâmetro “email” é opcional. Dependendo se passamos ou não esse parâmetro, um dos dois construtores será chamado.</p>
<p>Porém, esse tipo de construção pode começar a ficar extremamente tedioso quando temos muitos parâmetros opcionais. Em Ruby temos algumas maneiras diferentes de lidar com isso. Para começar vejamos uma maneira simples:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">class</span> <span class="cl">Pessoa</span><tt>
</tt>  <span class="r">def</span> <span class="fu">initialize</span>(nome, email = <span class="s"><span class="dl">"</span><span class="dl">"</span></span>)<tt>
</tt>    <span class="iv">@nome</span>, <span class="iv">@email</span> = nome, email<tt>
</tt>  <span class="r">end</span><tt>
</tt><span class="r">end</span></em><tt>
</tt></pre>
<p>Duas novidades: primeiro que um método suporta valores padrão. Dessa forma, se nada for passado no segundo parâmetro, ele assume o padrão vazio &#8220;&#8221;, conforme descrevemos acima. Segundo, é possível fazer atribuição em massa. Acredito que esteja bastante óbvio entender apenas lendo o trecho acima.</p>
<p>Outra maneira:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">class</span> <span class="cl">Pessoa</span><tt>
</tt>  <span class="r">def</span> <span class="fu">initialize</span>(nome, *args)<tt>
</tt>    <span class="iv">@nome</span> = nome<tt>
</tt>    <span class="iv">@args</span> = args<tt>
</tt>  <span class="r">end</span><tt>
</tt>  <span class="r">def</span> <span class="fu">args</span><tt>
</tt>    <span class="iv">@args</span><tt>
</tt>  <span class="r">end</span><tt>
</tt><span class="r">end</span><tt>
</tt><tt>
</tt>&gt;&gt; diego = <span class="co">Pessoa</span>.new(<span class="s"><span class="dl">"</span><span class="k">Diego</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">diego@foo.com.br</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">6666-6666</span><span class="dl">"</span></span>)<tt>
</tt>=&gt; <span class="c">#&lt;Pessoa:0x26ee61c @args=["diego@foo.com.br", "6666-6666"], @nome="Diego"&gt;</span><tt>
</tt>&gt;&gt; diego.args.first<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">diego@foo.com.br</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; diego.args.last<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">6666-6666</span><span class="dl">"</span></span></em><tt>

</tt>O que temos no contrutor acima, o “*”, é o “splat”. Pense nele como um
buraco-negro: depois do parâmetro normal “nome”, tudo que vier depois
será literalmente sugado para dentro da variável “args”. A resultante
disso será um Array. Isso permite um método que tenha capacidade para
infinitos argumentos. Outro exemplo de uso é este:
<em>
<span class="r">def</span> <span class="fu">soma</span>(*args)<tt>
</tt>  args.inject(<span class="i">0</span>) { |elem, total| total += elem }<tt>
</tt><span class="r">end</span><tt>
</tt><tt>
</tt>&gt;&gt; soma(<span class="i">2</span>,<span class="i">2</span>)<tt>
</tt>=&gt; <span class="i">4</span><tt>
</tt>&gt;&gt; soma(<span class="i">1</span>,<span class="i">2</span>,<span class="i">3</span>,<span class="i">4</span>)<tt>
</tt>=&gt; <span class="i">10</span><tt>
</tt>&gt;&gt; soma(<span class="i">100</span>,<span class="i">200</span>,<span class="i">300</span>)<tt>
</tt>=&gt; <span class="i">600</span></em><tt>
</tt></pre>
<p>Felizmente já explicamos para que serve o “inject”. Resumindo: esse método somará todos os elementos passados como parâmetros, independente de quantos forem. E ainda podemos fazer mais: passar um array expandindo seus elementos para serem parâmetros:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; items = [<span class="i">1</span>,<span class="i">2</span>,<span class="i">3</span>,<span class="i">4</span>,<span class="i">5</span>,<span class="i">6</span>]<tt>
</tt>=&gt; [<span class="i">1</span>, <span class="i">2</span>, <span class="i">3</span>, <span class="i">4</span>, <span class="i">5</span>, <span class="i">6</span>]<tt>
</tt>&gt;&gt; soma *items<tt>
</tt>=&gt; <span class="i">21</span></em><tt>

</tt>Se passássemos o array “items” sem o splat para expandí-lo, o array
inteiro seria considerado um único elemento do array “args” dentro do
método, não dando o efeito esperado, veja:

<em>&gt;&gt; soma items<tt>
</tt><span class="co">TypeError</span>: can<span class="s"><span class="dl">'</span><span class="k">t convert Fixnum into Array<tt>
</tt>  from (irb):31:in `+</span><span class="dl">'</span></span><tt>
</tt>  from (irb):<span class="i">31</span><span class="sy">:in</span> <span class="sh"><span class="dl">`</span><span class="k">soma'<tt>
</tt>  from (irb):40:in </span><span class="dl">`</span></span>inject<span class="s"><span class="dl">'</span><span class="k"><tt>
</tt>  from (irb):31:in `each</span><span class="dl">'</span></span><tt>
</tt>  from (irb):<span class="i">31</span><span class="sy">:in</span> <span class="sh"><span class="dl">`</span><span class="k">inject'<tt>
</tt>  from (irb):31:in </span><span class="dl">`</span></span>soma<span class="s"><span class="dl">'</span><span class="k"><tt>
</tt>  from (irb):40</span></span></em></pre>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">Outra situação é quando temos métodos com um número muito grande de
parâmetros opcionais. No Ruby on Rails temos exemplos como este:</pre>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>
&gt;&gt; <span class="co">Person</span>.find <span class="sy">:first</span>, <span class="sy">:conditions</span> =&gt; { <span class="sy">:nome</span> =&gt; <span class="s"><span class="dl">"</span><span class="k">Diego</span><span class="dl">"</span></span> }, <span class="sy"> <img src='http://www.debugando.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> rder</span> =&gt; <span class="sy">:nome</span><tt>
</tt>=&gt; <span class="co">SELECT</span> * <span class="co">FROM</span> <span class="s"><span class="dl">"</span><span class="k">people</span><span class="dl">"</span></span> <span class="co">WHERE</span> (<span class="s"><span class="dl">"</span><span class="k">people</span><span class="dl">"</span></span>.<span class="s"><span class="dl">"</span><span class="k">nome</span><span class="dl">"</span></span> = <span class="s"><span class="dl">'</span><span class="k">Diego</span><span class="dl">'</span></span>) <span class="co">ORDER</span> <span class="co">BY</span> nome <span class="co">LIMIT</span> <span class="i">1</span></em><tt>
</tt></pre>
<p>Qualquer um que já tenha lidado com <span class="caps">SQL</span> sabe que montar consultas pode ser bastante complexo. Criar um único método que cuide disso numa linguagem estático é impossível. Se tentar criar um conjunto de métodos via overloading como vimos antes, também será um trabalho homérico e totalmente fútil.</p>
<p>Vejamos como é definido o método “find” da classe “ActiveRecord::Base”</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>
<span class="r">def</span> <span class="fu">find</span>(*args)<tt>
</tt>  options = args.extract_options!<tt>
</tt>  validate_find_options(options)<tt>
</tt>  set_readonly_option!(options)<tt>
</tt><tt>
</tt>  <span class="r">case</span> args.first<tt>
</tt>    <span class="r">when</span> <span class="sy">:first</span> <span class="r">then</span> find_initial(options)<tt>
</tt>    <span class="r">when</span> <span class="sy">:last</span>  <span class="r">then</span> find_last(options)<tt>
</tt>    <span class="r">when</span> <span class="sy">:all</span>   <span class="r">then</span> find_every(options)<tt>
</tt>    <span class="r">else</span>             find_from_ids(args, options)<tt>
</tt>  <span class="r">end</span><tt>
</tt><span class="r">end</span></em><tt>
</tt></pre>
<p>O método “find” por si só é somente um envelope que chama outros métodos. Ele recebe nada mais, nada menos que um Array, usando o splat como mostramos antes. Logo na primeira linha ele usa um método interno do Rails para extrair tudo que é considerado “options”, no caso, elementos de um Hash.</p>
<p>Dependendo do primeiro argumento, ele repassa o Hash a métodos como “find_initial”, “find_last”, etc. No caso, o Hash em questão é o seguinte:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>options = { <span class="sy">:conditions</span> =&gt; { <span class="sy">:nome</span> =&gt; <span class="s"><span class="dl">"Diego</span><span class="dl">"</span></span> }, <span class="sy"> <img src='http://www.debugando.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> rder</span> =&gt; <span class="sy">:nome</span> }</em><tt>
</tt>
Vejamos um exemplo mais simples de um método com um parâmetro
obrigatório e uma lista de parâmetros opcionais:</pre>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">class</span> <span class="cl">Pessoa</span><tt>
</tt>  attr_accessor <span class="sy">:primeiro_nome</span>, <span class="sy">:sobrenome</span>, <span class="sy">:iniciais</span>, <span class="sy">:email</span><tt>
</tt>  <span class="r">def</span> <span class="fu">initialize</span>(primeiro_nome = <span class="s"><span class="dl">"</span><span class="dl">"</span></span>, options = {})<tt>
</tt>    <span class="iv">@primeiro_nome</span> = primeiro_nome<tt>
</tt>    <span class="iv">@sobrenome</span> = options[<span class="sy">:sobrenome</span>]<tt>
</tt>    <span class="iv">@iniciais</span> = options[<span class="sy">:iniciais</span>]<tt>
</tt>    <span class="iv">@email</span> = options[<span class="sy">:email</span>]<tt>
</tt>  <span class="r">end</span><tt>
</tt><span class="r">end</span><tt>
</tt><tt>
</tt>&gt;&gt; diego = <span class="co">Pessoa</span>.new(<span class="s"><span class="dl">"</span><span class="k">Diego</span><span class="dl">"</span></span>, <span class="sy">:sobrenome</span> =&gt; <span class="s"><span class="dl">"</span><span class="k">Moreira</span><span class="dl">"</span></span>, <span class="sy">:iniciais</span> =&gt; <span class="s"><span class="dl">"</span><span class="k">DM</span><span class="dl">"</span></span>)<tt>
</tt>=&gt; <span class="c">#&lt;Pessoa:0x26b2c98 @iniciais="DM", @sobrenome="Moreira", @email=nil, @primeiro_nome="Diego"&gt;</span><tt>
</tt>&gt;&gt; diego.primeiro_nome<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">Diego</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; diego.sobrenome<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">Moreira</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; diego.iniciais<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">DM</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; diego.email<tt>
</tt>=&gt; <span class="pc">nil</span></em><tt>

</tt>Caso não saiba, o método “attr_accessor” serve para criar métodos
equivalentes a “getters” e “setters” de Java ou C#. Como já falamos em
seções anteriores, classes Ruby podem ser modificadas em tempo de
execução. Veremos isso depois, por enquanto vejamos o construtor
novamente. Depois do primeiro parâmetro, temos o familiar uso do par
chave e valor. O que pode parece estranho é que talvez alguém estivesse
esperando algo assim:

<em>diego = <span class="co">Pessoa</span>.new(<span class="s"><span class="dl">"</span><span class="k">Diego</span><span class="dl">"</span></span>, {<span class="sy">:sobrenome</span> =&gt; <span class="s"><span class="dl">"</span><span class="k">Moreira</span><span class="dl">"</span></span>, <span class="sy">:iniciais</span> =&gt; <span class="s"><span class="dl">"</span><span class="k">DM</span><span class="dl">"</span></span>})</em><tt>
</tt>
Novamente, as chaves “{}” são opcionais: os últimos parâmetros, sendo
pares com a sintaxe de “rocket” (“=&gt;”) são tratados como elementos
do mesmo Hash e todos são “sugados” para o parâmetro “options” no
método construtor. Retirando tudo que é opcional, a chamada poderia
ficar simplesmente assim:

<em>diego = <span class="co">Pessoa</span>.new <span class="s"><span class="dl">"</span><span class="k">Diego</span><span class="dl">"</span></span>, <span class="sy">:sobrenome</span> =&gt; <span class="s"><span class="dl">"</span><span class="k">Moreira</span><span class="dl">"</span></span>, <span class="sy">:iniciais</span> =&gt; <span class="s"><span class="dl">"</span><span class="k">DM</span><span class="dl">"</span></span></em> <tt>
</tt>
E assim temos algumas maneiras para criar métodos bastante flexíveis.
Obviamente, aqui cabe cuidados sobre como planejar seus métodos. Fica
muito fácil criar métodos que fazem mais do que deveriam dessa forma.
Assim como mostramos acima com o método “find” tente criar métodos
enxutos, que delegam a execução a outros métodos mais especializados,
por exemplo.</pre>
<h2>Métodos Dinâmicos</h2>
<p>Vejamos mais sobre o método “attr_accessor”:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">class</span> <span class="cl">Pessoa</span><tt>
</tt>  attr_accessor <span class="sy">:nome</span>, <span class="sy">:email</span><tt>
</tt><span class="r">end</span><tt>
</tt><tt>
</tt>&gt;&gt; diego = <span class="co">Pessoa</span>.new<tt>
</tt>=&gt; <span class="c">#&lt;Pessoa:0x26a6f24 @iniciais=nil, @sobrenome=nil, @email=nil, @primeiro_nome=""&gt;</span><tt>
</tt>&gt;&gt; diego.nome = <span class="s"><span class="dl">"Diego</span><span class="dl">"</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">Diego</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; diego.nome<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">Diego</span><span class="dl">"</span></span></em><tt>

</tt>Podemos reimplementar nossa própria versão simplificada de “attr_accessor” desta maneira:

<em><span class="r">class</span> <span class="cl">Object</span><tt>
</tt>  <span class="r">def</span> <span class="fu">my_accessor</span>( *symbols )<tt>
</tt>    symbols.each <span class="r">do</span> |symbol|<tt>
</tt>      module_eval( <span class="s"><span class="dl">"</span><span class="k">def </span><span class="il"><span class="dl">#{</span>symbol<span class="dl">}</span></span><span class="k">() @</span><span class="il"><span class="dl">#{</span>symbol<span class="dl">}</span></span><span class="k">; end</span><span class="dl">"</span></span> )<tt>
</tt>      module_eval( <span class="s"><span class="dl">"</span><span class="k">def </span><span class="il"><span class="dl">#{</span>symbol<span class="dl">}</span></span><span class="k">=(val) @</span><span class="il"><span class="dl">#{</span>symbol<span class="dl">}</span></span><span class="k"> = val; end</span><span class="dl">"</span></span> )<tt>
</tt>    <span class="r">end</span><tt>
</tt>  <span class="r">end</span><tt>
</tt><span class="r">end</span><tt>
</tt><tt>
</tt><span class="r">class</span> <span class="cl">Pessoa</span><tt>
</tt>  my_accessor <span class="sy">:telefone</span><tt>
</tt><span class="r">end</span><tt>
</tt><tt>
</tt>&gt;&gt; diego = <span class="co">Pessoa</span>.new<tt>
</tt>=&gt; <span class="c">#&lt;Pessoa:0x2690f30 @iniciais=nil, @sobrenome=nil, @email=nil, @primeiro_nome=""&gt;</span><tt>
</tt>&gt;&gt; diego.telefone = <span class="s"><span class="dl">"</span><span class="k">6666-6666</span><span class="dl">"</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">6666-6666</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; diego.telefone<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">6666-6666</span><span class="dl">"</span></span></em><tt>
</tt></pre>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">Abrindo a classe Object significa que nosso método “my_accessor” estará
disponível a qualquer classe do Ruby, já que todos herdam de Object.
Esse método recebe um array de symbols, como já descrevemos antes. Daí
usamos “each” para iterar symbol a symbol, e para cada um chamamos
“module_eval” que simplesmente executa qualquer String passado a ele,
no caso criamos dinamicamente dois métodos, os equivalente a “getter” e
“setter”. Para o exemplo :telefone, seria o mesmo que escrevêssemos:

<em><span class="r">class</span> <span class="cl">Pessoa</span><tt>
</tt>  <span class="r">def</span> <span class="fu">telefone</span>() <span class="iv">@telefone</span>; <span class="r">end</span><tt>
</tt>  <span class="r">def</span> <span class="fu">telefone=</span>(val) <span class="iv">@telefone</span> = val; <span class="r">end</span><tt>
</tt><span class="r">end</span></em><tt>

</tt>Muita gente confunde “meta-programação” com “reflexão”. Reflexão é
apenas perguntar a um objeto o que ele responde. Podemos fazer isso em
Ruby de várias maneiras:

<em>&gt;&gt; a = <span class="s"><span class="dl">"</span><span class="k">string</span><span class="dl">"</span></span><tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">string</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; a.methods<tt>
</tt>=&gt; [<span class="s"><span class="dl">"</span><span class="k">chop!</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">constantize</span><span class="dl">"</span></span>, ... <span class="s"><span class="dl">"</span><span class="k">squish</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">&lt;&lt;</span><span class="dl">"</span></span>]<tt>
</tt>&gt;&gt; a.respond_to? <span class="sy">:size</span><tt>
</tt><tt>
</tt>&gt;&gt; p = <span class="co">Pessoa</span>.new<tt>
</tt>=&gt; <span class="c">#&lt;Pessoa:0x261af60 @iniciais=nil, @sobrenome=nil, @email=nil, @primeiro_nome=""&gt;</span><tt>
</tt>&gt;&gt; p.telefone<tt>
</tt>=&gt; <span class="pc">nil</span><tt>
</tt>&gt;&gt; p.instance_variable_set(<span class="s"><span class="dl">"</span><span class="k">@telefone</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">3333-4444</span><span class="dl">"</span></span>)<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">3333-4444</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; p.instance_variable_get(<span class="s"><span class="dl">"</span><span class="k">@telefone</span><span class="dl">"</span></span>)<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">3333-4444</span><span class="dl">"</span></span></em><tt>
</tt></pre>
<p>Aqui vemos como todo objeto Ruby tem um método chamado “methods” que devolve um Array listando todos os métodos que ele responde. Além disso todo objeto Ruby ainda responde ao método “respond_to?” que recebe um symbol como parâmetro e responde se esse objeto responde a essa mensagem.</p>
<p>No exemplo seguinte, com a classe “Pessoa”, podemos ainda manipular diretamente a variável de instância “@telefone” sem sequer precisar de métodos acessores.</p>
<p>Como podemos ver, Reflexão em Ruby é trivial. Já vimos antes como funciona o método “send” para enviar mensagens arbitrárias e também como implementar o método “method_missing” para fazer um objeto responder a mensagens arbitrárias. Mas com exemplos como do “attr_accessor” podemos entender como manipular o comportamento de um objeto em tempo de execução.</p>
<p>Por isso dizemos que Ruby tem capacidades muito poderosas de meta-programação, que é o que o torna particularmente prazeroso de usar, sem precisar contar com sintaxes obscuras ou truques não documentados. Pensar em meta-programação faz parte do dia-a-dia de programação com Ruby.</p>
<h2>Indo além do Nulo</h2>
<p>Como mais um exemplo da flexibilidade do Ruby, vamos analisar o bom o velho “nulo”. Note que nulo é realmente nada. Não é o mesmo que zero. Não é o mesmo que uma string vazia.</p>
<p>Em Ruby, estamos falando do ‘nil’. Porém, como quase tudo em Ruby é um objeto, assim também é ‘nil’:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; <span class="pc">nil</span><tt>
</tt>=&gt; <span class="pc">nil</span><tt>
</tt>&gt;&gt; <span class="pc">nil</span>.class<tt>
</tt>=&gt; <span class="co">NilClass</span><tt>
</tt>&gt;&gt; <span class="pc">nil</span>.object_id<tt>
</tt>=&gt; <span class="i">4</span></em><tt>
</tt></pre>
<p>Ou seja, quando um método não devolve nada, ou seja, ‘nil’, ainda assim ele está devolvendo alguma coisa: a instância singleton da classe NilClass.</p>
<p>Não é difícil cair em situações onde queremos chamar um método em um objeto onde ainda não sabemos se o objeto é nil ou não. Por isso costumamos fazer algo assim:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">unless</span> obj.nil?<tt>
</tt>  obj.say_hello<tt>
</tt><span class="r">else</span><tt>
</tt>  <span class="pc">nil</span><tt>
</tt><span class="r">end</span></em><tt>

</tt>Aqui eu propositadamente fiz um código mais longo do que deveria,
apenas para aproveitar e demonstrar o “unless”. Pense nele como o
oposto de “if”. Em outras linguagens estamos acostumados a fazer algo
assim:

<em><span class="r">if</span> !obj.nil? ...</em><tt>

</tt>Ou seja, “se não for …”. Mas em vez disso, em Ruby preferimos dizer “a
menos que …”. Fica menos poluído do que colocar “!” ("not") o tempo
todo. Além disso chamamos o método “nil?” que checa se o objeto atual é
nulo ou não. Esse método “nil?” está presente direto da classe pai
“Object”, portanto todos os objetos no Ruby respondem a esse método, em
particular, como “nil” também é um objeto, ele também responde a esse
método:

<em>&gt;&gt; <span class="pc">nil</span>.nil?<tt>
</tt>=&gt; <span class="pc">true</span><tt>
</tt>&gt;&gt; <span class="i">1</span>.nil?<tt>
</tt>=&gt; <span class="pc">false</span></em><tt>
</tt>
E eu disse que o código acima era mais longo do que o necessário porque
sempre podemos usar o operador ternário (que também existe em outras
linguagens):

<em>obj ? obj.say_hello : <span class="pc">nil</span></em><tt>

</tt></pre>
<p>Ou seja, se “obj” devolver “true” (apenas “false” e “nil” respondem como “false” em condicionais), então chame o método “say_hello”, caso contrário, devolva ‘nil’.</p>
<p>Como em qualquer objeto, se tentarmos chamar um método em ‘nil’ que não existe, ele responderá normalmente com uma exceção:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; <span class="pc">nil</span>.size<tt>
</tt><span class="co">NoMethodError</span>: undefined method <span class="sh"><span class="dl">`</span><span class="k">size' for nil:NilClass<tt>
</tt>  from (irb):91</span></span></em></pre>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">Um outro truque que <a href="http://ozmm.org/posts/try.html">discutiu-se</a> algum tempo atrás é criar um novo método em Object chamado “try”:

<em><span class="r">class</span> <span class="cl">Object</span><tt>
</tt>  <span class="r">def</span> <span class="fu">try</span>(metodo, *args)<tt>
</tt>    send(metodo, *args) <span class="r">if</span> respond_to? metodo<tt>
</tt>  <span class="r">end</span><tt>
</tt><span class="r">end</span><tt>
</tt><tt>
</tt>&gt;&gt; <span class="s"><span class="dl">"</span><span class="dl">"</span></span>.try(<span class="sy">:size</span>)<tt>
</tt>=&gt; <span class="i">0</span><tt>
</tt>&gt;&gt; <span class="pc">nil</span>.try(<span class="sy">:size</span>)<tt>
</tt>=&gt; <span class="pc">nil</span></em><tt>
</tt></pre>
<p>Em vez de chamar um método diretamente quando ainda não sabemos se o objeto é nil ou não, podemos chamar o método “try” passando a mensagem (o nome do método) e seus parâmetros. Se o objeto para onde enviamos a mensagem souber responder essa mensagem (respond_to?), então repassamos normalmente, senão devolvemos nil.</p>
<p>Recomendo que teste todos esses exemplos no <span class="caps">IRB</span> para entender o comportamento. Esse tipo de pensamento é crucial na programação Ruby. Não quer dizer, claro, que agora devemos usar coisas como “try” o tempo todo, mas nas situações onde são necessárias, essa pode ser a diferença entre um código extremamente enxuto e expressivo do que um código burocrático e difícil de entender.</p>
<h3>Conclusão</h3>
<p>Até aqui mostramos apenas a ponta do iceberg da programação com Ruby. Existem dezenas de classes que já vêm na biblioteca padrão do Ruby que vocês precisam saber, como Net, File, FileUtils e muitos outros. Use o site <a href="http://apidock.com/">ApiDock</a> sempre que tiver dúvidas quanto à sintaxe de algum método. Lembre-se da questão de parâmetros dinâmicos, o que dificulta a documentação automática. Mas também lembre-se que o código-fonte de bibliotecas Ruby costumam ser muito simples de ler. Portanto recomendo muito que, na dúvida, procure o código-fonte (que já está na sua máquina) e tente ler direto na fonte.</p>
<p>E para ver alguns exemplos muito interessantes de resolução de problemas em Ruby, também recomendo ler o site <a href="http://rubyquiz.com/">Ruby Quiz</a> que contém uma biblioteca enorme de pequenos problemas simples com soluções muito criativas usando os recursos de Ruby.</p>
<p>O mais importante: não tente escrever Ruby da mesma forma como se escreve Java ou C#. <em>“Quando se está em Roma, faça como os romanos.”</em> Portanto, nada de usar “camelCasing” para nomear seus métodos, por exemplo, use “metodos_separados_por_underscore”. Escreva Ruby da forma Ruby.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.debugando.com/micro-tutorial-de-ruby-parte-iii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Busca fácil on Rails</title>
		<link>http://www.debugando.com/busca-facil-on-rails/</link>
		<comments>http://www.debugando.com/busca-facil-on-rails/#comments</comments>
		<pubDate>Thu, 18 Dec 2008 11:47:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[busca]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.debugando.com/?p=260</guid>
		<description><![CDATA[Após algumas buscas e testes encontrei um projeto chamado Searchlogic. A primeira impressão foi muito boa: de cara já vejo o projeto com uma ampla documentação disponível. Bastaram algumas linhas de código para conseguir o que eu queria!
Com base nesse resultado positivo, resolvi compartilhar aqui a minha experiência fazendo uma pequena explicação sobre como integrar [...]]]></description>
			<content:encoded><![CDATA[<p>Após algumas buscas e testes encontrei um projeto chamado <a href="http://searchlogic.rubyforge.org/">Searchlogic</a>. A primeira impressão foi muito boa: de cara já vejo o projeto com uma ampla documentação disponível. Bastaram algumas linhas de código para conseguir o que eu queria!</p>
<p>Com base nesse resultado positivo, resolvi compartilhar aqui a minha experiência fazendo uma pequena explicação sobre como integrar o Searchlogic ao seu site.</p>
<p><strong>Passo 1</strong>: Instalação do Searchlogic: Você pode fazer a instalação usando o <a href="http://rubyforge.org/projects/rubygems/">RubyGems</a> ou instalando com um plugin dentro do seu projeto.</p>
<p>Instalação como gem:</p>
<pre class="bash"><code><em>sudo gem install searchlogic</em>

<span class="re3"># e depois adicione ao config/environment.rb</span>
<em>config.gem <span class="st0">"searchlogic"</span> </em></code></pre>
<p>Instalação como plugin:</p>
<pre class="bash"><em><code>script/plugin install git://github.com/binarylogic/searchlogic.git</code></em></pre>
<p><strong>Passo 2</strong>: Faça a busca! É isso mesmo, já está “tudo no jeito” para você fazer a sua busca. Uma busca simples seria:</p>
<pre class="rails"><em><code><span class="re1">@search</span> = Model.<span class="me1">new_search</span><span class="br0">(</span> params<span class="br0">[</span><span class="re3">:q</span><span class="br0">]</span> <span class="br0">)</span>
<span class="re1">@items</span>, <span class="re1">@items_count</span> = <span class="re1">@search</span>.<span class="me1">all</span>, <span class="re1">@search</span>.<span class="kw5">count</span></code></em></pre>
<p>O que esse código faz é buscar registros a partir do seu modelo (<em>Model</em> no exemplo) e colocar o resultado em duas variáveis: uma com a coleção de registros e outra com a quantidade retornada. Mais fácil impossível.</p>
<p><strong>Passo 3</strong>: Personalizando sua busca: se você quiser, e você provavelmente quer, você pode especificar quais campos devem ser pesquisados ou quais as condições devem ser atendidas. Tudo isso é muito simples de ser feito e pode ser definido de duas formas: você pode usar um <em>hash</em> com as opções e condições (similar ao que fazemos com o tradicional <em>find</em>) ou uma abordagem mais orientada a objetos. Exemplos simulando uma busca de carros:</p>
<p>Passando um hash:</p>
<pre class="rails"><em><code>Car.<span class="me1">all</span><span class="br0">(</span>
  <span class="re3">:conditions</span> =&gt; <span class="br0">{</span>
    <span class="re3">:name_contains</span> =&gt; <span class="st0">'ford'</span>, <span class="co1"># name like '%ford%'</span>
  <span class="br0">}</span>,
  <span class="re3">:per_page</span> =&gt; <span class="nu0">10</span>
  <span class="re3">:page</span> =&gt; params<span class="br0">[</span><span class="re3">:page</span><span class="br0">]</span>,
  <span class="re3"> <img src='http://www.debugando.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> rder_by</span> =&gt; <span class="st0">'year'</span>,
  <span class="re3"> <img src='http://www.debugando.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> rder_as</span> =&gt; <span class="st0">'DESC'</span>,
<span class="br0">)</span></code></em></pre>
<p>Ou como um objeto:</p>
<pre class="rails"><em><code>search = Car.<span class="me1">new_search</span>
search.<span class="me1">conditions</span>.<span class="me1">name_contains</span> = <span class="st0">'ford'</span>
search.<span class="me1">per_page</span> = <span class="nu0">10</span>
search.<span class="me1">page</span> = params<span class="br0">[</span><span class="re3">:page</span><span class="br0">]</span>
search.<span class="me1">order_by</span> = <span class="st0">'year'</span>
search.<span class="me1">order_as</span> = <span class="st0">'DESC'</span>
search.<span class="me1">all</span> <span class="co1"># execute</span></code></em></pre>
<p>Simples não? E isso é só o começo, na <a href="http://searchlogic.rubyforge.org/">documentação do projeto</a> há muitos outros exemplos e possibilidades!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.debugando.com/busca-facil-on-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Micro-Tutorial de Ruby &#8211; Parte II</title>
		<link>http://www.debugando.com/micro-tutorial-de-ruby-parte-ii/</link>
		<comments>http://www.debugando.com/micro-tutorial-de-ruby-parte-ii/#comments</comments>
		<pubDate>Wed, 10 Dec 2008 16:43:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.debugando.com/?p=179</guid>
		<description><![CDATA[Para quem quer aprender Ruby com material em português tem três opções: Aprenda a Programar que foi um esforço de tradução da comunidade Brasileira, é um livro bem mais básico para quem sequer tem treinamento em programação. Também tem o Why’s Poignant Guide to Ruby que é outro esforço coletivo de tradução da nossa comunidade, [...]]]></description>
			<content:encoded><![CDATA[<p>Para quem quer aprender Ruby com material em português tem três opções: <a href="http://aprendaaprogramar.rubyonrails.pro.br/">Aprenda a Programar</a> que foi um esforço de tradução da comunidade Brasileira, é um livro bem mais básico para quem sequer tem treinamento em programação. Também tem o <a href="http://github.com/carlosbrando/poignant-br/tree/master">Why’s Poignant Guide to Ruby</a> que é outro esforço coletivo de tradução da nossa comunidade, liderada pelo Carlos Brando. O livro do Why é um grande clássico da literatura de Ruby. O TaQ também tem um <span class="caps">PDF</span> disponível para <a href="http://eustaquiorangel.com/downloads/tutorialruby.pdf">download</a>.</p>
<h2>Métodos vs Mensagens</h2>
<p>Na seção anterior vimos como podemos organizar nosso código em módulos e durante os exemplos usamos um método estranho, o “send”. Vamos ver para que ele serve de fato.</p>
<p>Outra noção que precisamos mudar aqui: <em>“nós chamamos métodos dos objetos.”</em> Em orientação a objetos, na realidade deveria ser <em>“nós enviamos mensagens aos objetos.”</em> Por exemplo:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; <span class="s"><span class="dl">"</span><span class="k">teste</span><span class="dl">"</span></span>.hello<tt>
</tt><span class="co">NoMethodError</span>: undefined method <span class="sh"><span class="dl">`</span><span class="k">hello' for "teste":String<tt>
</tt>  from (irb):1

</span></span></em></pre>
<p>O pensamento comum seria: <em>“tentamos chamar o método ‘hello’ que não existe em String.”</em> Mas devemos pensar assim: <em>“tentamos enviar a mensagem ‘hello’ ao objeto e sua resposta padrão é que ele não sabe responder a essa mensagem.”</em></p>
<p>Podemos reescrever o mesmo comportamento acima da seguinte forma:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; <span class="s"><span class="dl">"</span><span class="k">teste</span><span class="dl">"</span></span>.send(<span class="sy">:hello</span>)<tt>
</tt><span class="co">NoMethodError</span>: undefined method <span class="sh"><span class="dl">`</span><span class="k">hello' for "teste":String<tt>
</tt>  from (irb):22:in </span><span class="dl">`</span></span>send<span class="s"><span class="dl">'</span><span class="k"><tt>
</tt>  from (irb):22

</span></span></em>Outro exemplo de ‘envio de mensagens’:

<em>&gt;&gt; <span class="s"><span class="dl">"</span><span class="k">teste</span><span class="dl">"</span></span>.diga(<span class="s"><span class="dl">"</span><span class="k">Fabio</span><span class="dl">"</span></span>)<tt>
</tt><span class="co">NoMethodError</span>: undefined method <span class="sh"><span class="dl">`</span><span class="k">diga' for "teste":String<tt>
</tt>  from (irb):24<tt>
</tt>  <tt>
</tt>&gt;&gt; "teste".send(:diga, "Fabio")<tt>
</tt>NoMethodError: undefined method </span><span class="dl">`</span></span>diga<span class="s"><span class="dl">'</span><span class="k"> for "teste":String<tt>
</tt>  from (irb):25:in `send</span><span class="dl">'</span></span><tt>
</tt>  from (irb):<span class="i">25</span></em><tt>
</tt></pre>
<p>Está entendendo o padrão? O equivalente a <em>‘chamar um método’</em> é como se estivéssemos chamando o método ‘send’ onde o primeiro parâmetro é o ‘nome do método’ e a seguir uma lista (de tamanho arbitrário) de parâmetros. Numa linguagem tradicional, uma vez que a classe é definida, o contrato está fechado. Mas como vimos antes, em Ruby, nada é fechado. No caso, tentamos enviar uma mensagem chamada :diga e :hello que o String “teste” não sabe como responder. A resposta padrão é enviar uma exceção ‘NoMethodError’ indicando o erro.</p>
<p>Podemos resolver esse problema de duas formas: 1) reabrindo a classe String e definindo um método chamado ‘hello’ ou ‘diga’ ou 2) fazer com que a String receba qualquer mensagem, independente se existe um método para responder a ela ou não.</p>
<p>Nesse segundo caso, poderíamos fazer o seguinte:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">class</span> <span class="cl">String</span><tt>
</tt>  <span class="r">def</span> <span class="fu">method_missing</span>(metodo, *args)<tt>
</tt>    puts <span class="s"><span class="dl">"</span><span class="k">Nao conheco o metodo </span><span class="il"><span class="dl">#{</span>metodo<span class="dl">}</span></span><span class="k">. Os argumentos foram:</span><span class="dl">"</span></span><tt>
</tt>    args.each { |arg| puts arg }<tt>
</tt>  <span class="r">end</span><tt>
</tt><span class="r">end</span></em><tt>

</tt>Antes de explicar, vejamos agora como o String “teste” vai se comportar:

<em>&gt;&gt; <span class="s"><span class="dl">"</span><span class="k">teste</span><span class="dl">"</span></span>.hello<tt>
</tt><span class="co">Nao</span> conheco o metodo hello. <span class="co">Os</span> argumentos foram:<tt>
</tt>=&gt; []<tt>
</tt><tt>
</tt>&gt;&gt; <span class="s"><span class="dl">"</span><span class="k">teste</span><span class="dl">"</span></span>.diga(<span class="s"><span class="dl">"</span><span class="k">Fabio</span><span class="dl">"</span></span>)<tt>
</tt><span class="co">Nao</span> conheco o metodo diga. <span class="co">Os</span> argumentos foram:<tt>
</tt><span class="co">Fabio</span><tt>
</tt>=&gt; [<span class="s"><span class="dl">"</span><span class="k">Fabio</span><span class="dl">"</span></span>]<tt>
</tt><tt>
</tt>&gt;&gt; <span class="s"><span class="dl">"</span><span class="k">teste</span><span class="dl">"</span></span>.blabla(<span class="i">1</span>,<span class="i">2</span>,<span class="i">3</span>)<tt>
</tt><span class="co">Nao</span> conheco o metodo blabla. <span class="co">Os</span> argumentos foram:<tt>
</tt><span class="i">1</span><tt>
</tt><span class="i">2</span><tt>
</tt><span class="i">3</span><tt>
</tt>=&gt; [<span class="i">1</span>, <span class="i">2</span>, <span class="i">3</span>]</em><tt>
</tt></pre>
<p>Se você pensar em <em>“chamar métodos”</em> o que estamos fazendo acima parece muito estranho pois estaríamos <em>“chamando métodos que não existem”</em>. Mas se mudar o ponto de vista para <em>“enviar mensagens a objetos”</em> agora temos <em>“objetos que respondem a qualquer mensagem”</em>.</p>
<p>Outra coisa que é meio polêmico são métodos privados. Em Ruby podemos fazer assim:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">class</span> <span class="cl">Teste</span><tt>
</tt>  private<tt>
</tt>  <span class="r">def</span> <span class="fu">alo</span><tt>
</tt>     <span class="s"><span class="dl">"</span><span class="k">alo</span><span class="dl">"</span></span><tt>
</tt>  <span class="r">end</span><tt>
</tt><span class="r">end</span><tt>
</tt><tt>
</tt>&gt;&gt; <span class="co">Teste</span>.new.alo<tt>
</tt><span class="co">NoMethodError</span>: private method <span class="sh"><span class="dl">`</span><span class="k">alo' called for #&lt;Teste:0x17d3b3c&gt;<tt>
</tt>  from (irb):47<tt>
</tt><tt>
</tt>&gt;&gt; Teste.new.send(:alo)<tt>
</tt>=&gt; "alo"</span></span></em></pre>
<p>Essa classe ‘Foo’ tem um método privado (tudo que vem depois de ’private’). A primeira tentativa de chamar o método “alo” falha, obviamente, por ser um método privado. Mas a segunda tentativa, usando “send” é bem sucedido! Na realidade “private” serve para indicar que não deveríamos estar acessando determinado método, mas Ruby não nos força a não conseguir. Se nós realmente quisermos, temos que explicitamente usar “send”, mas aí nós estamos conscientemente fazendo algo que “não deveríamos”. Ruby não é paternalista: é feita para quem sabe o que está fazendo.</p>
<p>Por isso no artigo anterior usamos Pessoa.send(:include, MeusPatches), porque “include” é um método privado que só deveria ser usado dentro da própria classe. Mas esse “pattern” costuma funcionar.</p>
<p>Talvez o melhor exemplo para demonstrar esta funcionalidade dinâmica é mostrando o <span class="caps">XML</span> Builder. Primeiro, instale a gem:</p>
<pre><code><em>gem install builder</em>
</code></pre>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">Agora podemos usar no <span class="caps">IRB</span>:</pre>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; require <span class="s"><span class="dl">'</span><span class="k">rubygems</span><span class="dl">'</span></span><tt>
</tt>&gt;&gt; require <span class="s"><span class="dl">'</span><span class="k">builder</span><span class="dl">'</span></span><tt>
</tt>=&gt; <span class="pc">false</span><tt>
</tt>&gt;&gt; x = <span class="co">Builder</span>::<span class="co">XmlMarkup</span>.new(<span class="sy">:target</span> =&gt; <span class="gv">$stdout</span>, <span class="sy">:indent</span> =&gt; <span class="i">1</span>)<tt>
</tt>&lt;inspect/&gt;<tt>
</tt>=&gt; <span class="c">#&lt;IO:0x12b7cc&gt;</span><tt>
</tt>&gt;&gt; x.instruct!<tt>
</tt>&lt;<span class="i">?x</span>ml version=<span class="s"><span class="dl">"</span><span class="k">1.0</span><span class="dl">"</span></span> encoding=<span class="s"><span class="dl">"</span><span class="k">UTF-8</span><span class="dl">"</span></span>?&gt;<tt>
</tt>=&gt; <span class="c">#&lt;IO:0x12b7cc&gt;</span><tt>
</tt>&gt;&gt; x.pessoa <span class="r">do</span> |p|<tt>
</tt><span class="i">?&gt;</span>     p.nome <span class="s"><span class="dl">"</span><span class="k">Fabio Akita</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt;     p.email <span class="s"><span class="dl">"</span><span class="k">fabioakita@gmail.com</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt;     p.telefones <span class="r">do</span> |t|<tt>
</tt><span class="i">?&gt;</span>       t.casa <span class="s"><span class="dl">"</span><span class="k">6666-8888</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt;       t.trabalho <span class="s"><span class="dl">"</span><span class="k">2222-3333</span><span class="dl">"</span></span><tt>
</tt>&gt;&gt;     <span class="r">end</span><tt>
</tt>&gt;&gt;   <span class="r">end</span><tt>
</tt>&lt;pessoa&gt;<tt>
</tt> &lt;nome&gt;<span class="co">Fabio</span> <span class="co">Akita</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">nome&gt;<tt>
</tt> &lt;email&gt;fabioakita@gmail.com&lt;</span><span class="dl">/</span><span class="mod">em</span></span>ail&gt;<tt>
</tt> &lt;telefones&gt;<tt>
</tt>  &lt;casa&gt;<span class="i">6666</span><span class="i">-8888</span>&lt;<span class="rx"><span class="dl">/</span><span class="k">casa&gt;<tt>
</tt>  &lt;trabalho&gt;2222-3333&lt;</span><span class="dl">/</span></span>trabalho&gt;<tt>
</tt> &lt;<span class="rx"><span class="dl">/</span><span class="k">telefones&gt;<tt>
</tt>&lt;</span><span class="dl">/</span></span>pessoa&gt;<tt>
</tt>=&gt; <span class="c">#&lt;IO:0x12b7cc&gt;</span></em><tt>
</tt>Como podem ver, instanciamos a classe XmlMarkup na variável “x”. Daí
passamos a enviar mensagens como “pessoa” ou “email” e ele gera os tags
<span class="caps">XML</span> adequadamente. Muito diferente do que teríamos que fazer do jeito tradicional:
<em>
import org.w3c.dom.*;<tt>
</tt>import javax.xml.parsers.*; <tt>
</tt>import javax.xml.transform.*; <tt>
</tt><tt>
</tt>class CreateDomXml <tt>
</tt>{<tt>
</tt>  public static void main(String[] args) <tt>
</tt>  {<tt>
</tt>    try{<tt>
</tt>      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();<tt>
</tt>      DocumentBuilder docBuilder = factory.newDocumentBuilder();<tt>
</tt>      Document doc = docBuilder.newDocument();<tt>
</tt>      <tt>
</tt>      Element root = doc.createElement("pessoa");<tt>
</tt>      doc.appendChild(root);<tt>
</tt>      <tt>
</tt>      Element childElement = doc.createElement("nome");<tt>
</tt>      childElement.setValue("Fabio Akita");<tt>
</tt>      root.appendChild(childElement);<tt>
</tt>      <tt>
</tt>      childElement = doc.createElement("email");<tt>
</tt>      childElement.setValue("fabioakita@gmail.com");<tt>
</tt>      root.appendChild(childElement);<tt>
</tt>      .....<tt>
</tt>    } catch(Exception e) {<tt>
</tt>      System.out.println(e.getMessage());<tt>
</tt>    }<tt>
</tt>  }<tt>
</tt>}<tt>
</tt></em></pre>
<p>Note que este código sequer está completo pois seria comprido demais para mostrar aqui. A idéia toda de usar os conceitos de <strong>meta-programação</strong>, de redefinição dinâmica de comportamento do objeto, é de permitir que você nunca precise fazer mais código do que realmente necessário. Na versão Ruby, temos no máximo a mesma quantidade de linhas que o <span class="caps">XML</span> resultante, graças à capacidade de ter um método ‘method_missing’ que consegue definir dinamicamente o que fazer com cada nova mensagem inesperada.</p>
<h2>Higher Order Functions e Blocos</h2>
<p>Vejamos o Design Pattern chamado Command:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>interface <span class="co">Command</span> {<tt>
</tt>  public void execute();<tt>
</tt>}<tt>
</tt><tt>
</tt><span class="r">class</span> <span class="cl">Button</span> {<tt>
</tt>  <span class="co">Command</span> action;<tt>
</tt>  public void setCommand(<span class="co">Command</span> action) {<tt>
</tt>    this.action = action;<tt>
</tt>  }<tt>
</tt>  public void click() {<tt>
</tt>    this.action.execute();  <tt>
</tt>  }<tt>
</tt>}<tt>
</tt><tt>
</tt><span class="co">Button</span> myButton = new Button();<tt>
</tt>myButton.setCommand(new Command() {<tt>
</tt>  public void execute() {<tt>
</tt>    <span class="co">System</span>.out.println(<span class="s"><span class="dl">"</span><span class="k">Clicked!!</span><span class="dl">"</span></span>);<tt>
</tt>  }<tt>
</tt>});</em><tt>
</tt></pre>
<p>O que está acontecendo aqui é o seguinte: Criamos uma interface com um único método chamado ‘execute’. Daí criamos uma classe ‘Button’ onde podemos configurar que ação cada instância dele executará ao ser clicado. Essa ação é uma instância de um objeto que implementa Command. No final, criamos uma instância de Button e uma classe anônima (sem nome) com a implementação do método ‘execute’ para aquela instância.</p>
<p>Vejamos o mesmo exemplo do Design Pattern Command em Ruby (um dos vários jeitos de implementar):</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">class</span> <span class="cl">Button</span><tt>
</tt>  <span class="r">def</span> <span class="fu">initialize</span>(&amp;block)<tt>
</tt>    <span class="iv">@block</span> = block<tt>
</tt>  <span class="r">end</span><tt>
</tt>  <span class="r">def</span> <span class="fu">click</span><tt>
</tt>    <span class="iv">@block</span>.call<tt>
</tt>  <span class="r">end</span><tt>
</tt><span class="r">end</span><tt>
</tt><tt>
</tt>my_button = <span class="co">Button</span>.new { puts <span class="s"><span class="dl">"</span><span class="k">Clicked!!</span><span class="dl">"</span></span> }<tt>
</tt>my_button.click</em><tt>
</tt></pre>
<p>Primeiro, claro, bem mais curto, mas o mais importante: não precisamos encapsular uma ação como método de uma classe. Em linguagens tradicionais que não tem o conceito de “funções como cidadãos de primeira classe”, precisamos encapsular qualquer coisa em classes, mesmo que sejam classes anônimas.</p>
<p>No Ruby, temos o conceito de “código como objeto”. Na realidade encapsulamos o código diretamente em um objeto. No exemplo acima, o construtor ‘initialize’ captura qualquer bloco de código que passarmos a ele dentro da variável ‘block’ (para isso serve o “&amp;”). Daí quando instanciamos o parâmetro que passamos entre chaves {} é o bloco de código capturado como objeto e associado à variável ‘block’.</p>
<p>A partir daí ele fica armazenado como uma variável de instância “@block” e no método ‘click’ podemos executar esse bloco de código enviando a mensagem ‘call’ (afinal, ele é um objeto e, portanto, responde a métodos).</p>
<p>Vejamos um exemplo mais simples:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; <span class="r">def</span> <span class="fu">diga_algo</span>(nome)<tt>
</tt>&gt;&gt;   <span class="r">yield</span>(nome)<tt>
</tt>&gt;&gt; <span class="r">end</span><tt>
</tt>=&gt; <span class="pc">nil</span><tt>
</tt><tt>
</tt>&gt;&gt; diga_algo(<span class="s"><span class="dl">"</span><span class="k">Fabio</span><span class="dl">"</span></span>) { |nome| puts <span class="s"><span class="dl">"</span><span class="k">Hello, </span><span class="il"><span class="dl">#{</span>nome<span class="dl">}</span></span><span class="dl">"</span></span> }<tt>
</tt><span class="co">Hello</span>, <span class="co">Fabio</span><tt>
</tt>=&gt; <span class="pc">nil</span><tt>
</tt><tt>
</tt>&gt;&gt; diga_algo(<span class="s"><span class="dl">"</span><span class="k">Akita</span><span class="dl">"</span></span>) { |nome| puts <span class="s"><span class="dl">"</span><span class="k">Hello, </span><span class="il"><span class="dl">#{</span>nome<span class="dl">}</span></span><span class="dl">"</span></span> }<tt>
</tt><span class="co">Hello</span>, <span class="co">Akita</span><tt>
</tt>=&gt; <span class="pc">nil</span></em><tt>
</tt></pre>
<p>Agora complicou: primeiro definimos um método chamado ‘diga_algo’ que recebe apenas um parâmetro. Dentro do método chamamos o comando especial ‘yield’, passando o parâmetro recebido a ele. Esse comando ‘yield’ executa qualquer bloco que foi passado como último parâmetro à chamada do método. É como se o método ‘diga_algo’ tivesse um segundo parâmetro implícito – digamos, ‘&amp;b’ – e ‘yield(nome)’ fosse a mesma coisa que chamar ‘b.call(nome)’.</p>
<p>Preste atenção neste trecho:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>{ |nome| puts <span class="s"><span class="dl">"</span><span class="k">Hello, </span><span class="il"><span class="dl">#{</span>nome<span class="dl">}</span></span><span class="dl">"</span></span> }</em></pre>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">Pense nisso como se fosse uma função anônima: o que está entre pipes
“||” são parâmetros dessa função. O ‘yield’ irá executar esse bloco de
código. Por acaso, ele passará o parâmetro ‘nome’ para dentro do bloco
Vejamos outro exemplo:</pre>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; soma = lambda { |a, b| a + b }<tt>
</tt>=&gt; <span class="c">#&lt;Proc:0x012d4898@(irb):46&gt;</span><tt>
</tt>&gt;&gt; soma.call(<span class="i">1</span>,<span class="i">2</span>)<tt>
</tt>=&gt; <span class="i">3</span><tt>
</tt>&gt;&gt; soma.call(<span class="i">4</span>,<span class="i">4</span>)<tt>
</tt>=&gt; <span class="i">8</span></em><tt>
</tt></pre>
<p>O comando ‘lambda’ serve para capturar o bloco de código numa instância da classe Proc. No exemplo, esse bloco aceita dois parâmetros, “a” e “b” e faz a soma deles. Depois podemos pegar o objeto ‘soma’ e chamar o método ‘call’ passando os dois parâmetros que ele requer.</p>
<p>No Ruby 1.8, um bloco também é uma <strong>Closure</strong> (&#8220;Fechamento&#8221;). Ou seja, o bloco de código engloba o ambiente ao seu redor, incluindo variáveis fora do bloco. Por exemplo:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; <span class="r">def</span> <span class="fu">criar_bloco</span>(nome)<tt>
</tt>&gt;&gt;   lambda { puts <span class="s"><span class="dl">"</span><span class="k">Hello </span><span class="il"><span class="dl">#{</span>nome<span class="dl">}</span></span><span class="dl">"</span></span>}<tt>
</tt>&gt;&gt; <span class="r">end</span><tt>
</tt>=&gt; <span class="pc">nil</span><tt>
</tt>&gt;&gt; <tt>
</tt><span class="i">?&gt;</span> fabio = criar_bloco(<span class="s"><span class="dl">"</span><span class="k">Fabio</span><span class="dl">"</span></span>)<tt>
</tt>=&gt; <span class="c">#&lt;Proc:0x0124aae4@(irb):59&gt;</span><tt>
</tt>&gt;&gt; akita = criar_bloco(<span class="s"><span class="dl">"</span><span class="k">Akita</span><span class="dl">"</span></span>)<tt>
</tt>=&gt; <span class="c">#&lt;Proc:0x0124aae4@(irb):59&gt;</span></em><tt>
</tt></pre>
<p>O método ‘criar_bloco’ retorna um novo bloco de código. Note que o método recebe o parâmetro ‘nome’ e daí criamos o novo lambda usando esse ‘nome’ dentro dele. Finalmente chamamos o método duas vezes, criando dois lambdas diferentes, passando dois parâmetros diferentes a ‘nome’.</p>
<p>Agora vamos executar esses blocos:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; fabio.call<tt>
</tt><span class="co">Hello</span> <span class="co">Fabio</span><tt>
</tt>=&gt; <span class="pc">nil</span><tt>
</tt><tt>
</tt>&gt;&gt; akita.call<tt>
</tt><span class="co">Hello</span> <span class="co">Akita</span><tt>
</tt>=&gt; <span class="pc">nil</span><tt>
</tt><tt>
</tt>&gt;&gt; fabio.call<tt>
</tt><span class="co">Hello</span> <span class="co">Fabio</span><tt>
</tt>=&gt; <span class="pc">nil</span></em><tt>
</tt></pre>
<p>Veja que o bloco <strong>reteve</strong> o conteúdo do parâmetro ‘nome’ que foi passado como argumento ao método ‘criar_bloco’. Cada um dos blocos reteve o parâmetro, e como os configuramos com conteúdos diferentes, ao serem executados eles tem comportamentos diferentes. Esse conceito de <strong>Fechamento</strong> é um pouco complicado da primeira vez, por isso se você pelo menos entendeu que existem blocos e que eles são encapsulados em objetos anônimos que chamamos de <strong>lambdas</strong>, por enquanto é o suficiente.</p>
<p>Mas mais do que isso, você viu como métodos Ruby conseguem receber blocos de código e devolver blocos de código. É a isso que chamamos de <a href="http://en.wikipedia.org/wiki/Higher-order_function">Higher Order Functions</a>, ou seja, uma ‘função’ (que chamamos de ‘bloco de código’) pode ser recebido ou repassado como se fosse uma variável qualquer. Isso é muito importante para categorizar Ruby como uma linguagem ‘inspirada em linguagens funcionais’, como Lisp. No caso, lambdas de Ruby não são livres de efeitos-colaterais, por isso ela não pode ser considerada puramente funcional. Mas isso já auxilia em muitas operações e é uma maneira bem mais eficiente inclusive de encapsular funcionalidades.</p>
<p>Vejamos outro exemplo de código para ler arquivos, começando por Java:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>StringBuilder contents = new StringBuilder();<tt>
</tt>    <tt>
</tt>try {<tt>
</tt>  BufferedReader input =  new BufferedReader(<tt>
</tt>    new FileReader(aFile));<tt>
</tt>  try {<tt>
</tt>    String line = null; <tt>
</tt>    while (( line = input.readLine()) != null){<tt>
</tt>      contents.append(line);<tt>
</tt>      contents.append(<tt>
</tt>        System.getProperty("line.separator"));<tt>
</tt>    }<tt>
</tt>  }<tt>
</tt>  finally {<tt>
</tt>    input.close();<tt>
</tt>  }<tt>
</tt>}<tt>
</tt>catch (IOException ex){<tt>
</tt>  ex.printStackTrace();<tt>
</tt>}</em><tt>

</tt>Algo parecido, de forma literal, em Ruby, ficaria assim:</pre>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>contents = <span class="s"><span class="dl">"</span><span class="dl">"</span></span><tt>
</tt><span class="r">begin</span><tt>
</tt>  input = <span class="co">File</span>.open(aFile, <span class="s"><span class="dl">"</span><span class="k">r</span><span class="dl">"</span></span>)<tt>
</tt>  <span class="r">begin</span><tt>
</tt>    <span class="r">while</span> line = input.gets<tt>
</tt>      contents &lt;&lt; line<tt>
</tt>      contents &lt;&lt; <span class="s"><span class="dl">"</span><span class="ch">\n</span><span class="dl">"</span></span><tt>
</tt>    <span class="r">end</span><tt>
</tt>  <span class="r">ensure</span><tt>
</tt>    input.close<tt>
</tt>  <span class="r">end</span><tt>
</tt><span class="r">rescue</span> e<tt>
</tt>  puts e<tt>
</tt><span class="r">end</span></em><tt>
</tt></pre>
<p>Nada muito diferente, sequer em número de linhas. Porém, se considerarmos o caso de uso <em>“abrir um arquivo e processar seu conteúdo”</em>, todo esse código lida com o fato de abrir o arquivo, garantir que ele seja fechado, tratar exceções. O trecho específico de <em>“processar o conteúdo”</em> é nada mais do que as 4 linhas do bloco ‘while’. Podemos tornar isso mais <em>Rubista</em> criando um novo método ‘open’, que usa o recurso de ‘yield’ que mostramos acima.</p>
<p>Felizmente o Ruby já implementa o método ‘open’ da classe ‘File’ dessa forma, por isso podemos re-escrever o trecho de código acima assim:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>contents = <span class="s"><span class="dl">"</span><span class="dl">"</span></span><tt>
</tt><span class="co">File</span>.open(aFile, <span class="s"><span class="dl">"</span><span class="k">r</span><span class="dl">"</span></span>) <span class="r">do</span> |input|<tt>
</tt>  <span class="r">while</span> line = input.gets<tt>
</tt>    contents &lt;&lt; line<tt>
</tt>    contents &lt;&lt; <span class="s"><span class="dl">"</span><span class="ch">\n</span><span class="dl">"</span></span><tt>
</tt>  <span class="r">end</span><tt>
</tt><span class="r">end</span></em><tt>
</tt>Um pouco melhor, bem mais encapsulado, expondo apenas o que é realmente
essencial ao que queremos fazer. Olhando para este trecho sabemos
exatamente que queremos abrir um arquivo e processar linha a linha de
seu conteúdo, armazenando o resultado na variável ‘contents’. Todo o
resto do <em>encanamento</em> está escondido dentro do método ‘open’.
Podemos passar apenas o bloco do ‘while’ como um lambda e ele será
executado no meio da implementação desse método. Se fôssemos
reimplementar o método ‘open’ da classe ‘File’ para agir dessa forma,
poderíamos fazer assim:</pre>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">class</span> <span class="cl">File</span> <tt>
</tt>  <span class="r">def</span> <span class="co">File</span>.open(*args) <tt>
</tt>    result = f = <span class="co">File</span>.new(*args) <tt>
</tt>    <span class="r">if</span> block_given? <tt>
</tt>      <span class="r">begin</span> <tt>
</tt>        result = <span class="r">yield</span> f <tt>
</tt>      <span class="r">ensure</span> <tt>
</tt>        f.close <tt>
</tt>      <span class="r">end</span> <tt>
</tt>    <span class="r">end</span> <tt>
</tt>    <span class="r">return</span> result <tt>
</tt>  <span class="r">end</span> <tt>
</tt><span class="r">end</span></em> <tt>
</tt></pre>
<p>Aqui, simulamos a reabertura da classe ‘File’ e a reimplementação do método ‘open’. Note que primeiro checamos se foi passado um bloco (‘block_given?’) e daí usamos ‘yield’ para executar o lambda passado a ele, daí repassamos o arquivo ‘f’ recém-aberto. Quando seja lá o que ‘yield’ executar terminar, daí fechamos o arquivo e retornamos.</p>
<p>Aliás, é exatamente assim que os <strong>iteradores</strong> funcionam em Ruby. Um iterador serve para navegar pelos vários elementos de uma lista (ou outro objeto que se comporte como uma lista), sem se incomodar com os detalhes da implementação dessa lista (se é um array, uma lista ligada, uma sequência de bytes de um arquivo, etc).</p>
<p>Um pouco acima falei em reescrever de um jeito “um pouco mais Rubista”, mas vejamos um jeito mais Rubista ainda:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>contents = <span class="co">File</span>.open(aFile).readlines.inject(<span class="s"><span class="dl">"</span><span class="dl">"</span></span>) <span class="r">do</span> |buf, line| <tt>
</tt>  buf += line<tt>
</tt><span class="r">end</span></em><tt>
</tt></pre>
<p>O método ‘readlines’ devolve um Array, onde cada elemento é uma linha do arquivo texto. O método “inject” é um <strong>Redutor</strong>: ele pega linha a linha do Array e repassa ao bloco, como primeiro parâmetro. O segundo parâmetro, ‘buf’, é um totalizador que é iniciado com o primeiro parâmetro que passamos no método ‘inject’, no caso a string vazia “&#8221;. Ele repassa sempre esse objeto como segundo parâmetro do bloco. Dentro do bloco podemos fazer o que quiser, mas normalmente queremos que seja um totalizador por isso usamos o operador &#8220;+=” que significa “buf = buf + line”.</p>
<p>Em Ruby é muito comum utilizar essa maneira de pensar: em vez de pensar em <em>“como vamos iterar elemento a elemento”</em>, partimos do princípio que isso é trivial e daí pensamos <em>“como queremos filtrar elemento a elemento”</em>. Linhas como a seguinte são bastante comuns:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; [<span class="i">1</span>,<span class="i">2</span>,<span class="i">3</span>,<span class="i">4</span>,<span class="i">5</span>].map { |elem| elem * elem }<tt>
</tt>=&gt; [<span class="i">1</span>, <span class="i">4</span>, <span class="i">9</span>, <span class="i">16</span>, <span class="i">25</span>]<tt>
</tt><tt>
</tt>&gt;&gt; [<span class="i">1</span>,<span class="i">2</span>,<span class="i">3</span>,<span class="i">4</span>,<span class="i">5</span>].select { |elem| elem % <span class="i">2</span> == <span class="i">0</span> }<tt>
</tt>=&gt; [<span class="i">2</span>, <span class="i">4</span>]<tt>
</tt><tt>
</tt>&gt;&gt; [<span class="i">1</span>,<span class="i">2</span>,<span class="i">3</span>,<span class="i">4</span>,<span class="i">5</span>].inject(<span class="i">0</span>) { |total, elem| total += elem }<tt>
</tt>=&gt; <span class="i">15</span><tt>
</tt><tt>
</tt>&gt;&gt; total = <span class="i">0</span><tt>
</tt>=&gt; <span class="i">0</span><tt>
</tt>&gt;&gt; [<span class="i">1</span>,<span class="i">2</span>,<span class="i">3</span>,<span class="i">4</span>,<span class="i">5</span>].each { |elem| total += elem }<tt>
</tt>=&gt; [<span class="i">1</span>, <span class="i">2</span>, <span class="i">3</span>, <span class="i">4</span>, <span class="i">5</span>]<tt>
</tt>&gt;&gt; total<tt>
</tt>=&gt; <span class="i">15</span></em><tt>
</tt></pre>
<p>O primeiro exemplo – “map” – substitui elemento a elemento pelo resultado do bloco. O segundo – “select” – devolve o resultado do filtro que é passado como bloco. O terceiro – “inject” – é o redutor que já vimos acima e o quarto – “each” – é a mesma coisa que o “inject” mas menos encapsulado e usando código extra para chegar ao mesmo efeito.</p>
<p>Para completar, blocos podem ser passados como parâmetro a um método usando duas sintaxes: chaves (&#8220;{}&#8221;) ou “do..end”, por exemplo:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>[<span class="i">1</span>,<span class="i">2</span>,<span class="i">3</span>,<span class="i">4</span>].each { |elem| puts elem }<tt>
</tt><tt>
</tt>[<span class="i">1</span>,<span class="i">2</span>,<span class="i">3</span>,<span class="i">4</span>].each <span class="r">do</span> |elem|<tt>
</tt>  puts elem<tt>
</tt><span class="r">end</span></em><tt>
</tt>Ambas as formas acima fazem a mesma coisa. A diferença é que costumamos
usar chaves para blocos curtos, de uma única linha. Já o do..end é mais
usado quando temos múltiplas linhas. Em ambos os casos os parâmetros do
bloco vão entre pipes (“||”). Na realidade existem mais diferenças, mas
para começar até aqui está bom.</pre>
<h2>Tipos Básicos</h2>
<p>Invertendo a ordem das coisas, finalmente vamos falar um pouco mais sobre os tipos básicos do Ruby. Nós já vimos muitos deles então vamos apenas passar por eles rapidamente.</p>
<h3>Arrays</h3>
<p>Arrays são listas simples de elementos, a sintaxe mais básica é a seguinte:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; lista = [<span class="i">100</span>,<span class="i">200</span>,<span class="i">300</span>,<span class="i">400</span>]<tt>
</tt>=&gt; [<span class="i">100</span>, <span class="i">200</span>, <span class="i">300</span>, <span class="i">400</span>]<tt>
</tt>&gt;&gt; lista[<span class="i">2</span>]<tt>
</tt>=&gt; <span class="i">300</span></em><tt>
</tt>Até aqui nada de novo, porém o Ruby tem alguns facilitadores, por exemplo:

<em><span class="i">?&gt;</span> lista.first<tt>
</tt>=&gt; <span class="i">100</span><tt>
</tt>&gt;&gt; lista.last<tt>
</tt>=&gt; <span class="i">400</span></em><tt>
</tt>
Também já vimos que ele tem vários métodos que aceitam blocos para
processar elemento a elemento, como “each”, “map”, “select”, “inject”.
Já vimos anteriormente como operadores em Ruby nada mais são do que
métodos. Vejamos como os Arrays se comportam:

<em>&gt;&gt; [<span class="i">1</span>,<span class="i">2</span>,<span class="i">3</span>,<span class="i">4</span>] + [<span class="i">5</span>,<span class="i">6</span>,<span class="i">7</span>,<span class="i">8</span>]<tt>
</tt>=&gt; [<span class="i">1</span>, <span class="i">2</span>, <span class="i">3</span>, <span class="i">4</span>, <span class="i">5</span>, <span class="i">6</span>, <span class="i">7</span>, <span class="i">8</span>]<tt>
</tt><tt>
</tt>&gt;&gt; [<span class="i">1</span>,<span class="i">2</span>,<span class="i">3</span>,<span class="i">4</span>,<span class="i">5</span>] - [<span class="i">2</span>,<span class="i">3</span>,<span class="i">4</span>]<tt>
</tt>=&gt; [<span class="i">1</span>, <span class="i">5</span>]<tt>
</tt><tt>
</tt>&gt;&gt; [<span class="i">1</span>,<span class="i">2</span>,<span class="i">3</span>] * <span class="i">2</span><tt>
</tt>=&gt; [<span class="i">1</span>, <span class="i">2</span>, <span class="i">3</span>, <span class="i">1</span>, <span class="i">2</span>, <span class="i">3</span>]</em><tt>
</tt>
Como na maioria das linguagens a notação de colchetes (“[]”) deve ser
familiar, para encontrar o elemento através do seu índice. Mas em Ruby,
os colchetes também são operadores! Vamos fazer uma brincadeira:

<em><span class="r">class</span> <span class="cl">Array</span><tt>
</tt>  <span class="r">alias</span> <span class="sy">:seletor_antigo</span> <span class="sy">:[]</span><tt>
</tt>  <span class="r">def</span> <span class="fu">[]</span>(indice)<tt>
</tt>    <span class="r">return</span> seletor_antigo(indice) <span class="r">if</span> indice.is_a? <span class="co">Fixnum</span><tt>
</tt>    <span class="r">return</span> <span class="pc">self</span>.send(indice) <span class="r">if</span> indice.is_a? <span class="co">Symbol</span><tt>
</tt>    <span class="s"><span class="dl">"</span><span class="k">Nada encontrado para </span><span class="il"><span class="dl">#{</span>indice<span class="dl">}</span></span><span class="dl">"</span></span><tt>
</tt>  <span class="r">end</span><tt>
</tt><span class="r">end</span><tt>
</tt><tt>
</tt>&gt;&gt; lista = [<span class="i">1</span>,<span class="i">2</span>,<span class="i">3</span>,<span class="i">4</span>]<tt>
</tt>=&gt; [<span class="i">1</span>, <span class="i">2</span>, <span class="i">3</span>, <span class="i">4</span>]<tt>
</tt><tt>
</tt>&gt;&gt; lista[<span class="i">2</span>]<tt>
</tt>=&gt; <span class="i">3</span><tt>
</tt><tt>
</tt>&gt;&gt; lista[<span class="sy">:first</span>]<tt>
</tt>=&gt; <span class="i">1</span><tt>
</tt><tt>
</tt>&gt;&gt; lista[<span class="sy">:last</span>]<tt>
</tt>=&gt; <span class="i">4</span><tt>
</tt><tt>
</tt>&gt;&gt; lista[<span class="sy">:size</span>]<tt>
</tt>=&gt; <span class="i">4</span><tt>
</tt><tt>
</tt>&gt;&gt; lista[<span class="s"><span class="dl">"</span><span class="k">bla bla</span><span class="dl">"</span></span>]<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">Nada encontrado para bla bla</span><span class="dl">"</span></span></em><tt>
</tt></pre>
<p>Viram o que aconteceu? Usamos “alias” novamente para criar um novo atalho à antiga implementação de [], daí reimplementamos []. Ele se comporta assim: se o parâmetro passado entre colchetes for um inteiro, é para se comportar como antes, portanto chamando o atalho “seletor_antigo”. Se for um símbolo (vamos explicar isso depois mas por enquanto entenda que é uma palavra com dois pontos antes, como “:first”), ele deve enviar a mensagem ao objeto usando “send”, ou seja, deve executar como se fosse um método. Dessa forma “lista[:first]” deve se comportar igual a “lista.first”. Finalmente, se for qualquer outra coisa (como um String), apenas mostre uma mensagem dizendo que nada foi encontrado.</p>
<p>Como podemos ver, mais do que o Array em si, o operador “[]” pode ser muito útil em vários cenários. Enfim, na maior parte dos casos um Array em Ruby se comporta muito parecido com um Array em qualquer outra linguagem.</p>
<h3>Hashes</h3>
<p>Um Hash, em outras linguagens, também é chamado de Dicionário, ou seja, é uma lista onde a ordem de inserção não é importante, e cada elemento é um par que liga uma chave a um valor. Por exemplo:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; dic = { <span class="s"><span class="dl">"</span><span class="k">car</span><span class="dl">"</span></span> =&gt; <span class="s"><span class="dl">"</span><span class="k">carro</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">table</span><span class="dl">"</span></span> =&gt; <span class="s"><span class="dl">"</span><span class="k">mesa</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">mouse</span><span class="dl">"</span></span> =&gt; <span class="s"><span class="dl">"</span><span class="k">rato</span><span class="dl">"</span></span> }<tt>
</tt>=&gt; {<span class="s"><span class="dl">"</span><span class="k">mouse</span><span class="dl">"</span></span>=&gt;<span class="s"><span class="dl">"</span><span class="k">rato</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">table</span><span class="dl">"</span></span>=&gt;<span class="s"><span class="dl">"</span><span class="k">mesa</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">car</span><span class="dl">"</span></span>=&gt;<span class="s"><span class="dl">"</span><span class="k">carro</span><span class="dl">"</span></span>}<tt>
</tt><tt>
</tt>&gt;&gt; dic[<span class="s"><span class="dl">"</span><span class="k">car</span><span class="dl">"</span></span>]<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">carro</span><span class="dl">"</span></span><tt>
</tt><tt>
</tt>&gt;&gt; dic[<span class="s"><span class="dl">"</span><span class="k">mouse</span><span class="dl">"</span></span>]<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">rato</span><span class="dl">"

</span></span></em>Novamente, é um comportamento parecido com um Array, mas em vez de
passar índices numéricos ao operador “[]”, passamos uma chave e
esperamos encontrar o valor correspondente. Para acrescentar mais
elementos à lista, podemos fazer assim:

<em>&gt;&gt; dic.merge!( {<span class="s"><span class="dl">"</span><span class="k">book</span><span class="dl">"</span></span> =&gt; <span class="s"><span class="dl">"</span><span class="k">livro</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">leg</span><span class="dl">"</span></span> =&gt; <span class="s"><span class="dl">"</span><span class="k">perna</span><span class="dl">"</span></span>} )<tt>
</tt>=&gt; {<span class="s"><span class="dl">"</span><span class="k">leg</span><span class="dl">"</span></span>=&gt;<span class="s"><span class="dl">"</span><span class="k">perna</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">mouse</span><span class="dl">"</span></span>=&gt;<span class="s"><span class="dl">"</span><span class="k">rato</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">table</span><span class="dl">"</span></span>=&gt;<span class="s"><span class="dl">"</span><span class="k">mesa</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">book</span><span class="dl">"</span></span>=&gt;<span class="s"><span class="dl">"</span><span class="k">livro</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">car</span><span class="dl">"</span></span>=&gt;<span class="s"><span class="dl">"</span><span class="k">carro</span><span class="dl">"</span></span>}

</em>Mais uma peculiaridade de Ruby. Um Hash tem dois métodos para mesclar
novos elementos a uma lista já existente: “merge” e “merge!”. A
diferença de um para outro é que o primeiro é um método não-destrutivo
e o segundo é um método destrutivo, ou seja, o primeiro retorna a lista
mesclada mas a original continua como antes, já o segundo método mescla
os novos elementos diretamente na lista original. Ou seja, a linha
anterior seria equivalente a fazer isso:

<em>dic = dic.merge( {<span class="s"><span class="dl">"</span><span class="k">book</span><span class="dl">"</span></span> =&gt; <span class="s"><span class="dl">"</span><span class="k">livro</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">leg</span><span class="dl">"</span></span> =&gt; <span class="s"><span class="dl">"</span><span class="k">perna</span><span class="dl">"</span></span>} )</em><tt>

</tt>O resultado do merge é atribuído à mesma variável, ignorando a lista
original, que é o que fazemos normalmente. Você também pode ter Hashes
dentro de Hashes, assim:

<em>&gt;&gt; fabio = { <span class="s"><span class="dl">"</span><span class="k">emails</span><span class="dl">"</span></span> =&gt; <tt>
</tt><span class="i">?&gt;</span>           { <span class="s"><span class="dl">"</span><span class="k">trabalho</span><span class="dl">"</span></span> =&gt; <span class="s"><span class="dl">"</span><span class="k">fabio.akita@locaweb.com.br</span><span class="dl">"</span></span>,<tt>
</tt><span class="i">?&gt;</span>              <span class="s"><span class="dl">"</span><span class="k">normal</span><span class="dl">"</span></span>   =&gt; <span class="s"><span class="dl">"</span><span class="k">fabioakita@gmail.com</span><span class="dl">"</span></span> } }<tt>
</tt>=&gt; {<span class="s"><span class="dl">"</span><span class="k">emails</span><span class="dl">"</span></span>=&gt;{<span class="s"><span class="dl">"</span><span class="k">normal</span><span class="dl">"</span></span>=&gt;<span class="s"><span class="dl">"</span><span class="k">fabioakita@gmail.com</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">trabalho</span><span class="dl">"</span></span>=&gt;<span class="s"><span class="dl">"</span><span class="k">fabio.akita@locaweb.com.br</span><span class="dl">"</span></span>}}<tt>
</tt><tt>
</tt><span class="i">?&gt;</span> fabio[<span class="s"><span class="dl">"</span><span class="k">emails</span><span class="dl">"</span></span>][<span class="s"><span class="dl">"</span><span class="k">normal</span><span class="dl">"</span></span>]<tt>
</tt>=&gt; <span class="s"><span class="dl">"</span><span class="k">fabioakita@gmail.com</span><span class="dl">"</span></span></em><tt>
</tt>
Finalmente, podemos explorar o conteúdo de um Hash da seguinte maneira:

<em>&gt;&gt; dic.keys<tt>
</tt>=&gt; [<span class="s"><span class="dl">"</span><span class="k">leg</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">mouse</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">table</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">book</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">car</span><span class="dl">"</span></span>]<tt>
</tt>&gt;&gt; dic.values<tt>
</tt>=&gt; [<span class="s"><span class="dl">"</span><span class="k">perna</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">rato</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">mesa</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">livro</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">carro</span><span class="dl">"</span></span>]<tt>
</tt><tt>
</tt>&gt;&gt; dic.keys.each <span class="r">do</span> |chave|<tt>
</tt><span class="i">?&gt;</span>   puts <span class="s"><span class="dl">"</span><span class="il"><span class="dl">#{</span>chave<span class="dl">}</span></span><span class="k"> = </span><span class="il"><span class="dl">#{</span>dic[chave]<span class="dl">}</span></span><span class="dl">"</span></span><tt>
</tt>&gt;&gt; <span class="r">end</span><tt>
</tt>leg = perna<tt>
</tt>mouse = rato<tt>
</tt>table = mesa<tt>
</tt>book = livro<tt>
</tt>car = carro</em><tt>
</tt></pre>
<p>Se você entendeu blocos nas seções anteriores, este código deve ser bastante trivial de entender. Se não, retome a leitura do começo.</p>
<p>Hash é um dos tipos mais importantes e vamos retornar a ele em outra seção para ver como esse tipo é usado por todo tipo de codificação Ruby. Inclusive o Ruby on Rails utiliza Hashes o tempo todo em lugares onde a maioria nem imagina.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.debugando.com/micro-tutorial-de-ruby-parte-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Micro-Tutorial de Ruby &#8211; Parte I</title>
		<link>http://www.debugando.com/micro-tutorial-de-ruby-parte-i/</link>
		<comments>http://www.debugando.com/micro-tutorial-de-ruby-parte-i/#comments</comments>
		<pubDate>Wed, 10 Dec 2008 11:56:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.debugando.com/?p=175</guid>
		<description><![CDATA[Este artigo é destinado aos iniciantes ou a quem começou a se interessar recentemente por Ruby e Rails. Antes de mais nada, quem já sabe um pouco de Ruby e quer alguma documentação sobre Rails, recomendo muito o novo site Rails Guides, um esforço que se iniciou com o Pratik Naik e deu grandes frutos. [...]]]></description>
			<content:encoded><![CDATA[<p>Este artigo é destinado aos iniciantes ou a quem começou a se interessar recentemente por Ruby e Rails. Antes de mais nada, quem já sabe um pouco de Ruby e quer alguma documentação sobre Rails, recomendo muito o novo site <a href="http://guides.rails.info/">Rails Guides</a>, um esforço que se iniciou com o <strong>Pratik Naik</strong> e deu grandes frutos. Este site é um trabalho em constante evolução mas já concentra toneladas de guias sobre as principais funcionalidades do Rails. O Cassio, da <span class="caps">DRC</span>, também tem um <span class="caps">PDF</span> (e um screencast) disponível em <a href="http://www.devlab.com.br/rails">seu site</a>, que é uma atualização do material criado pelo Ronaldo Ferraz.</p>
<p>Meu objetivo nesta série de artigos é demonstrar algumas das características de Ruby que a tornam diferente de outras linguagens, principalmente as estáticas como Java ou C#.</p>
<p><strong>Disclaimer:</strong> antes de mais nada, vale avisar que usarei alguns trechos de código Java apenas como referência para quem vem de linguagens tradicionais. Não considere isso uma comparação direta (pois os códigos estão propositadamente não otimizados ou simplificados por motivos didáticos).</p>
<h2>O que tem de diferente no Ruby?</h2>
<p>Todos os códigos Ruby mostrados neste artigo podem ser testados no ambiente <span class="caps">IRB</span> (Interpreted Ruby). Com o Ruby já <a href="http://rubyforge.org/frs/download.php/43428/ruby186-27_rc1.exe">instalado</a> em sua máquina, digite o comando ‘irb’ e você estará dentro do ambiente dinâmico do interpretador Ruby. Qualquer código Ruby será executado na hora, o que deve facilitar seus testes. Na realidade eu recomendo que à medida que leiam o artigo, digitem os códigos em Ruby no <span class="caps">IRB</span> e vejam vocês mesmos os resultados. Será bem mais educativo desta forma.</p>
<p>Para começar, vejam este código:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">class</span> <span class="cl">Pessoa</span></em><tt>
</tt><em>  <span class="r">def</span> <span class="fu">initialize</span>(nome)</em><tt>
</tt><em>    <span class="iv">@nome</span> = nome</em><tt>
</tt><em>  <span class="r">end</span></em><tt>
</tt><tt>
</tt><em>  <span class="r">def</span> <span class="fu">nome</span></em><tt>
</tt><em>    <span class="iv">@nome</span></em><tt>
</tt><em>  <span class="r">end</span></em><tt>
</tt><tt>
</tt><em>  <span class="r">def</span> <span class="fu">nome=</span>(valor)</em><tt>
</tt><em>    <span class="iv">@nome</span> = valor</em><tt>
</tt><em>  <span class="r">end</span></em><tt>
</tt><span class="r"><em>end</em></span><tt>
</tt><tt>
</tt><em>fabio = <span class="co">Pessoa</span>.new(<span class="s"><span class="dl">"</span><span class="k">Fabio</span><span class="dl">"</span></span>)  </em><tt>
</tt><em>puts fabio.nome</em><tt>
</tt></pre>
<p>Antes de mais nada, algumas explicações: o que outras linguagens chamam de funções ou métodos, em Ruby são definidas com ‘def … end’. Todo bloco de código termina com ‘end’.</p>
<p>Para colocar um método todo na mesma linha você poderia separar cada linha com “;” (ponto-e-vírgula):</p>
<table class="CodeRay" border="0">
<tbody>
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre><tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">def</span> <span class="fu">nome</span>; <span class="iv">@nome</span>; <span class="r">end</span></em></pre>
</td>
</tr>
</tbody>
</table>
<p>Para que um método retorne um valor, não é necessário usar a palavra ‘return’ como estamos acostumados. O resultado da última expressão de um método sempre é devolvida no retorno. Por exemplo, o método ‘nome’ acima tem apenas ‘@nome’, que é o equivalente a fazer ‘return @nome’. Use ‘return’ apenas se quiser sair do fluxo do método antes de chegar à linha final. Finalmente, variáveis de instância (algo como ‘this.nome’) são denotados com o prefixo ‘@’.</p>
<p>Para instanciar uma classe, basta chamar o método ‘new’ dela. Os parâmetros passados a esse método são repassados como argumentos ao método padrão ‘initialize’. E ‘puts’ é apenas algo parecido com ‘System.out.println()’. Parênteses são opcionais, só os use para eliminar ambigüidades na hora de chamar um método com parâmetros.</p>
<p>À primeira vista, o código acima não é diferente de algo semelhante em Java:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>class Pessoa {</em><tt>
</tt><em>  String nome;</em><tt>
</tt><em>  public Pessoa(String nome) {</em><tt>
</tt><em>    this.nome = nome;</em><tt>
</tt><em>  }</em><tt>
</tt><em>  public String getNome() {</em><tt>
</tt><em>    return this.nome;</em><tt>
</tt><em>  }</em><tt>
</tt><em>  public void setNome(String nome) {</em><tt>
</tt><em>    this.nome = nome;</em><tt>
</tt><em>  }</em><tt>
</tt><em>}</em><tt>
</tt><tt>
</tt><em>Pessoa fabio = new Pessoa("Fabio");</em><tt>
</tt><em>System.out.println(fabio.getNome());</em><tt>
</tt></pre>
<p>Nem mesmo em número de linhas de código temos algum ganho. Olhando apenas dessa forma, para um iniciante, ficaria a pergunta: <em>Onde está a diferença? Apenas por não ter chaves?</em></p>
<p>Bom, vejamos um outro exemplo – da mesma classe Ruby:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>require <span class="s"><span class="dl">'</span><span class="k">ostruct</span><span class="dl">'</span></span></em><tt>
</tt><em><span class="r">class</span> <span class="cl">Pessoa</span> &lt; <span class="co">OpenStruct</span>; <span class="r">end</span></em><tt>
</tt><tt>
</tt><em>fabio = <span class="co">Pessoa</span>.new <span class="sy">:nome</span> =&gt; <span class="s"><span class="dl">"</span><span class="k">Fabio</span><span class="dl">"</span></span></em><tt>
</tt><em>puts fabio.nome</em><tt>
</tt><tt>
</tt><em>fabio.email = <span class="s"><span class="dl">'</span><span class="k">akitaonrails@mac.com</span><span class="dl">'</span></span></em><tt>
</tt><em>puts fabio.email</em><tt>
</tt></pre>
<p>Bom, agora estamos começando a conversar! No caso acima eu confesso, trapaceei um pouco. Fiz a classe ‘Pessoa’ herdar a partir de uma classe padrão do Ruby, a ‘OpenStruct’. Ela permite que os objetos instanciados a partir dessa classe tenham qualquer atributo que for necessário em tempo de execução! Vou voltar neste ponto mais tarde, por enquanto apenas ignore a magia negra e continue.</p>
<p>Ruby suporta herança simples de classes, assim como em Java ou C#. O caracter ‘&lt;’ é o equivalente a ‘extends’ em Java.</p>
<p>Vamos a mais alguns exemplos simples:</p>
<p><strong></p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; <span class="i">1</span> + <span class="i">2</span></em><tt>
</tt><em>=&gt; <span class="i">3</span></em><tt>
</tt><em>&gt;&gt; numero = <span class="i">5</span></em><tt>
</tt><em>=&gt; <span class="i">5</span></em><tt>
</tt><em>&gt;&gt; numero * <span class="i">3</span></em><tt>
</tt><em>=&gt; <span class="i">15</span></em><tt>
</tt><tt>
</tt><em>&gt;&gt; contador = <span class="i">1</span></em><tt>
</tt><em>=&gt; <span class="i">1</span></em><tt>
</tt><em>&gt;&gt; <span class="r">while</span> contador &lt; numero</em><tt>
</tt><em>&gt;&gt;   puts contador</em><tt>
</tt><em>&gt;&gt;   contador += <span class="i">1</span></em><tt>
</tt><em>&gt;&gt; <span class="r">end</span></em><tt>
</tt><span class="i"><em>1</em></span><tt>
</tt><span class="i"><em>2</em></span><tt>
</tt><span class="i"><em>3</em></span><tt>
</tt><span class="i"><em>4</em></span><tt>
</tt><tt>
</tt><em>&gt;&gt; <span class="r">def</span> <span class="fu">hello</span></em><tt>
</tt><em>&gt;&gt;   <span class="s"><span class="dl">"</span><span class="k">Hello World</span><span class="dl">"</span></span></em><tt>
</tt><em>&gt;&gt; <span class="r">end</span></em><tt>
</tt><tt>
</tt><em>&gt;&gt; puts hello</em><tt>
</tt><em><span class="co">Hello</span> <span class="co">World</span></em><tt>
</tt></pre>
<p></strong></p>
<p><strong>Obs:</strong> quando você está no <span class="caps">IRB</span>, “&gt;&gt;” é o “prompt de comando” e “=&gt;” é o resultado do comando que você acabou de executar. Não confunda com o código Ruby propriamente dito.</p>
<p>Na primeira parte algumas operações simples. Em seguida um loop tradicional, com contador. Depois um pequeno método chamado “hello” e sendo executado. Acredito que, independente da linguagem de onde você veio, o que mostrei até agora é bastante familiar. Novamente, fica a pergunta: <em>“onde está a diferença?”</em></p>
<h2>Quase tudo é Objeto</h2>
<p>Ruby foi muito influenciado por <strong>Smalltalk</strong>, a verdadeira linguagem que inspirou quase todas as outras mais modernas de orientação-a-objetos. Não quero aqui começar nenhuma discussão sobre o que é ser <span class="caps">OOP</span> ou não pois argumentos desse tipo são irrelevantes aqui.</p>
<p>O que muitos costumam reclamar em linguagens tradicionais é o seguinte:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>class Teste {</em><tt>
</tt><em>  public static void main(String[] args) {</em><tt>
</tt><em>    System.out.println("Hello World");</em><tt>
</tt><em>  }</em><tt>
</tt><em>}</em><tt>
</tt></pre>
<p>Muita coisa para fazer um simples “Hello World”. Agora vejamos o Hello World em Ruby:</p>
<p><em></p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>puts <span class="s"><span class="dl">"</span><span class="k">Hello World</span><span class="dl">"</span></span></em><tt>
</tt></pre>
<p></em></p>
<p><em>“Oras, mas Ruby não é <span class="caps">OOP</span>?? Cadê a classe!!?”</em> Vamos entender o exemplo. Considerando que ainda estamos dentro do ambiente <span class="caps">IRB</span>, faça o seguinte:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; puts <span class="s"><span class="dl">"</span><span class="k">Hello World</span><span class="dl">"</span></span></em><tt>
</tt><em><span class="co">Hello</span> <span class="co">World</span></em><tt>
</tt><em>=&gt; <span class="pc">nil</span></em><tt>
</tt><tt>
</tt><em>&gt;&gt; <span class="pc">self</span></em><tt>
</tt><em>=&gt; main</em><tt>
</tt><em>&gt;&gt; <span class="pc">self</span>.class</em><tt>
</tt><em>=&gt; <span class="co">Object</span></em><tt>
</tt></pre>
<p>Em Ruby, “self” é <em>mais ou menos</em> parecido com a função do “this” em Java ou outras linguagens. Mas como podem ver, nós já estamos <strong>dentro</strong> de um objeto, de uma instância de Object. Nunca estamos num ambiente estático ou não-objeto. Criar um método no <span class="caps">IRB</span> significa adicionar esse método ao objeto ‘main’ que, por sua vez é uma instância da classe Object.</p>
<p>Mas não é apenas isso, veja o seguinte:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; <span class="i">1</span>.class</em><tt>
</tt><em>=&gt; <span class="co">Fixnum</span></em><tt>
</tt><tt>
</tt><em>&gt;&gt; <span class="pc">true</span>.class</em><tt>
</tt><em>=&gt; <span class="co">TrueClass</span></em><tt>
</tt><tt>
</tt><em>&gt;&gt; <span class="pc">false</span>.class</em><tt>
</tt><em>=&gt; <span class="co">FalseClass</span></em><tt>
</tt><tt>
</tt><em>&gt;&gt; <span class="pc">nil</span>.class</em><tt>
</tt><em>=&gt; <span class="co">NilClass</span></em><tt>
</tt></pre>
<p>Um número, um booleano (verdadeiro, falso) e até nulo (o &#8220;nil&#8221;) são bjetos. Todos eles respondem a métodos, em especial o método “class” que indica de que classe esse objeto é instância. Note que até o nulo é uma instância da classe chamada “NilClass”.</p>
<h2>Classes Abertas</h2>
<p>Uma coisa que não tem o que se fazer em muitas linguagens estáticas como Java é <strong>mudar de idéia</strong>. Toda a idéia de se ter interfaces e classes fechadas força o programador a decidir da primeira vez e ter que sobreviver às conseqüências de sua decisão, o que normalmente força ter que tomar a decisão certa logo no começo e incentiva o temido <a href="http://en.wikipedia.org/wiki/Big_Design_Up_Front">Big Design Up Front</a>.</p>
<p>Quando precisamos de mais funcionalidades nesses casos, precisamos improvisar. Por exemplo:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>class StringUtils {</em><tt>
</tt><em>  public static boolean isEmpty(String str) {</em><tt>
</tt><em>    return str == null || str.length() == 0;</em><tt>
</tt><em>  }</em><tt>
</tt><em>}</em><tt>
</tt><tt>
</tt><em>String nome = "Fabio Akita";</em><tt>
</tt><em>StringUtils.isEmpty(nome);</em><tt>
</tt></pre>
<p>O método “isEmpty()”, disponível na classe StringUtils do pacote Commons do Jakarta, avalia se o string que ele recebeu como argumento é nulo ou vazio. Na classe original “java.lang.String” não existia o método “isEmpty()”. Isso não é um erro, apenas na época em que essa classe foi criada, não parecia óbvio a ninguém que um método assim poderia ser útil. Mas agora, a classe String é fechada e não pode ser reimplementada. Também não adianta criar uma classe MyString que herda de String porque todas instâncias de String não terão as novas funcionalidades do MyString.</p>
<p>Portanto a solução-gambiarra significa criar uma classe separada “StringUtils”, com vários métodos estáticos, como o “isEmpty()”, o que efetivamente significa programação procedural e não-orientada a objetos. StringUtils é apenas uma estrutura com um punhado de métodos estáticos.</p>
<p>Em Ruby, podemos o mesmo problema resolver desta forma:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">class</span> <span class="cl">String</span></em><tt>
</tt><em>  <span class="r">def</span> <span class="fu">empty?</span></em><tt>
</tt><em>    <span class="pc">self</span>.nil? || <span class="pc">self</span>.size == <span class="i">0</span></em><tt>
</tt><em>  <span class="r">end</span></em><tt>
</tt><span class="r"><em>end</em></span><tt>
</tt><tt>
</tt><em>nome = <span class="s"><span class="dl">"</span><span class="k">Fabio Akita</span><span class="dl">"</span></span></em><tt>
</tt><em>nome.empty?</em><tt>
</tt></pre>
<p>Nesse caso específico nem precisaríamos fazer isso porque o método “empty?” já existe na String de Ruby, mas está aí apenas para ilustrar o problema.</p>
<p>Temos algumas coisas interessantes aqui. Primeiro, o nome do método pode parecer estranho por causa da interrogação no final. Mas não se assustem, em Ruby isso é um caracter válido num nome de método e não tem nenhum efeito colateral, é apenas um caracter a mais que expressa a intenção do método, no caso, de fazer uma pergunta ao objeto.</p>
<p>Mas o mais importante: hoje estamos decidindo que a classe String deveria ter mais métodos do que ele já tem. Felizmente, graças às características da linguagem, não estamos presos a uma classe fechada: podemos reabrí-la, reimplementá-la como quisermos e, automaticamente, toda instância de String (novas e inclusive as que já existiam), passam a responder à nova implementação.</p>
<p>Vejamos outro exemplo de orientação a objetos mesclado com “eye candy”.</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; <span class="i">1</span> + <span class="i">2</span></em><tt>
</tt><em>=&gt; <span class="i">3</span></em><tt>
</tt></pre>
<p>Vamos lembrar do básico: números, em Ruby, são objetos, mais especificamente instâncias da classe Fixnum. Agora vejamos outra maneira de escrever a mesma coisa em Ruby, sem “eye candy”:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; <span class="i">1</span>.+(<span class="i">2</span>)</em><tt>
</tt><em>=&gt; <span class="i">3</span></em><tt>
</tt></pre>
<p>Espero que isso esteja claro: quando somamos dois números, na realidade estamos <em>chamando o método especial</em> “+” do objeto “1” e passando como argumento o objeto “2”. E isso vale para todos os operadores matemáticos que conhecemos como “-”, “/”. Mas o que acontece quando tentamos somar dois objetos incompatíveis?</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; <span class="i">1</span> + <span class="s"><span class="dl">"</span><span class="k">2</span><span class="dl">"</span></span></em><tt>
</tt><em><span class="co">TypeError</span>: <span class="co">String</span> can</em><span class="s"><span class="dl"><em>'</em></span><span class="k"><em>t be coerced into Fixnum</em><tt>
</tt><em>  from (irb):35:in `+</em></span><span class="dl"><em>'</em></span></span><tt>
</tt><em>  from (irb):<span class="i">35</span></em><tt>
</tt><em>  </em><tt>
</tt><em>&gt;&gt; <span class="i">1</span>.+(<span class="s"><span class="dl">"</span><span class="k">s</span><span class="dl">"</span></span>)</em><tt>
</tt><em><span class="co">TypeError</span>: <span class="co">String</span> can</em><span class="s"><span class="dl"><em>'</em></span><span class="k"><em>t be coerced into Fixnum</em><tt>
</tt><em>  from (irb):36:in `+</em></span><span class="dl"><em>'</em></span></span><tt>
</tt><em>  from (irb):<span class="i">36</span></em><tt>
</tt></pre>
<p>Escrevi as duas maneiras novamente: passar um String como parâmetro ao método “+” de um Fixnum devolve uma exceção “TypeError” indicando que a operação é inválida. Mas digamos que, apenas por motivos didáticos, eu realmente queira que o Ruby reaja como Javascript ou Perl e que “1” seja convertido em String e depois concatenado ao parâmetro “2”, resultando em “12”.</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; <span class="r">class</span> <span class="cl">Fixnum</span></em><tt>
</tt><em>&gt;&gt;   <span class="r">alias</span> <span class="sy">:soma_velha</span> <span class="sy">:+</span></em><tt>
</tt><em><span class="i">?&gt;</span>   <span class="r">def</span> <span class="fu">+</span>(valor)</em><tt>
</tt><em>&gt;&gt;     <span class="r">return</span> <span class="pc">self</span>.to_s + valor <span class="r">if</span> valor.is_a? <span class="co">String</span></em><tt>
</tt><em>&gt;&gt;     soma_velha(valor)</em><tt>
</tt><em>&gt;&gt;   <span class="r">end</span></em><tt>
</tt><em>&gt;&gt; <span class="r">end</span></em><tt>
</tt><em>=&gt; <span class="pc">nil</span></em><tt>
</tt><tt>
</tt><em>&gt;&gt; <span class="i">1</span> + <span class="i">2</span></em><tt>
</tt><em>=&gt; <span class="i">3</span></em><tt>
</tt><em>&gt;&gt; <span class="i">1</span> + <span class="s"><span class="dl">"</span><span class="k">2</span><span class="dl">"</span></span></em><tt>
</tt><em>=&gt; <span class="s"><span class="dl">"</span><span class="k">12</span><span class="dl">"</span></span></em><tt>
</tt></pre>
<p>Várias coisas acontecendo aqui. Vejamos os principais pontos: primeiro, estamos reabrindo a classe Fixnum, ou seja, todas as instâncias dessa classe serão afetadas automaticamente pelo que faremos a seguir.</p>
<p>Depois, mais uma novidade: o método ‘alias’. Esse é um método de classe que cria um novo apontamento a um método que já existe. Pense em algo assim: você tem ‘a = foo’ e depois ‘b = a’. Agora, tanto ‘a’ quanto ‘b’ apontam para o mesmo objeto ‘foo’.</p>
<p>Outra coisa: quando uma classe é criada, reaberta ou ‘executada’ os métodos chamados dentro dela são executados. Ou seja, o comando ‘alias’, por exemplo, serve para reapontar um método com outro nome. No exemplo, já existia o método chamado “+” e com “alias” criamos um segundo método chamado “soma_velha” que aponta para a mesma implementação do método original. Ou seja, neste ponto as três chamadas a seguir se equivalem:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; <span class="i">5</span> + <span class="i">10</span></em><tt>
</tt><em>=&gt; <span class="i">15</span></em><tt>
</tt><tt>
</tt><em>&gt;&gt; <span class="i">5</span>.+(<span class="i">10</span>)</em><tt>
</tt><em>=&gt; <span class="i">15</span></em><tt>
</tt><tt>
</tt><em>&gt;&gt; <span class="i">5</span>.soma_velha(<span class="i">10</span>)</em><tt>
</tt><em>=&gt; <span class="i">15</span></em><tt>
</tt></pre>
<p>Mas fizemos mais: depois de criar o novo apontamento “soma_velha” reimplementamos o método antigo “+”. A idéia é: se o parâmetro for um String, quero transformar o objeto Fixnum num String e depois concatenamos os dois. Veja como usamos o ‘return’ para retornar imediatamente caso este seja o caso. Senão, se o argumento passado não for um String, passamos para o método ‘soma_velha’ fazer a soma do jeito antigo.</p>
<p>Note também que usamos o ‘if’ de uma forma um pouco diferente: no fim da expressão:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">return</span> <span class="pc">self</span>.to_s + valor <span class="r">if</span> valor.is_a? <span class="co">String</span></em><tt>
</tt></pre>
<p>‘is_a?’ é um método que está sem os parênteses (lembram-se? são opcionais) e serve para verificar o tipo do objeto ‘valor’. Literalmente podemos ler assim: “retorne self.to_s concatenado com ‘valor’ se for do tipo String.” Se você entende inglês verá que a expressão é praticamente uma frase.</p>
<p>E é isso que acontece agora quando tentamos somar um número com um string: ele retorna a concatenação de dois Strings. Note também que esse comportamento passa a valer para todos os objetos numéricos (instâncias de Fixnum).</p>
<p>Esse conceito de reabrir uma classe e implementar uma nova funcionalidade ficou conhecido com o nome de <a href="http://en.wikipedia.org/wiki/Monkey_patch">monkey patching</a>. É um recurso muito poderoso e, como tudo que é poderoso ele pode ser tanto uma grande vantagem como um grande risco se usado da maneira errada. Espera-se, claro, que o programador não abuse disso.</p>
<p>O framework Ruby on Rails faz muito uso desse recurso. Um dos pacotes que compõe o Rails chama-se Active Support e uma de suas utilidades é justamente reabrir diversas classes padrão do Ruby para incorporar mais funcionalidades. Por exemplo:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="c"><em># carrega o pacote activesupport</em></span><tt>
</tt><em>&gt;&gt; require <span class="s"><span class="dl">'</span><span class="k">rubygems</span><span class="dl">'</span></span></em><tt>
</tt><em>&gt;&gt; require <span class="s"><span class="dl">'</span><span class="k">activesupport</span><span class="dl">'</span></span></em><tt>
</tt><em>=&gt; <span class="pc">true</span></em><tt>
</tt><tt>
</tt><span class="c"><em># horário atual</em></span><tt>
</tt><em>&gt;&gt; <span class="co">Time</span>.now</em><tt>
</tt><em>=&gt; <span class="co">Wed</span> <span class="co">Oct</span> <span class="i">29</span> <span class="i">23</span>:<span class="i">36</span>:<span class="i">24</span> <span class="i">-0200</span> <span class="i">2008</span></em><tt>
</tt><tt>
</tt><span class="c"><em># fazendo cálculos com datas</em></span><tt>
</tt><em>&gt;&gt; <span class="co">Time</span>.now - <span class="i">23</span>.days</em><tt>
</tt><em>=&gt; <span class="co">Mon</span> <span class="co">Oct</span> <span class="i">06</span> <span class="i">23</span>:<span class="i">36</span>:<span class="i">28</span> <span class="i">-0300</span> <span class="i">2008</span></em><tt>
</tt><tt>
</tt><em>&gt;&gt; <span class="i">2</span>.weeks.ago</em><tt>
</tt><em>=&gt; <span class="co">Wed</span> <span class="co">Oct</span> <span class="i">15</span> <span class="i">23</span>:<span class="i">36</span>:<span class="i">32</span> <span class="i">-0200</span> <span class="i">2008</span></em><tt>
</tt><tt>
</tt><span class="c"><em># fazendo cálculos com unidades de medida</em></span><tt>
</tt><em>&gt;&gt; (<span class="i">1</span>.gigabyte - <span class="i">512</span>.megabytes) / <span class="i">1</span>.kilobyte</em><tt>
</tt><em>=&gt; <span class="i">524288</span></em><tt>
</tt><tt>
</tt><span class="c"><em># transformando objetos em XML</em></span><tt>
</tt><em>&gt;&gt; { <span class="sy">:html</span> =&gt; { <span class="sy">:body</span> =&gt; { <span class="sy">:p</span> =&gt; <span class="s"><span class="dl">"</span><span class="k">teste</span><span class="dl">"</span></span> } } }.to_xml</em><tt>
</tt><em>=&gt; <span class="s"><span class="dl">"</span><span class="k">&lt;?xml version=</span><span class="dl">"</span></span><span class="fl">1.0</span><span class="s"><span class="dl">"</span><span class="k"> encoding=</span><span class="dl">"</span></span><span class="co">UTF</span><span class="i">-8</span></em><span class="s"><em><span class="dl">"</span><span class="k">?&gt;</span><span class="ch">\n</span></em><span class="k"><tt>
</tt><em>&lt;hash&gt;</em></span><em><span class="ch">\n</span><span class="k">  &lt;html&gt;</span><span class="ch">\n</span><span class="k">    &lt;body&gt;</span><span class="ch">\n</span></em><span class="k"><em>      </em><tt>
</tt><em>&lt;p&gt;teste&lt;/p&gt;</em></span><em><span class="ch">\n</span><span class="k">    &lt;/body&gt;</span><span class="ch">\n</span><span class="k">  &lt;/html&gt;</span><span class="ch">\n</span></em><span class="k"><tt>
</tt><em>&lt;/hash&gt;</em></span><em><span class="ch">\n</span><span class="dl">"</span></em></span><tt>
</tt></pre>
<p>Como podem ver, podemos incrementar muito as funcionalidades de tudo que já existe. O Ruby on Rails começa exatamente assim: primeiro incorporando muitas coisas novas ao próprio Ruby e depois construindo sobre ela. Muitos são casos onde simplesmente depender de criar novas sub-classes não adiantaria muita coisa. Outro exemplo: em Java, se quisermos comparar o conteúdo de dois Strings, não devemos fazer isso:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>String a = "foo";</em><tt>
</tt><em>String b = "bla";</em><tt>
</tt><em>if (a == b) {</em><tt>
</tt><em>  System.out.println("encontrado!");</em><tt>
</tt><em>}</em><tt>
</tt><em>if (a &gt; b) {</em><tt>
</tt><em>  System.out.println("a maior do que b");</em><tt>
</tt><em>}</em><tt>
</tt></pre>
<p>O correto seria assim:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>if (a.equals(b)) {</em><tt>
</tt><em>  System.out.println("encontrado!");</em><tt>
</tt><em>}</em><tt>
</tt><em>if (a.compareTo(b) &gt; 0) {</em><tt>
</tt><em>  System.out.println("a maior do que b");</em><tt>
</tt><em>}</em><tt>
</tt></pre>
<p>Já, em Ruby, fazemos assim:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>a = <span class="s"><span class="dl">"</span><span class="k">foo</span><span class="dl">"</span></span></em><tt>
</tt><em>b = <span class="s"><span class="dl">"</span><span class="k">bla</span><span class="dl">"</span></span></em><tt>
</tt><em>puts <span class="s"><span class="dl">"</span><span class="k">encontrado!</span><span class="dl">"</span></span> <span class="r">if</span> a == b</em><tt>
</tt><em>puts <span class="s"><span class="dl">"</span><span class="k">a maior do que b</span><span class="dl">"</span></span> <span class="r">if</span> a &gt; b</em><tt>
</tt></pre>
<p>Exatamente como imaginaríamos que deveria ser. Isso porque “==” e “&gt;” são ‘operadores’ mas são também nomes de métodos, como explicamos acima. Então fica fácil implementar o comportamento que precisamos da maneira mais clara e expressiva possível.</p>
<h3>Módulos e Organização</h3>
<p>No exemplo do Fixnum, reabrimos diretamente a classe para colocar novas funcionalidades. Mas podemos fazer diferente:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="co">Fixnum</span>.class_eval <span class="r">do</span><tt>
</tt>  <span class="r">alias</span> <span class="sy">:soma_velha</span> <span class="sy">:+</span><tt>
</tt>  <span class="r">def</span> <span class="fu">+</span>(valor)<tt>
</tt>    <span class="r">return</span> <span class="pc">self</span>.to_s + valor <span class="r">if</span> valor.is_a? <span class="co">String</span><tt>
</tt>    soma_velha(valor)<tt>
</tt>  <span class="r">end</span><tt>
</tt><span class="r">end</span><tt>
</tt></pre>
<p>Como a classe “Fixnum” é por si mesmo um objeto, podemos chamar métodos nela. Por exemplo, “new” é um método dessa instância de Class. O que fizemos acima é a mesma coisa que fizemos antes, mas esse código podemos colocar dentro um método, para ser executado somente quando quisermos. Ou seja, podemos alterar o comportamento de uma classe programaticamente. Mas podemos ser ainda mais seletivos:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; a = <span class="s"><span class="dl">"</span><span class="k">teste</span><span class="dl">"</span></span></em><tt>
</tt><em>=&gt; <span class="s"><span class="dl">"</span><span class="k">teste</span><span class="dl">"</span></span></em><tt>
</tt><em>&gt;&gt; a.instance_eval <span class="r">do</span></em><tt>
</tt><em><span class="i">?&gt;</span>   <span class="r">def</span> <span class="fu">hello</span></em><tt>
</tt><em>&gt;&gt;     <span class="s"><span class="dl">"</span><span class="k">hello from teste</span><span class="dl">"</span></span></em><tt>
</tt><em>&gt;&gt;   <span class="r">end</span></em><tt>
</tt><em>&gt;&gt; <span class="r">end</span></em><tt>
</tt><em>=&gt; <span class="pc">nil</span></em><tt>
</tt><em>&gt;&gt; a.hello</em><tt>
</tt><em>=&gt; <span class="s"><span class="dl">"</span><span class="k">hello from teste</span><span class="dl">"</span></span></em><tt>
</tt><em>&gt;&gt; <span class="s"><span class="dl">"</span><span class="k">foo</span><span class="dl">"</span></span>.hello</em><tt>
</tt><em><span class="co">NoMethodError</span>: undefined method </em><span class="sh"><span class="dl"><em>`</em></span><span class="k"><em>hello' for "foo":String</em><tt>
</tt><em>  from (irb):17</em><tt>
</tt><em>  from :0</em></span></span></pre>
<p>Veja agora: criamos um String na variável “a”. Então modificamos essa instância acrescentando um método chamado “hello”, mas somente a essa instância. Quando chamamos “a.hello” ele responde como esperamos, mas quando pegamos uma nova instância de String e tentamos chamar o mesmo método, vemos que não existe. Ou seja, podemos modificar o comportamento de todos os objetos de uma classe, ou somente de um único objeto individual.</p>
<p>Agora vejamos um outro meio de injetar código em classes de maneiras mais organizadas:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">module</span> <span class="cl">MeusPatches</span></em><tt>
</tt><em>  <span class="r">def</span> <span class="fu">say_hello</span></em><tt>
</tt><em>    <span class="s"><span class="dl">"</span><span class="k">Hello World!</span><span class="dl">"</span></span></em><tt>
</tt><em>  <span class="r">end</span></em><tt>
</tt><tt>
</tt><em>  <span class="r">def</span> <span class="fu">say_time</span></em><tt>
</tt><em>    <span class="co">Time</span>.now</em><tt>
</tt><em>  <span class="r">end</span></em><tt>
</tt><span class="r"><em>end</em></span><tt>
</tt><tt>
</tt><em><span class="r">class</span> <span class="cl">Fixnum</span></em><tt>
</tt><em>  include <span class="co">MeusPatches</span></em><tt>
</tt><span class="r"><em>end</em></span><tt>
</tt><tt>
</tt><em><span class="r">class</span> <span class="cl">String</span></em><tt>
</tt><em>  extend <span class="co">MeusPatches</span></em><tt>
</tt><span class="r"><em>end</em></span><tt>
</tt></pre>
<p>Módulos são como Classes que não podem ser instanciadas. No exemplo acima, organizamos dois métodos dentro de um módulo chamado “MeusPatches”. Em seguida reabrimos as classes “Fixnum” e “String”. No primeiro incluímos o módulo e no segundo extendemos o módulo. Para entender a diferença vamos usar isso:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; <span class="i">13</span>.say_hello</em><tt>
</tt><em>=&gt; <span class="s"><span class="dl">"</span><span class="k">Hello World!</span><span class="dl">"</span></span></em><tt>
</tt><tt>
</tt><em>&gt;&gt; <span class="s"><span class="dl">"</span><span class="dl">"</span></span>.say_hello</em><tt>
</tt><em><span class="co">NoMethodError</span>: undefined method </em><span class="sh"><span class="dl"><em>`</em></span><span class="k"><em>say_hello' for "":String</em><tt>
</tt><em>  from (irb):19</em><tt>
</tt><tt>
</tt><em>&gt;&gt; String.say_hello</em><tt>
</tt><em>=&gt; "Hello World!"</em></span></span></pre>
<p>O objeto “13” (que é instância de Fixnum) responde ao método do módulo. A string vazia “&#8221; não responde. Eis a diferença entre &#8220;include” e “extend”: no segundo quem responde ao método do módulo é a própria classe. Na prática, pense que “include” serve para acrescentar métodos de instância e “extend” para acrescentar “métodos de classe” – esse não é o termo correto mas para a maioria dos casos serve.</p>
<p>No Ruby on Rails esse recurso é muito usado, principalmente para organizar códigos de classes muito longas. Por exemplo, o ActiveRecord tem centenas de funcionalidades. Colocar tudo numa única classe seria muito difícil de manter depois, por isso ele se organiza desta forma:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="c"><em># </em></span><tt>
</tt><em><span class="co">ActiveRecord</span>::<span class="co">Base</span>.class_eval <span class="r">do</span></em><tt>
</tt><em>  extend <span class="co">ActiveRecord</span>::<span class="co">QueryCache</span></em><tt>
</tt><em>  include <span class="co">ActiveRecord</span>::<span class="co">Validations</span></em><tt>
</tt><em>  include <span class="co">ActiveRecord</span>::<span class="co">Locking</span>::<span class="co">Optimistic</span></em><tt>
</tt><em>  include <span class="co">ActiveRecord</span>::<span class="co">Locking</span>::<span class="co">Pessimistic</span></em><tt>
</tt><em>  include <span class="co">ActiveRecord</span>::<span class="co">AttributeMethods</span></em><tt>
</tt><em>  include <span class="co">ActiveRecord</span>::<span class="co">Dirty</span></em><tt>
</tt><em>  include <span class="co">ActiveRecord</span>::<span class="co">Callbacks</span></em><tt>
</tt><em>  include <span class="co">ActiveRecord</span>::<span class="co">Observing</span></em><tt>
</tt><em>  include <span class="co">ActiveRecord</span>::<span class="co">Timestamp</span></em><tt>
</tt><em>  include <span class="co">ActiveRecord</span>::<span class="co">Associations</span></em><tt>
</tt><em>  include <span class="co">ActiveRecord</span>::<span class="co">NamedScope</span></em><tt>
</tt><em>  include <span class="co">ActiveRecord</span>::<span class="co">AssociationPreload</span></em><tt>
</tt><em>  include <span class="co">ActiveRecord</span>::<span class="co">Aggregations</span></em><tt>
</tt><em>  include <span class="co">ActiveRecord</span>::<span class="co">Transactions</span></em><tt>
</tt><em>  include <span class="co">ActiveRecord</span>::<span class="co">Reflection</span></em><tt>
</tt><em>  include <span class="co">ActiveRecord</span>::<span class="co">Calculations</span></em><tt>
</tt><em>  include <span class="co">ActiveRecord</span>::<span class="co">Serialization</span></em><tt>
</tt><span class="r"><em>end</em></span><tt>
</tt></pre>
<p>Cada um dos includes acima tem um arquivo separado. Por exemplo ActiveRecord::QueryCache fica no arquivo “active_record/query_cache.rb”. É uma excelente maneira de organizar seus códigos. Mas existem alguns truques importantes de se conhecer. Uma delas é entender que módulos tem “eventos”. Ou seja, podemos instruir o módulo para executar alguma coisa toda vez que for incluso em alguma classe.</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">module</span> <span class="cl">MeusPatches</span></em><tt>
</tt><em>  <span class="r">def</span> <span class="pc">self</span>.included(base)</em><tt>
</tt><em>    base.send(<span class="sy">:extend</span>, <span class="co">ClassMethods</span>)</em><tt>
</tt><em>    puts <span class="s"><span class="dl">"</span><span class="k">Module MeusPaches incluso na classe </span><span class="il"><span class="dl">#{</span>base.name<span class="dl">}</span></span><span class="dl">"</span></span></em><tt>
</tt><em>  <span class="r">end</span></em><tt>
</tt><tt>
</tt><em>  <span class="r">def</span> <span class="fu">metodo_de_instancia</span></em><tt>
</tt><em>    <span class="s"><span class="dl">"</span><span class="k">sou um metodo de instancia</span><span class="dl">"</span></span></em><tt>
</tt><em>  <span class="r">end</span></em><tt>
</tt><tt>
</tt><em>  <span class="r">module</span> <span class="cl">ClassMethods</span></em><tt>
</tt><em>    <span class="r">def</span> <span class="pc">self</span>.extended(base)</em><tt>
</tt><em>      puts <span class="s"><span class="dl">"</span><span class="k">Module MeusPatches::ClassMethods extendido na classe </span><span class="il"><span class="dl">#{</span>base.name<span class="dl">}</span></span><span class="dl">"</span></span></em><tt>
</tt><em>    <span class="r">end</span></em><tt>
</tt><tt>
</tt><em>    <span class="r">def</span> <span class="fu">metodo_de_classe</span></em><tt>
</tt><em>      <span class="s"><span class="dl">"</span><span class="k">sou um metodo de classe</span><span class="dl">"</span></span></em><tt>
</tt><em>    <span class="r">end</span></em><tt>
</tt><em>  <span class="r">end</span></em><tt>
</tt><span class="r"><em>end</em></span><tt>
</tt><tt>
</tt><em><span class="r">class</span> <span class="cl">Pessoa</span></em><tt>
</tt><span class="r"><em>end</em></span><tt>
</tt><tt>
</tt><em><span class="i">?&gt;</span>   <span class="co">Pessoa</span>.send(<span class="sy">:include</span>, <span class="co">MeusPatches</span>)</em><tt>
</tt><em><span class="co">Module</span> <span class="co">MeusPatches</span>::<span class="co">ClassMethods</span> extendido na classe <span class="co">Pessoa</span></em><tt>
</tt><em><span class="co">Module</span> <span class="co">MeusPaches</span> incluso na classe <span class="co">Pessoa</span></em><tt>
</tt><em>=&gt; <span class="co">Pessoa</span></em><tt>
</tt><em>&gt;&gt; </em><tt>
</tt><em><span class="i">?&gt;</span>   fabio = <span class="co">Pessoa</span>.new</em><tt>
</tt><em>=&gt; <span class="c">#&lt;Pessoa:0x1789528&gt;</span></em><tt>
</tt><em>&gt;&gt; fabio.metodo_de_instancia</em><tt>
</tt><em>=&gt; <span class="s"><span class="dl">"</span><span class="k">sou um metodo de instancia</span><span class="dl">"</span></span></em><tt>
</tt><em>&gt;&gt; </em><tt>
</tt><em><span class="i">?&gt;</span> <span class="co">Pessoa</span>.metodo_de_classe</em><tt>
</tt><em>=&gt; <span class="s"><span class="dl">"</span><span class="k">sou um metodo de classe</span><span class="dl">"</span></span></em><tt>
</tt></pre>
<p>Você vai entender o que significa “send” na próxima seção. Apenas entenda a seguinte idéia: criamos um módulo chamado “MeusPatches” e um sub-módulo dentro dele chamado “ClassMethods” (poderia ser outro nome, mas só para padronizar). Os métodos do módulo principal ficam disponíveis às instâncias dos objetos e os métodos do sub-módulo ficam disponíveis como métodos de classe. A sequência é assim:</p>
<ol>
<li>primeiro definimos o módulo MeusPatches e seu sub-módulo ClassMethods</li>
<li>definimos a classe Pessoa, uma classe vazia</li>
<li>incluímos o módulo MeusPatches à classe Pessoa</li>
<li>o método self.included é ativado que, por sua vez, manda extender o sub-módulo ClassMethods na classe Pessoa (que é passado como o parâmetro &#8220;base&#8221;)</li>
<li>agora a classe Pessoa ganhou os métodos de instância e de classe</li>
<li>criamos a instância “fabio” e chamamos o método “metodo_de_instancia”</li>
<li>chamamos o método “metodo_de_classe” diretamente da classe Pessoa</li>
</ol>
<p>Se fôssemos reescrever a classe Pessoa sem o recurso de módulos, ela ficaria assim:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">class</span> <span class="cl">Pessoa</span></em><tt>
</tt><em>  <span class="r">def</span> <span class="fu">metodo_de_instancia</span></em><tt>
</tt><em>    <span class="s"><span class="dl">"</span><span class="k">sou um metodo de instancia</span><span class="dl">"</span></span></em><tt>
</tt><em>  <span class="r">end</span></em><tt>
</tt><tt>
</tt><em>  <span class="r">def</span> <span class="pc">self</span>.metodo_de_classe</em><tt>
</tt><em>    <span class="s"><span class="dl">"</span><span class="k">sou um metodo de classe</span><span class="dl">"</span></span></em><tt>
</tt><em>  <span class="r">end</span></em><tt>
</tt><span class="r"><em>end</em></span><tt>
</tt></pre>
<p>Criar um método a partir de “self” significa que o método está disponível apenas à classe e não às suas instâncias. Novamente, para ser mais fácil de comparar, pense em métodos estáticos de classe como em Java. Mas entenda que não é a mesma coisa: em Java ou C# as classes são estruturas estáticas, em Ruby a própria classe é um objeto (pois ela é instância da classe &#8220;Class&#8221;). Outra maneira de escrever a mesma coisa seria:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em><span class="r">class</span> <span class="cl">Pessoa</span></em><tt>
</tt><em>  <span class="r">def</span> <span class="fu">metodo_de_instancia</span></em><tt>
</tt><em>    <span class="s"><span class="dl">"</span><span class="k">sou um metodo de instancia</span><span class="dl">"</span></span></em><tt>
</tt><em>  <span class="r">end</span></em><tt>
</tt><tt>
</tt><em>  <span class="r">class</span> &lt;&lt; <span class="cl">self</span></em><tt>
</tt><em>    <span class="r">def</span> <span class="fu">metodo_de_classe</span></em><tt>
</tt><em>      <span class="s"><span class="dl">"</span><span class="k">sou um metodo de classe</span><span class="dl">"</span></span></em><tt>
</tt><em>    <span class="r">end</span></em><tt>
</tt><em>  <span class="r">end</span></em><tt>
</tt><span class="r"><em>end</em></span><tt>
</tt></pre>
<p>A diferença é que em vez de escrever “def self.” o tempo todo, podemos simplesmente reabrir a metaclasse da classe Pessoa e escrever todos os métodos “localmente” ali dentro. Em ambos os casos a classe vai se comportar da seguinte forma:</p>
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><em>&gt;&gt; p = <span class="co">Pessoa</span>.new</em><tt>
</tt><em>=&gt; <span class="c">#&lt;Pessoa:0x1775370&gt;</span></em><tt>
</tt><tt>
</tt><em>&gt;&gt; p.metodo_de_instancia</em><tt>
</tt><em>=&gt; <span class="s"><span class="dl">"</span><span class="k">sou um metodo de instancia</span><span class="dl">"</span></span></em><tt>
</tt><tt>
</tt><em>&gt;&gt; p.metodo_de_classe</em><tt>
</tt><em><span class="co">NoMethodError</span>: undefined method </em><span class="sh"><span class="dl"><em>`</em></span><span class="k"><em>metodo_de_classe' for #&lt;Pessoa:0x1775370&gt;</em><tt>
</tt><em>  from (irb):94</em><tt>
</tt><tt>
</tt><em>&gt;&gt; Pessoa.metodo_de_instancia</em><tt>
</tt><em>NoMethodError: undefined method </em></span><span class="dl"><em>`</em></span></span><em>metodo_de_instancia</em><span class="s"><span class="dl"><em>'</em></span><span class="k"><em> for Pessoa:Class</em><tt>
</tt><em>  from (irb):95</em><tt>
</tt><tt>
</tt><em>&gt;&gt; Pessoa.metodo_de_classe</em><tt>
</tt><em>=&gt; "sou um metodo de classe"</em></span></span></pre>
<p>Não perca a Parte II deste artigo para entender o básico da linguagem Ruby. Espero que até aqui tenha ficado bastante claro que não devemos tentar codificar Ruby da mesma forma que codificamos em outras linguagens estáticas. Tirem proveito do dinamismo dessa linguagem, é assim que fazemos o “The Ruby Way”.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.debugando.com/micro-tutorial-de-ruby-parte-i/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Acessando configurações do banco de dados no Rails</title>
		<link>http://www.debugando.com/acessando-configuracoes-do-banco-de-dados-no-rails/</link>
		<comments>http://www.debugando.com/acessando-configuracoes-do-banco-de-dados-no-rails/#comments</comments>
		<pubDate>Mon, 08 Dec 2008 12:52:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Banco de Dados]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.debugando.com/?p=127</guid>
		<description><![CDATA[Toda aplicação Rails possui o arquivo config/database.yml, onde você configura a conexão com o banco de dados nos ambientes de produção, desenvolvimento e teste. O Rails se encarrega de realizar a conexão com o banco de dados quando a aplicação é iniciada (com o WEBrick, por exemplo).
E como fazer caso seja necessário, no seu contexto, [...]]]></description>
			<content:encoded><![CDATA[<p>Toda aplicação Rails possui o arquivo <code>config/database.yml</code>, onde você configura a conexão com o banco de dados nos ambientes de produção, desenvolvimento e teste. O Rails se encarrega de realizar a conexão com o banco de dados quando a aplicação é iniciada (com o WEBrick, por exemplo).</p>
<p>E como fazer caso seja necessário, no seu contexto, ter acesso ao username e password presentes nesse arquivo? Acredito que esses dados não estejam disponíveis em nenhum dos objetos que o Rails instancia (eu procurei), certamente por questões de segurança, mas se você realmente precisa carregar esses dados, eis aqui uma forma bem simples.</p>
<p>De preferência dentro de um controller da sua aplicação (como o <code>ApplicationController</code>), você pode definir esta linha:</p>
<pre><code><em>class ApplicationController &lt; ActiveRecord::Base
  @@db_config = YAML.load_file("#{RAILS_ROOT}/config/database.yml")
               [RAILS_ENV]
end</em>
</code></pre>
<p>Agora você tem em <code>@@db_config</code> um hash (cujas chaves são strings, e não símbolos) com tudo aquilo que você precisa. Digamos que seu <code>config/database.yml</code> tivesse esta cara:</p>
<pre><code><em>production:
  adapter: mysql
  database: teste_production
  username: teste
  password: teste
  timeout: 5000

development:
  adapter: mysql
  database: teste_development
  username: teste
  password: teste
  timeout: 5000</em>
</code></pre>
<p>Se o servidor da aplicação está rodando em modo de desenvolvimento, então a constante <code>RAILS_ENV</code> guarda <code>development</code>. Por conseqüência, <code>@@db_config['database']</code>, por exemplo, guarda <code>teste_development</code>.</p>
<p>Por ter sido declarada no escopo de classe de <code>ApplicationController</code>, nesse exemplo <code>@@db_config</code> estaria disponível em todos os métodos de todos os seus controllers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.debugando.com/acessando-configuracoes-do-banco-de-dados-no-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Open Source Rails</title>
		<link>http://www.debugando.com/open-source-rails/</link>
		<comments>http://www.debugando.com/open-source-rails/#comments</comments>
		<pubDate>Fri, 05 Dec 2008 12:02:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Projetos]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.debugando.com/?p=81</guid>
		<description><![CDATA[O OpenSouce Rails é um site dedicado a disponibilizar projetos desenvolvidos em Rails. Nele você irá encontrar uma grande variedades de aplicações Rails, podendo baixar para estudos ou até mesmo utilizar em seus projetos.

É uma grande iniciativa open source e com certeza vale a pena conhecer, então fica aí a dica!
]]></description>
			<content:encoded><![CDATA[<p>O <a onclick="javascript:urchinTracker ('/outbound/article/www.opensourcerails.com');" href="http://www.opensourcerails.com/" target="_blank">OpenSouce Rails</a> é um site dedicado a disponibilizar projetos desenvolvidos em Rails. Nele você irá encontrar uma grande variedades de aplicações Rails, podendo baixar para estudos ou até mesmo utilizar em seus projetos.<br />
<img class="alignnone size-full wp-image-526" title="OpenSource Rails" src="http://www.fernandoquadro.com.br/html/wp-content/uploads/2008/06/osrails.png" alt="OpenSource Rails" width="300" height="38" /><br />
É uma grande iniciativa open source e com certeza vale a pena conhecer, então fica aí a dica!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.debugando.com/open-source-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

