<?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>Saga do programador &#187; block</title>
	<atom:link href="http://www.sagadoprogramador.com.br/tag/block/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sagadoprogramador.com.br</link>
	<description></description>
	<lastBuildDate>Thu, 22 Sep 2011 04:20:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>DRY e Blocos de Código com Ruby</title>
		<link>http://www.sagadoprogramador.com.br/2010/02/dry-e-blocos-de-codigo-com-ruby/</link>
		<comments>http://www.sagadoprogramador.com.br/2010/02/dry-e-blocos-de-codigo-com-ruby/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 02:54:22 +0000</pubDate>
		<dc:creator>Sergio Azevedo</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[Ruby para iniciantes]]></category>
		<category><![CDATA[aprenda ruby]]></category>
		<category><![CDATA[block]]></category>
		<category><![CDATA[blocos]]></category>
		<category><![CDATA[blocos de codigo ruby]]></category>
		<category><![CDATA[ruby block]]></category>
		<category><![CDATA[ruby blocks]]></category>

		<guid isPermaLink="false">http://www.sagadoprogramador.com.br/?p=451</guid>
		<description><![CDATA[O Iuri já mostrou num post anterior, como criar métodos (funções) em ruby. Sendo assim somos praticamente craques em construir funções ruby. Neste post vamos explorar recursos avançados e interessantes das funçoes ruby, para isso, utilizaremos um array com alguns nomes. Problema Inicial: Devemos criar um  método que seja capaz de percorrer um array, exibindo seus [...]]]></description>
			<content:encoded><![CDATA[<p>O <a href="http://twitter.com/iurims">Iuri</a> já mostrou num <a href="http://www.sagadoprogramador.com.br/2009/07/aprenda-ruby-parte-v-metodos/">post anterior</a>, como criar métodos (funções) em ruby. Sendo assim somos praticamente craques em construir funções ruby. Neste post vamos explorar recursos avançados e interessantes das funçoes ruby, para isso, utilizaremos um array com alguns nomes.</p>
<h2>Problema Inicial:</h2>
<p>Devemos criar um  método que seja capaz de percorrer um array, exibindo seus elementos. <em>(Ok, tudo bem nós sabemos que todo array possui um método each. Mas vamos fingir que esse kra não existe)</em></p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">lista = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;sergio&quot;</span>,<span style="color:#996600;">&quot;roberto&quot;</span>, <span style="color:#996600;">&quot;iuri&quot;</span>,<span style="color:#996600;">&quot;luiz&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">def</span> mostra_elementos<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC0066; font-weight:bold;">array</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">for</span> elemento <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#CC0066; font-weight:bold;">array</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> elemento
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
mostra_elementos<span style="color:#006600; font-weight:bold;">&#40;</span>lista<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Ótimo! Atingimos nosso objetivo. O codigo acima exibira os nomes contidos no array.</p>
<h2>Os requisitos mudaram:</h2>
<p>Agora nós queremos  percorrer o array exibindo cada um de seus elementos ao contrario, por exemplo, &#8220;sergio&#8221; será exibido como &#8220;oigres&#8221;. Podemos criar um novo método para isso, então vamos ao trabalho:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> mostra_elementos_ao_contrario<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC0066; font-weight:bold;">array</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">for</span> elemento <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#CC0066; font-weight:bold;">array</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> elemento.<span style="color:#9900CC;">reverse</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
mostra_elementos_ao_contrario<span style="color:#006600; font-weight:bold;">&#40;</span> lista <span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Perfeito! Mais uma vez concluímos nossa tarefa.</p>
<h2>DRY, mais um princípio de Desenvolvimento de Software:</h2>
<p>Os problemas anteriores envolviam operações com elementos de um array (uma lista), e assim acabamos criando dois métodos para resolver os problemas propostos. Existe um princípio de desenvolvimento de software que é focado em reduzir a repetição/duplicação de código, ele é conhecido como: <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">Don&#8217;t Repeat Yourself &#8211; (DRY)</a>. Este principio diz que:</p>
<blockquote>
<h4>&#8220;Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.&#8221;</h4>
</blockquote>
<p style="text-align: justify;">O que poderiamos traduzir como: <em>&#8220;Cada parte do conhecimento deve ter uma representação única e não ambigua dentro de um sistema&#8221;. </em>Desta forma utilizando o DRY para analisar as funções que escrevemos até agora, podemos notar que <em>a parte do conhecimento </em>de percorrer um array não possui <em>uma representação única</em> em nosso sistema. O ideal seria que o codigo de percorrer um array nao fosse mais repetido, e é exatamente nisso que vamos trabalhar agora.</p>
<h2>Aplicando o DRY</h2>
<p>A maneira mais simples de resolvemos o problema de duplicação do codigo de percorrer o array, é sem duvida realizar um refactor chamado <a href="http://sourcemaking.com/refactoring/extract-method">extract method</a>, e assim isolar a lógica de percorrer arrays em um método. Entao vamos lá:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> percorre_array<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC0066; font-weight:bold;">array</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">for</span> elemento <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#CC0066; font-weight:bold;">array</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">def</span> mostra_elementos<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC0066; font-weight:bold;">array</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
   percorre_array<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC0066; font-weight:bold;">array</span><span style="color:#006600; font-weight:bold;">&#41;</span>
   <span style="color:#CC0066; font-weight:bold;">puts</span> elemento
<span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">def</span> mostra_elementos_ao_contrario<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC0066; font-weight:bold;">array</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
  percorre_array<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">array</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> elemento.<span style="color:#9900CC;">reverse</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
lista = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;sergio&quot;</span>,<span style="color:#996600;">&quot;roberto&quot;</span>, <span style="color:#996600;">&quot;iuri&quot;</span>,<span style="color:#996600;">&quot;luiz&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
mostra_elementos<span style="color:#006600; font-weight:bold;">&#40;</span>lista<span style="color:#006600; font-weight:bold;">&#41;</span>
mostra_elementos_ao_contrario<span style="color:#006600; font-weight:bold;">&#40;</span>lista<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Pronto! Com este método que acabamos de criar eliminamos o problema de  repetição de código. Porém ao executar este programa receberemos uma mensagem de erro. O grande problema aqui é que agora os métodos <em>mostra_elementos </em>e <em>mostra_elementos_ao_contrario</em> não conseguem mais acessar cada elemento do array. Estes métodos agora usam a função percorre_array, e somente dentro desta função é que a variavel <em>elemento</em> existe. Neste ponto podemos pensar que, ou fazemos a coisa ficar DRY, ou fazemos o programa funcionar. Calma, com Ruby nos poderemos fazer isso funcionar e ainda ser DRY. Para isso só precisamos aprender a usar os famosos blocos do Ruby.</p>
<h2>Ruby block&#8217;s</h2>
<p>Com certeza você já ouviu, que tudo em ruby é objeto. Na verdade mesmo, quase tudo em Ruby é objeto, por exemplo blocos de código não são objetos. Mas o importante é  que  em Ruby podemos armazenar trechos de código em um objeto especial que se chama Proc. Veja:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">bloco = <span style="color:#CC0066; font-weight:bold;">Proc</span>.<span style="color:#9900CC;">new</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;sou um bloco de codigo&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
bloco.<span style="color:#9900CC;">call</span></pre></div></div>

<p>Acabamos de criar um objeto, que contem código, e fizemos isso utilizando Proc.new e fornecendo o código através das chaves  &#8221;{ }&#8221;. De posse de uma Proc, podemos executar o código que ela contem a qualquer momento. Basta pra isso usar o método call da Proc. No exemplo acima ao chamar <em>bloco.call </em>veremos o texto <em>s</em><em>ou um bloco de codigo<strong>.</strong><span style="font-style: normal;"> O interessante disso é que agora podemos passar </span> código </em> como parametro, veja um exemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> faco_o_que_mandar<span style="color:#006600; font-weight:bold;">&#40;</span> block <span style="color:#006600; font-weight:bold;">&#41;</span>
  block.<span style="color:#9900CC;">call</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
bloco = <span style="color:#CC0066; font-weight:bold;">Proc</span>.<span style="color:#9900CC;">new</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;sou um bloco de codigo&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
faco_o_que_mandar<span style="color:#006600; font-weight:bold;">&#40;</span>bloco<span style="color:#006600; font-weight:bold;">&#41;</span>
faco_o_que_mandar <span style="color:#CC0066; font-weight:bold;">Proc</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Mais um bloco&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>Mas podemos fazer como os rubistas fazem na maioria das vezes. Eles chamam a função e passam o bloco como parametro, para isso precisamos fazer uma pequena alteração em nossa função, basta colocar um <strong>&#038;</strong> a frente do nome do nosso parametro. Outra coisa é que geralmente os rubistas utilizam a plavara <strong>yield</strong> ao invés de coisas como <strong>bloco.call</strong>, vamos mudar isso também:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> faco_o_que_mandar<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#006600; font-weight:bold;">&amp;</span>block <span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">yield</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
faco_o_que_mandar <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;sou um bloco de codigo tipo rubista&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
faco_o_que_mandar <span style="color:#9966CC; font-weight:bold;">do</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;blocos do end sao usados quando vc quer&quot;</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;fazer coisas que precisem de mais de uma&quot;</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;linha =)&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>O grande barato é que agora escrevemos uma função que recebe e executa um código &#8220;visitante&#8221;. Este é um recurso muito poderoso, e é graças a ele que vamos conseguir resolver o problema de percorrer um array para fazer coisas diferentes com seus elementos, sem precisar repetir código.</p>
<h2>Tirando vantagem dos blocos</h2>
<p>Bem, nós já temos uma função que sabe andar em um array. Agora só precisamos fazer esta função receber um bloco de código &#8220;visitante&#8221; e assim teremos tudo resolvido. Vamos então ao trabalho:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> percorre_array<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC0066; font-weight:bold;">array</span>, <span style="color:#006600; font-weight:bold;">&amp;</span>block <span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">for</span> elemento <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#CC0066; font-weight:bold;">array</span>
    <span style="color:#9966CC; font-weight:bold;">yield</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
lista = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;sergio&quot;</span>,<span style="color:#996600;">&quot;roberto&quot;</span>, <span style="color:#996600;">&quot;iuri&quot;</span>,<span style="color:#996600;">&quot;luiz&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
percorre_array<span style="color:#006600; font-weight:bold;">&#40;</span>lista<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#CC0066; font-weight:bold;">puts</span> elemento <span style="color:#006600; font-weight:bold;">&#125;</span>
percorre_array<span style="color:#006600; font-weight:bold;">&#40;</span>lista<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#CC0066; font-weight:bold;">puts</span> elemento.<span style="color:#9900CC;">reverse</span> <span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p><em>Neste momento você pode estar se perguntando o porquê do bloco de código estar fora dos parênteses. Por mais estranho que possa parecer é desse jeito que funciona mesmo. Os blocos são informados depois dos parametros &#8220;convencionais&#8221;.</em></p>
<p>Agora seria ótimo se isso funcionasse, não é? Pena que não vai funcionar. Ao executar esse código veremos o seguinte erro: <span style="color: #ff0000;">undefined local variable or method `elemento&#8217; for main:Object (NameError).</span></p>
<p><span style="color: #ff0000;"><span style="color: #000000;">Repare no erro, ele diz que a variavel <em>elemento </em>não está definida. Isso aconteceu porque esta variavel é local do método <em>percorre_array</em>, ou seja só existe, e só é visivel naquele método. Nós precisamos manipular esta variavel, para que isto seja possível o método que <strong>possui</strong> a variavel precisa permitir que os blocos visitantes utilizem esta variavel. Fazer isso é simples, basta que no <strong>yield</strong> nos passemos a variavel em questão como parâmetro. </span></span></p>
<p><span style="color: #ff0000;"><span style="color: #000000;">Quando colocamos o  <strong>yield</strong> na função é como se dissesemos: &#8220;Rode o codigo visitante agora&#8221;. E quando colocamos a frente do <strong>yield</strong> parâmetros é como se dissessemos: &#8220;Ei código vistante, se você quiser pode usar estes caras aqui que eu tenho&#8221;. Vejamos como fica isso no nosso codigo:</span></span></p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> percorre_array<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC0066; font-weight:bold;">array</span>, <span style="color:#006600; font-weight:bold;">&amp;</span>block <span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">for</span> elemento <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#CC0066; font-weight:bold;">array</span>
    <span style="color:#008000; font-style:italic;">#agora estamos expondo a variavel elemento</span>
    <span style="color:#008000; font-style:italic;"># para o codigo visitante</span>
    <span style="color:#9966CC; font-weight:bold;">yield</span> elemento
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
lista = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;sergio&quot;</span>,<span style="color:#996600;">&quot;roberto&quot;</span>, <span style="color:#996600;">&quot;iuri&quot;</span>,<span style="color:#996600;">&quot;luiz&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#008000; font-style:italic;"># uma pequena alteracao é necessaria aqui</span>
percorre_array<span style="color:#006600; font-weight:bold;">&#40;</span>lista<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>elemento<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#CC0066; font-weight:bold;">puts</span> elemento <span style="color:#006600; font-weight:bold;">&#125;</span>
percorre_array<span style="color:#006600; font-weight:bold;">&#40;</span>lista<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>elemento<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> elemento.<span style="color:#9900CC;">reverse</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Agora sim o código funciona. A linha<em></em> <em>yield elemento</em>, tem o efeito de enviar para o bloco visitante a variavel <em>elemento </em>como parametro. Assim a cada iteracao do loop for um novo valor é enviado ao código visitante através da variavel <em>elemento.</em> Com isso nosso trabalho está terminado, implementamos as funcionalidades solicitadas, sem repetir código, e de quebra aprendemos sobre DRY e blocos de código em Ruby.</p>
<p>Bloco de código é um assunto bem interessante, e aqui nós abordamos só uma pequena parte. Tem ainda um lance de lambdas, enfim como disse antes o assunto é muito interessante, e se você quiser saber mais pode olhar um post do Anderson Leite sobre isso, <a href="http://andersonleiteblog.wordpress.com/2010/02/18/metaprogramacao-procs-lambdas-e/">o link é este</a>.</p>
<p>Abraços.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sagadoprogramador.com.br/2010/02/dry-e-blocos-de-codigo-com-ruby/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>

