<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>1up4Developers</title>
	
	<link>http://1up4dev.org</link>
	<description>Nadando contra o Waterfall. tail -f /mind/realworld &gt;&gt; /blog</description>
	<lastBuildDate>Thu, 29 Jul 2010 04:27:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/1up4dev/OfrU" /><feedburner:info uri="1up4dev/ofru" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>A extinção do programador sênior</title>
		<link>http://feedproxy.google.com/~r/1up4dev/OfrU/~3/HLBZk1fX7DY/</link>
		<comments>http://1up4dev.org/2010/07/a-extincao-do-programador-senior/#comments</comments>
		<pubDate>Thu, 29 Jul 2010 04:21:38 +0000</pubDate>
		<dc:creator>Humberto</dc:creator>
				<category><![CDATA[real world]]></category>

		<guid isPermaLink="false">http://1up4dev.org/?p=700</guid>
		<description><![CDATA[Quando foi a última vez em que você viu um programador sênior? Eu tenho tido sérias dificuldades para encontrar algum. Acho que se estivesse procurando ararinhas azuis teria tido mais sucesso &#8212; será que alguma toparia programar? Desconfio que não. Consciente da causa ecológica, ela me diria: cada ararinha programando toma o lugar de um [...]]]></description>
			<content:encoded><![CDATA[<p>Quando foi a última vez em que você viu um programador sênior? Eu tenho tido sérias dificuldades para encontrar algum. Acho que se estivesse procurando ararinhas azuis teria tido mais sucesso &#8212; será que alguma toparia programar? Desconfio que não. Consciente da causa ecológica, ela me diria: cada ararinha programando toma o lugar de um programador sênior, que é de uma espécie muito mais em risco do que eu. E bateria as asas em retirada.</p>
<p>É claro que, ao contrário da <a title="Cyanopsitta spixii" href="http://pt.wikipedia.org/wiki/Ararinha-azul" target="_blank">pobre arara</a>, o programador sênior ainda existe, e em grandes quantidades. Mas algo deu errado na evolução da sua espécie que, ao invés de melhorar, foi substituída por uma variedade mais fácil de reproduzir, bem adaptada ao cativeiro, de comportamento dócil, capaz de passar anos fazendo a mesma coisa e com duas opções de cor: terno preto ou azul. E que, curiosamente, não consegue programar. Eu já vou batizando essa variedade de <em>programador senhor</em>.</p>
<p>Estou falando por experiência própria. A <a href="http://www.alohapos.com.br/" target="_blank">empresa em que eu trabalho</a> está recrutando um &#8220;programador sênior&#8221; há alguns meses. Dada a indisponibilidade dos colegas no nosso <em>networking</em> (o que nos pouparia um grande tempo), resolvemos apelar e buscar no mercadão de trabalho (vulgo apinfo, catho, essas coisas). Nós filtramos dezenas de currículos, conduzimos entrevistas, aplicamos testes. Com isso, conseguimos achar diversos programadores <em>senhores</em> mas nenhum propriamente <em>sênior</em>. A maioria tinha 10+ anos de carreira, 30+ anos de idade e -1 noção para bolar respostas satisfatórias para questões como:</p>
<ol>
<li>Como dois programas podem se comunicar?</li>
<li>O que são threads?</li>
<li>Implemente o <a href="http://imranontech.com/2007/01/24/using-fizzbuzz-to-find-developers-who-grok-coding/" target="_blank">fizz buzz</a> na linguagem que preferir.</li>
</ol>
<p>E assim por diante. Nada muito específico: preferimos encontrar gente que tivesse convivido com certos problemas, independente da tecnologia adotada. Gente demonstrasse <em>senioridade</em> propriamente dita: maturidade, bom senso, raciocínio, segurança. E conhecimento suficiente para não achar que a chave de todos os problemas é uma consulta ao Google (houve quem confessasse isso). Não encontramos essa gente ainda, mas em compensação vimos muitas pessoas bem intencionadas, certamente esforçadas, mas com imensas dificuldades para concatenar opiniões a respeito de conceitos que julgamos básicos e, no nosso negócio, fundamentais.</p>
<p>Sequer exigimos que o candidato conheça tópicos como controle de versão, orientação a objetos, design patterns, agilidade e etcetera, que são sinais mais do que evidentes de maturidade. Já entendemos que tudo isso está além dos limites do habitat do programador senhor. São coisas tão exóticas quanto um programador sênior genuíno, que só deve existir em áreas de proteção ambiental, como este blog.</p>
<p>(Às araras azuis que estiverem interessadas no recrutamento: por ora concluímos o processo, mas não deixem de <a href="mailto:humberto.bulhoes@gmail.com">entrar em contato</a>.)</p>
<img src="http://feeds.feedburner.com/~r/1up4dev/OfrU/~4/HLBZk1fX7DY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://1up4dev.org/2010/07/a-extincao-do-programador-senior/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://1up4dev.org/2010/07/a-extincao-do-programador-senior/</feedburner:origLink></item>
		<item>
		<title>Gerando rotas com parâmetros dinâmicos no Rails de modo fácil</title>
		<link>http://feedproxy.google.com/~r/1up4dev/OfrU/~3/lXcMy-J9f1Q/</link>
		<comments>http://1up4dev.org/2010/07/gerando-rotas-com-parametros-dinamicos-no-rails-de-modo-facil/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 09:00:23 +0000</pubDate>
		<dc:creator>Rodrigo Panachi</dc:creator>
				<category><![CDATA[quick tips]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://1up4dev.org/?p=680</guid>
		<description><![CDATA[A API de rotas do Rails simplifica consideravelmente o desenvolvimento fornecendo um padrão de geração e utilização de URLs para toda aplicação. Porém algumas necessidades especificas e relativamente simples podem gerar dores de cabeça se forem implementadas incorretamente.
Um caso bastante comum são URLs compostas que sempre apontam para um mesmo recurso. Por exemplo, um blog que [...]]]></description>
			<content:encoded><![CDATA[<p>A <a href="http://api.rubyonrails.org/classes/ActionController/Routing.html">API de rotas</a> do Rails simplifica consideravelmente o desenvolvimento fornecendo um padrão de geração e utilização de URLs para toda aplicação. Porém algumas necessidades especificas e relativamente simples podem gerar dores de cabeça se forem implementadas incorretamente.</p>
<p>Um caso bastante comum são URLs compostas que sempre apontam para um mesmo recurso. Por exemplo, um blog que possua rotas para seus posts no formato <code>/posts/autor/categoria/permalink</code> provavelmente terá uma rota mapeada como <code>map.post "posts/:author/:category/:permalink"</code> gerando automaticamente os helpers <code>post_path</code> e <code>post_url</code>.</p>
<p>Muito bom, porém para <a href="http://guides.rubyonrails.org/routing.html#generating-urls-from-code">usufruirmos desta facilidade</a> precisamos fornecer os valores dos parâmetros dinâmicos nos <em>controllers</em> e <em>views</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">post_path<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:author</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@post</span>.<span style="color:#9900CC;">author</span>, <span style="color:#ff3333; font-weight:bold;">:category</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@post</span>.<span style="color:#9900CC;">category</span>, <span style="color:#ff3333; font-weight:bold;">:permalink</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@post</span>.<span style="color:#9900CC;">permalink</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>E mesmo que você forneça os <a href="http://guides.rubyonrails.org/routing.html#route-generation-from-arrays">parâmetros em um array</a>, vai dar muito trabalho além de deixar muito código repetido pela aplicação.</p>
<h2>Entendi! Mas como resolvo este problema?</h2>
<p>Para este caso, apenas implementar o método <code><a href="http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M001840">to_param</a></code> do model não vai servir. Uma solução seria reescrever o método <code>post_path</code> (que é gerado automaticamente) no respectivo helper (posts_helper.rb):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> post_path<span style="color:#006600; font-weight:bold;">&#40;</span>post, options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">super</span><span style="color:#006600; font-weight:bold;">&#40;</span>post, <span style="color:#ff3333; font-weight:bold;">:author</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> post.<span style="color:#9900CC;">author</span>, <span style="color:#ff3333; font-weight:bold;">:category</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> post.<span style="color:#9900CC;">category</span>, <span style="color:#ff3333; font-weight:bold;">:permalink</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> post.<span style="color:#9900CC;">permalink</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Outra solução seria sobrescrever o método <code><a href="http://api.rubyonrails.org/classes/ActionController/Base.html#M000467">default_url_options</a></code> no <em>controller</em> para retorna os parâmetros padrões da rota:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> default_url_options<span style="color:#006600; font-weight:bold;">&#40;</span>options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  options.<span style="color:#9900CC;">merge</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:author</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@post</span>.<span style="color:#9900CC;">author</span>, <span style="color:#ff3333; font-weight:bold;">:category</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@post</span>.<span style="color:#9900CC;">category</span>, <span style="color:#ff3333; font-weight:bold;">:permalink</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@post</span>.<span style="color:#9900CC;">permalink</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:action</span><span style="color:#006600; font-weight:bold;">&#93;</span> == <span style="color:#996600;">&quot;show&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>A má notícia é que você terá que fazer isto para todos seus controllers e respectivos models.</p>
<p>A terceira solução (e mais elegante) é padronizar a maneira com que os parâmetros opcionais da rota são obtidos a partir do controller e seu respectivo model. Basta adicionar os seguintes métodos no seu <em>ApplicationController</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> default_url_options<span style="color:#006600; font-weight:bold;">&#40;</span>options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>model = controller_model<span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    dynamic_route_params<span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>param<span style="color:#006600; font-weight:bold;">|</span>
      options<span style="color:#006600; font-weight:bold;">&#91;</span>param<span style="color:#006600; font-weight:bold;">&#93;</span> = model.<span style="color:#9900CC;">send</span><span style="color:#006600; font-weight:bold;">&#40;</span>param<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> model.<span style="color:#9900CC;">respond_to</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>param<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  options
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> controller_model<span style="color:#006600; font-weight:bold;">&#40;</span>options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  clazz = <span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:controller</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">singularize</span>.<span style="color:#9900CC;">camelize</span>.<span style="color:#9900CC;">constantize</span> <span style="color:#9966CC; font-weight:bold;">rescue</span> ActiveRecord<span style="color:#006600; font-weight:bold;">&#41;</span>
  options.<span style="color:#CC0066; font-weight:bold;">select</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>key, value<span style="color:#006600; font-weight:bold;">|</span> value.<span style="color:#9900CC;">is_a</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>clazz<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">first</span>.<span style="color:#9900CC;">second</span>
<span style="color:#9966CC; font-weight:bold;">rescue</span>
  <span style="color:#0000FF; font-weight:bold;">nil</span>
<span style="color:#9966CC; font-weight:bold;">end</span> 
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> dynamic_route_params<span style="color:#006600; font-weight:bold;">&#40;</span>options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  returning <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>dynamic_params<span style="color:#006600; font-weight:bold;">|</span>
    matched_routes = <span style="color:#6666ff; font-weight:bold;">ActionController::Routing::Routes</span>.<span style="color:#9900CC;">routes</span>.<span style="color:#CC0066; font-weight:bold;">select</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>route<span style="color:#006600; font-weight:bold;">|</span>
      route.<span style="color:#9900CC;">matches_controller_and_action</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:controller</span><span style="color:#006600; font-weight:bold;">&#93;</span>, options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:action</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    dynamic_segments = matched_routes.<span style="color:#9900CC;">map</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>:segments<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">flatten</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>segment<span style="color:#006600; font-weight:bold;">|</span>
      dynamic_params <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> segment.<span style="color:#9900CC;">key</span> <span style="color:#9966CC; font-weight:bold;">if</span> segment.<span style="color:#9900CC;">is_a</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#6666ff; font-weight:bold;">ActionController::Routing::DynamicSegment</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <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;">end</span></pre></div></div>

<p>Assim, os valores defaults dos parâmetros da rota serão obtidos diretamente do model. Caso queiram contribuir, este código está disponível no <a href="http://github.com/1up4dev/random-samples/blob/master/dynamic_route_params/dynamic_route_params.rb">github</a>.</p>
<p><strong>Referências</strong><br />
<a href="http://railsguts.com/routing_inside_out.html">Rails Routing from the Inside Out</a><br />
<a href="http://guides.rubyonrails.org/routing.html">Rails Guides: Routing</a></p>
<img src="http://feeds.feedburner.com/~r/1up4dev/OfrU/~4/lXcMy-J9f1Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://1up4dev.org/2010/07/gerando-rotas-com-parametros-dinamicos-no-rails-de-modo-facil/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://1up4dev.org/2010/07/gerando-rotas-com-parametros-dinamicos-no-rails-de-modo-facil/</feedburner:origLink></item>
		<item>
		<title>Active Record em: Como adicionar comportamento as suas associações</title>
		<link>http://feedproxy.google.com/~r/1up4dev/OfrU/~3/EqKnR8UQIU8/</link>
		<comments>http://1up4dev.org/2010/05/active-record-em-como-adicionar-comportamento-as-suas-associacoes/#comments</comments>
		<pubDate>Wed, 19 May 2010 13:14:18 +0000</pubDate>
		<dc:creator>Roger Leite</dc:creator>
				<category><![CDATA[quick tips]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[real world]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[active record]]></category>
		<category><![CDATA[pragmatismo]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://1up4dev.org/?p=657</guid>
		<description><![CDATA[Qualquer um que comece a desenvolver com Active Record (AR), minha primeira recomendação é, para tudo e leia:  A Guide to Active Record Associations ou O Guia de Associações do Active Record. O guia é bem completo, e descreve muito bem os tipos de associações que estão disponíveis no AR.
Association Proxy, #wtf !
As associações:

belongs_to
has_one
has_many
has_and_belongs_to_many

Quando usadas, [...]]]></description>
			<content:encoded><![CDATA[<p>Qualquer um que comece a desenvolver com <a href="http://api.rubyonrails.org/files/vendor/rails/activerecord/README.html">Active Record</a> (AR), minha primeira recomendação é, para tudo e leia:  <a href="http://guides.rubyonrails.org/association_basics.html">A Guide to Active Record Associations</a> ou <a href="http://guias.rubyonrails.pro.br/association_basics.html">O Guia de Associações do Active Record</a>. O guia é bem completo, e descreve muito bem os tipos de associações que estão disponíveis no AR.</p>
<h2>Association Proxy, #wtf !</h2>
<p>As associações:</p>
<ul>
<li>belongs_to</li>
<li>has_one</li>
<li>has_many</li>
<li>has_and_belongs_to_many</li>
</ul>
<p>Quando usadas, adicionam alguns métodos (veja <a href="http://guides.rubyonrails.org/association_basics.html#detailed-association-reference">Detailed Association Reference</a>). Por exemplo, ao declarar uma associação <em>belongs_to</em>, o model &#8220;ganhará&#8221; os seguintes métodos:</p>
<ul>
<li>association(force_reload = false)</li>
<li>association=(associate)</li>
<li>build_association(attributes = {})</li>
<li>create_association(attributes = {})</li>
</ul>
<p>Onde association, será substituído pelo nome da associação. Exemplo retirado do guides:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Order <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
   belongs_to <span style="color:#ff3333; font-weight:bold;">:customer</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Cada instância de Order, conterá os métodos:</p>
<p><span style="font-size: small;"> </span></p>
<ul>
<li>customer</li>
<li>customer=</li>
<li>build_customer</li>
<li>create_customer</li>
</ul>
<p>O <em>association proxy</em>, é o objeto que faz a ligação do objeto que contém a associação, conhecido como <em>owner</em>, e o objeto associado, conhecido como <em>target</em>.</p>
<h2>Legal e daí !?!</h2>
<p>Graças ao <em>association proxy</em>, ao declarar uma associação, podemos extendê-la e adicionar comportamentos &#8220;customizados&#8221;. No guia, é citado como <a href="http://guides.rubyonrails.org/association_basics.html#association-extensions">Association Extensions</a>. O código de exemplo abaixo, está no github em <a href="http://github.com/rogerleite/random-samples">random-samples</a>.</p>
<p>Para exemplificar, vamos criar um modulo que adiciona o comportamento de uma galeria a qualquer coleção.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">module</span> GalleryColletion
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> current=<span style="color:#006600; font-weight:bold;">&#40;</span>curr = <span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@current</span>, <span style="color:#0066ff; font-weight:bold;">@index</span> = <span style="color:#0000FF; font-weight:bold;">nil</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">if</span> curr.<span style="color:#0000FF; font-weight:bold;">nil</span>?
      <span style="color:#0066ff; font-weight:bold;">@current</span> = collection.<span style="color:#9900CC;">first</span>
      <span style="color:#0066ff; font-weight:bold;">@index</span> = <span style="color:#006666;">0</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      collection.<span style="color:#9900CC;">each_with_index</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>item, index<span style="color:#006600; font-weight:bold;">|</span>
        <span style="color:#9966CC; font-weight:bold;">if</span> item.<span style="color:#9900CC;">id</span>.<span style="color:#9900CC;">to_i</span> == curr.<span style="color:#9900CC;">to_i</span>
          <span style="color:#0066ff; font-weight:bold;">@current</span> = item
          <span style="color:#0066ff; font-weight:bold;">@index</span> = index
        <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;">end</span>
    <span style="color:#0066ff; font-weight:bold;">@current</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> current
    <span style="color:#0066ff; font-weight:bold;">@current</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> position
    <span style="color:#0066ff; font-weight:bold;">@index</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> previous?
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">false</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@index</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
    !!<span style="color:#006600; font-weight:bold;">&#40;</span>@index <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span> <span style="color:#006600; font-weight:bold;">&gt;</span>= <span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> previous
    collection<span style="color:#006600; font-weight:bold;">&#91;</span>@index <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">if</span> previous?
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#9966CC; font-weight:bold;">next</span>?
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">false</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@index</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
    !!<span style="color:#006600; font-weight:bold;">&#40;</span>@index <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span> <span style="color:#006600; font-weight:bold;">&lt;</span> collection.<span style="color:#9900CC;">size</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#9966CC; font-weight:bold;">next</span>
    collection<span style="color:#006600; font-weight:bold;">&#91;</span>@index <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#9966CC; font-weight:bold;">next</span>?
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  private
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> collection
    proxy_owner.<span style="color:#9900CC;">send</span><span style="color:#006600; font-weight:bold;">&#40;</span>proxy_reflection.<span style="color:#9900CC;">name</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p><a href="http://github.com/rogerleite/random-samples/blob/master/association_extend/lib/extensions/gallery_collection.rb">Gallery Collection</a></p>
<p>Note que o modulo está na pasta lib, logo, a pasta tem que ser adicionada no path via config/environment.rb.</p>
<p>Para extender a associação, declare:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Article <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  has_and_belongs_to_many <span style="color:#ff3333; font-weight:bold;">:images</span>, <span style="color:#ff3333; font-weight:bold;">:extend</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> GalleryColletion
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p><a href="http://github.com/rogerleite/random-samples/blob/master/association_extend/app/models/article.rb">Article model</a>, <a href="http://github.com/rogerleite/random-samples/blob/master/association_extend/app/models/image.rb">Image model aqui</a>.</p>
<p>Agora para navegar entre as imagens, você pode usar:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">a = Article.<span style="color:#9900CC;">first</span>
a.<span style="color:#9900CC;">images</span>.<span style="color:#9900CC;">current</span> = <span style="color:#006666;">1</span> <span style="color:#008000; font-style:italic;">#1 e o Image.id que deseja selecionar</span>
a.<span style="color:#9900CC;">images</span>.<span style="color:#9900CC;">current</span>
a.<span style="color:#9900CC;">images</span>.<span style="color:#9900CC;">position</span>
a.<span style="color:#9900CC;">images</span>.<span style="color:#9966CC; font-weight:bold;">next</span>?
a.<span style="color:#9900CC;">images</span>.<span style="color:#9966CC; font-weight:bold;">next</span>
a.<span style="color:#9900CC;">images</span>.<span style="color:#9900CC;">previous</span>?
a.<span style="color:#9900CC;">images</span>.<span style="color:#9900CC;">previous</span></pre></div></div>

<p>Caso esteja com coragem, baixe o projeto e veja rodando.</p>
<p>Dúvidas, sugestões, algum &#8220;case&#8221; de sucesso, comente!</p>
<img src="http://feeds.feedburner.com/~r/1up4dev/OfrU/~4/EqKnR8UQIU8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://1up4dev.org/2010/05/active-record-em-como-adicionar-comportamento-as-suas-associacoes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://1up4dev.org/2010/05/active-record-em-como-adicionar-comportamento-as-suas-associacoes/</feedburner:origLink></item>
		<item>
		<title>Teste sua aplicação de Linha de Comando com Cucumber!</title>
		<link>http://feedproxy.google.com/~r/1up4dev/OfrU/~3/oFGysyxfu4Y/</link>
		<comments>http://1up4dev.org/2010/05/teste-sua-aplicacao-de-linha-de-comando-com-cucumber/#comments</comments>
		<pubDate>Fri, 14 May 2010 10:00:21 +0000</pubDate>
		<dc:creator>Roger Leite</dc:creator>
				<category><![CDATA[projetos]]></category>
		<category><![CDATA[quick tips]]></category>
		<category><![CDATA[real world]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[linha de comando]]></category>
		<category><![CDATA[rake]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://1up4dev.org/?p=643</guid>
		<description><![CDATA[É engraçado como tudo é questão de treino e disciplina. Levei um tempo para me acostumar com TDD, Vim e não poderia ser diferente com testes funcionais, sendo mais especifico, Cucumber.
Até o momento, só tinha usado cucumber em projetos web. E quando voltei a desenvolver o rubygems_snapshot, senti falta de algo para testar funcionalmente. Baseado [...]]]></description>
			<content:encoded><![CDATA[<p>É engraçado como tudo é questão de treino e disciplina. Levei um tempo para me acostumar com <a href="http://en.wikipedia.org/wiki/Test-driven_development">TDD</a>, <a href="http://www.vim.org/">Vim</a> e não poderia ser diferente com testes funcionais, sendo mais especifico, <a href="http://cukes.info/">Cucumber</a>.</p>
<p>Até o momento, só tinha usado cucumber em projetos web. E quando voltei a desenvolver o <a href="http://github.com/rogerleite/rubygems_snapshot">rubygems_snapshot</a>, senti falta de algo para testar funcionalmente. Baseado no <a href="http://github.com/vertiginous/pik">pik</a>, montei um esquema simples para validar qualquer aplicação de linha de comando.</p>
<h2>Como instalar</h2>
<p>Basicamente, será necessário (fontes via gist):</p>
<ul>
<li>rake para executar o cucumber</li>
<li>env_terminal.rb</li>
<li>terminal_steps.rb</li>
</ul>
<p><script src="http://gist.github.com/400069.js"></script></p>
<p>Dado que você tem cucumber instalado, com o esquema da pasta &#8220;features&#8221;.</p>
<ul>
<li>Copie o cucumber.rake para a raiz.</li>
<li>Copie o env_terminal.rb para a pasta features.</li>
<li>Copie o terminal_steps.rb para a pasta features/step_definitions/terminal_steps.rb.</li>
<li>Edite o  env.rb incluindo (pode ser no começo):</li>
</ul>
<pre>require "env_terminal"</pre>
<ul>
<li>Dentro do Rakefile, pode ser no final mesmo, adicione:</li>
</ul>
<pre>load "cucumber.rake"</pre>
<h2>Como usar</h2>
<p>Todas features:</p>
<pre>rake cucumber</pre>
<p>Features com a tag @wip, também conhecida como Work in Progress.</p>
<pre>rake cucumber:wip</pre>
<h2>Informações Extras</h2>
<p>Caso precise de mais informações, você tem a opção de ver a saída dos comandos, executando a rake assim:</p>
<pre>rake cucumber show_output=true</pre>
<p>ou</p>
<pre>rake cucumber:wip show_output=true</pre>
<p>No caso do snapshot, tive a necessidade de &#8220;modificar&#8221; o comando gem toda vez que era executado, ou melhor, passar um parâmetro para controlar o ambiente. Dentro do env_terminal.rb, existe o método <strong>gsub_command</strong>, nele você pode &#8220;redefinir&#8221; comandos, caso necessite.</p>
<h2><strong>Gostei, quero mais!</strong></h2>
<p>A solução acima, é bem &#8220;caseira&#8221;. Para projetos simples com funcionalidades simples, funciona bem.</p>
<p>Caso queira algo mais robusto, você tem a opção da <a href="http://github.com/aslakhellesoy/aruba">gem Aruba</a>.</p>
<p>Tem este post como introdução:</p>
<p><a href="http://www.themodestrubyist.com/2010/04/22/aruba---cucumber-goodness-for-the-command-line/">Aruba &#8211; Cucumber Goodness for the Command-Line</a></p>
<img src="http://feeds.feedburner.com/~r/1up4dev/OfrU/~4/oFGysyxfu4Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://1up4dev.org/2010/05/teste-sua-aplicacao-de-linha-de-comando-com-cucumber/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://1up4dev.org/2010/05/teste-sua-aplicacao-de-linha-de-comando-com-cucumber/</feedburner:origLink></item>
		<item>
		<title>Rubygems Snapshot! Importando/Exportando gems com velocidade!</title>
		<link>http://feedproxy.google.com/~r/1up4dev/OfrU/~3/RbDspE5BJps/</link>
		<comments>http://1up4dev.org/2010/05/rubygems-snapshot-importandoexportando-gems-com-velocidade/#comments</comments>
		<pubDate>Mon, 10 May 2010 13:53:17 +0000</pubDate>
		<dc:creator>Roger Leite</dc:creator>
				<category><![CDATA[projetos]]></category>
		<category><![CDATA[quick tips]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[gems]]></category>
		<category><![CDATA[gems export]]></category>
		<category><![CDATA[gems import]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[rubygems]]></category>

		<guid isPermaLink="false">http://1up4dev.org/?p=637</guid>
		<description><![CDATA[Nova versão do Rubygems_Snapshot no ar!
Fico feliz em dizer que este é o meu primeiro projeto que passou dos dez &#8220;watchers&#8221; !   E que realmente ajudou alguns developers mundo afora.
A primeira versão foi muito focada no uso pessoal, como &#8220;quebra-galho&#8221; mesmo. Resolvi investir algum tempo e praticamente refaze-lá, pois ao usar no dia-a-dia [...]]]></description>
			<content:encoded><![CDATA[<p>Nova versão do <a href="http://github.com/rogerleite/rubygems_snapshot">Rubygems_Snapshot</a> no ar!</p>
<p>Fico feliz em dizer que este é o meu primeiro projeto que passou dos dez &#8220;watchers&#8221; ! <img src='http://1up4dev.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  E que realmente ajudou alguns developers mundo afora.</p>
<p>A primeira versão foi muito focada no uso pessoal, como &#8220;quebra-galho&#8221; mesmo. Resolvi investir algum tempo e praticamente refaze-lá, pois ao usar no dia-a-dia percebi algumas falhas e dificuldades de uso.</p>
<p>Basicamente, nesta nova versão:</p>
<p>- É possível trabalhar com mais de um formato. Yml e Tar, que é o padrão.</p>
<p>- Ao exportar, os arquivos &#8220;.gem&#8221; serão exportados.</p>
<p>- Ao importar, ocorre praticamente uma instalação &#8220;offlline&#8221;, muito mais rápido e livre de problemas com &#8220;sources&#8221; do rubygem !</p>
<p>- Usar o Snapshot como API !</p>
<p>Como tive um trabalhão para deixar o Readme legal, não pretendo escrever mais que isso! <img src='http://1up4dev.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p><a href="http://github.com/nofxx">Marcos</a>, valeu pelo incentivo! Cara, forka lá e manda bala!</p>
<img src="http://feeds.feedburner.com/~r/1up4dev/OfrU/~4/RbDspE5BJps" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://1up4dev.org/2010/05/rubygems-snapshot-importandoexportando-gems-com-velocidade/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://1up4dev.org/2010/05/rubygems-snapshot-importandoexportando-gems-com-velocidade/</feedburner:origLink></item>
		<item>
		<title>Importando e exportando suas gems com Rubygems Snapshot</title>
		<link>http://feedproxy.google.com/~r/1up4dev/OfrU/~3/2xy8SDDBnKY/</link>
		<comments>http://1up4dev.org/2009/12/importando-e-exportando-suas-gems-com-rubygems-snapshot/#comments</comments>
		<pubDate>Tue, 22 Dec 2009 16:24:09 +0000</pubDate>
		<dc:creator>Roger Leite</dc:creator>
				<category><![CDATA[projetos]]></category>
		<category><![CDATA[quick tips]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[rubygems]]></category>

		<guid isPermaLink="false">http://1up4dev.org/?p=618</guid>
		<description><![CDATA[Final de ano está rendendo.
O rubygems_snapshot nasceu da necessidade de &#8220;migrar&#8221; as gems instaladas de uma máquina para outra, aliado ao rvm (veja este post-guia-rápido), permite mudar e/ou criar diferentes ambientes em minutos. Assim você pode fugir do famoso &#8220;gem hell&#8221;.
Veja como é difícil usar:
Instalação:
sudo gem install rubygems_snapshot
Para exportar as gems instaladas:
gem snapshot export projeto-exemplo.yml
Supondo [...]]]></description>
			<content:encoded><![CDATA[<p>Final de ano está rendendo.<br />
O <a href="http://github.com/rogerleite/rubygems_snapshot">rubygems_snapshot</a> nasceu da necessidade de &#8220;migrar&#8221; as gems instaladas de uma máquina para outra, aliado ao <a href="http://rvm.beginrescueend.com/">rvm</a> (veja este <a href="http://www.nuxlli.com.br/2009/11/24/para-tudo-instale-o-rvm-antes/">post-guia-rápido</a>), permite mudar e/ou criar diferentes ambientes em minutos. Assim você pode fugir do <span style="text-decoration: line-through;">famoso</span> &#8220;gem hell&#8221;.</p>
<p>Veja como é difícil usar:</p>
<p>Instalação:</p>
<pre>sudo gem install rubygems_snapshot</pre>
<p>Para <strong>exportar</strong> as gems instaladas:</p>
<pre>gem snapshot export projeto-exemplo.yml</pre>
<p>Supondo que esteja em outra máquina, para <strong>importar</strong> as gems, use:</p>
<pre>[sudo] gem snapshot import projeto-exemplo.yml</pre>
<h2>Afinal, o que tem de legal nisso?</h2>
<p>Vamos supor que você acaba de entrar numa nova equipe e tem que montar o ambiente de desenvolvimento (por sinal, um ambiente complicado de configurar). O gem snapshot aliada ao rvm, foi feito para facilitar isto, vamos a um exemplo rápido:</p>
<p>Com o rvm, você pode criar um &#8220;novo ambiente&#8221;:</p>
<pre>rvm use 1.8.7%projeto_exemplo</pre>
<pre>gem list</pre>
<p>Deve retornar vazio.</p>
<pre>gem install rubygems_snapshot</pre>
<pre>gem snapshot import projeto-exemplo.yml</pre>
<p>Instalará as gems necessárias para o projeto e pronto!</p>
<h2>ToDo:</h2>
<p>Esta é uma versão bem básica, onde o &#8220;import&#8221; somente lê as gem e version e manda instalar sem requerir dependências. Está previsto de colocar um aviso no final das gems que deram erro, geralmente devido a dependências de &#8220;build nativos&#8221;, mas por enquanto estamos usando aqui na equipe com sucesso.</p>
<h2>Como faço para criar um rubygems plugin também?</h2>
<p>Bom, logo de cara posso te garantir que não é difícil (apesar da pouca documentação na internet), mas deixarei os detalhes para um outro post. Por enquanto, a minha recomendação é: clone o projeto, analise os dois rb do projeto <img src='http://1up4dev.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  e crie o seu!</p>
<p>Caso algum corajoso for usar, estou a disposição para ajudar, é só deixar um comentário aê!<br />
Valeu e sucesso!</p>
<img src="http://feeds.feedburner.com/~r/1up4dev/OfrU/~4/2xy8SDDBnKY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://1up4dev.org/2009/12/importando-e-exportando-suas-gems-com-rubygems-snapshot/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://1up4dev.org/2009/12/importando-e-exportando-suas-gems-com-rubygems-snapshot/</feedburner:origLink></item>
		<item>
		<title>Agile Enterprise Edition</title>
		<link>http://feedproxy.google.com/~r/1up4dev/OfrU/~3/PAK6UAvwyHA/</link>
		<comments>http://1up4dev.org/2009/12/agile-enterprise-edition/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 09:00:08 +0000</pubDate>
		<dc:creator>Rodrigo Panachi</dc:creator>
				<category><![CDATA[questionamento]]></category>
		<category><![CDATA[real world]]></category>
		<category><![CDATA[agilidade]]></category>
		<category><![CDATA[corporativismo]]></category>
		<category><![CDATA[metodologia]]></category>
		<category><![CDATA[pragmatic waterfall]]></category>
		<category><![CDATA[scrum]]></category>

		<guid isPermaLink="false">http://1up4dev.org/?p=560</guid>
		<description><![CDATA[Para começar o post, segue esta história sobre gerenciamento que vi no blog do Gustavo Ribeiro:
Todos os dias, uma formiga chegava cedinho ao escritório e pegava duro no trabalho. A formiga era produtiva e feliz. O gerente marimbondo estranhou a formiga trabalhar sem supervisão. Se ela era produtiva sem supervisão, seria ainda mais se fosse [...]]]></description>
			<content:encoded><![CDATA[<p>Para começar o post, segue esta história sobre <em>gerenciamento</em> que vi no blog do <a href="http://gustavoribeiro.com/blog/gerenciamento" target="_blank">Gustavo Ribeiro</a>:</p>
<blockquote><p>Todos os dias, uma formiga chegava cedinho ao escritório e pegava duro no trabalho. A formiga era produtiva e feliz. O gerente marimbondo estranhou a formiga trabalhar sem supervisão. Se ela era produtiva sem supervisão, seria ainda mais se fosse supervisionada.</p>
<p>E colocou uma barata, que preparava belíssimos relatórios e tinha muita experiência, como supervisora. A primeira preocupação da barata foi a de padronizar o horário de entrada e saída da formiga.</p>
<p>Logo, a barata precisou de uma secretária para ajudar a preparar os relatórios e contratou também uma aranha para organizar os arquivos e controlar as ligações telefônicas.</p>
<p>O marimbondo ficou encantado com os relatórios da barata e pediu também gráficos com indicadores e análise das tendências que eram mostradas em reuniões.</p>
<p>A barata, então, contratou uma mosca, e comprou um computador com impressora colorida. Logo, a formiga produtiva e feliz, começou a se lamentar de toda aquela movimentação de papéis e reuniões!<br />
O marimbondo concluiu que era o momento de criar a função de gestor para a área onde a formiga produtiva e feliz, trabalhava. O cargo foi dado a uma cigarra, que mandou colocar carpete no seu escritório e comprar uma cadeira especial.</p>
<p>A nova gestora cigarra logo precisou de um computador e de uma assistente (sua assistente na empresa anterior) para ajudá-la a preparar um plano estratégico de melhorias e um controle do orçamento para a área onde trabalhava a formiga, que já não cantarolava mais e cada dia se tornava mais chateada.</p>
<p>A cigarra, então, convenceu o gerente marimbondo, que era preciso fazer um estudo de clima. Mas, o marimbondo, ao rever as cifras, se deu conta de que a unidade na qual a formiga trabalhava já não rendia como antes e contratou a coruja, uma prestigiada consultora, muito famosa, para que fizesse um diagnóstico da situação. A coruja permaneceu três meses nos escritórios e emitiu um volumoso relatório, com vários volumes que concluía: &#8220;Há muita gente nesta empresa!&#8221;</p>
<p>Então o marimbondo mandou demitir a formiga porque ela andava muito desmotivada e aborrecida.</p></blockquote>
<p>Então lembrei de uma imagem que ilustra perfeitamente esta fábula e retrata fielmente a &#8220;organização&#8221; de alguma empresas:</p>
<p style="text-align: center;"><a href="http://1up4dev.org/wp-content/uploads/2009/07/trabalho_em_equipe.jpg"><img class="aligncenter" title="trabalho_em_equipe" src="http://1up4dev.org/wp-content/uploads/2009/07/trabalho_em_equipe-222x300.jpg" alt="" width="222" height="300" /></a></p>
<h2>Dividir para conquistar: você está fazendo isso errado!</h2>
<p>Quando uma <em>startup</em> passa a vender mais e ter uma procura maior por seus produtos/serviços (o que é bom), uma reação comum da &#8220;cúpula&#8221; é aumentar o quadro de funcionários visando atender a demanda. Logo surgem os problemas com a organização do pessoal e/ou fluxo de trabalho. A solução mais simplista (e óbvia) é a especialização: fulano faz isso, ciclano faz aquilo, e beltrano gerencia. Logo controles são criados, fluxos validados, centros de custo, documentos, reuniões, atas, comitês, gestão de pessoas e relacionamento, terceirização, cargos, departamentos&#8230; e nasce o monstro da <a href="http://pt.wikipedia.org/wiki/Burocracia">burocracia</a>, aka &#8220;enterprise&#8221;.</p>
<p>Com essa <a href="http://en.wikipedia.org/wiki/Enterprise_architecture">especialização</a>, cada &#8220;módulo&#8221; (também conhecido como departamento) começa a perder o foco no GRANDE objetivo da empresa e passa a defender apenas <a href="http://1up4dev.org/2008/11/os-guardioes-da-cascata">seus interesses</a> &#8211; a famosa MISSÃO da empresa passa a ser coadjuvante. O resultado? A empresa dobra ou triplica seu quadro de funcionários e na maioria dos casos, seu lucro bruto. Porém agora tem mais despesas com pessoal e gastos extras para manter  esse novo modelo &#8220;enterprise&#8221;. Trocando em miúdos, continua na mesma!</p>
<p>Onde está o erro? Mais uma vez o FOCO está na <a href="http://1up4dev.org/2008/11/foco-no-problema/">solução</a> ao invés de PROBLEMA. Se você ler meus posts anteriores vai ver que este é um tema recorrente. Então por que as empresas continuam fazendo as coisas erradas e cometendo os mesmos erros?</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/R47Xe8kVrv0&amp;hl=pt_BR&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/R47Xe8kVrv0&amp;hl=pt_BR&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>Idéias criativas surgem das pessoas <a href="http://blog.aspercom.com.br/2008/07/21/hierarquias-sao-inteligentes-nas-pontas/">diretamente</a> relacionadas com os problemas e não de diretores, contadores, gestores, etc. Esse modelo &#8220;enterprise&#8221; é um <em>overhead</em> organizacional que só gera ruído e desperdício!</p>
<h2>A solução é adotar agile!</h2>
<p>SOLUÇÃO!? Mas qual era o PROBLEMA mesmo!? Sim, mais uma vez o foco é a <a href="http://agilesoftwaredevelopment.com/blog/janusz-gorycki/agile-dead">solução</a> ao invés do problema.</p>
<p>Como eu disse nos posts anteriores, acreditar que uma mudança drástica do processo pode mudar a cultura da empresa e pincipalmente as pessoas é o maior erro na adoção de metodologias ágeis. Mudam o processo mas não mudam as pessoas.</p>
<p>De uma forma simples e direta, agile resume-se a quatro valores:</p>
<blockquote><p>Individuals and interactions over processes and tools<br />
Working software over comprehensive documentation<br />
Customer collaboration over contract negotiation<br />
Responding to change over following a plan</p></blockquote>
<p>Ou seja, pessoas, software, colaboração e feedback. Simples assim!</p>
<p>O manifesto ágil não cita nada sobre &#8220;enterprise&#8221;, sobre a implementação. Este é o grande desafio em sua adoção. Como seguir estes valores sem burocratizar e engessar o processo? Como criar uma relação de colaboração com os clientes? Como responder rapidamente a mudanças? Como eliminar o esforço que não agrega valor ao produto e/ou empresa? Como evitar politicagem?</p>
<h2>Mantenha-se pequeno!</h2>
<p>Otimize! Busque soluções para os problemas que impedem de produzir mais e com mais qualidade. Faça MAIS com MENOS. Foque no O QUE ao invés do COMO. Escale as pessoas verticalmente!</p>
<p>Inove! Não espere conseguir resultados diferentes fazendo sempre a mesma coisa. Busque novidades, opniões, experiências. Ouça seus funcionários, seus clientes. Estude, pesquise, arrisque, erre, acerte&#8230; continuamente.</p>
<p>Mantenha o foco! Tenha um GRANDE e único objetivo e certifique-se que todos acreditem nesta filosofia. É importante que todos comprem a idéia e o <em>modus operandis</em>.</p>
<p>Finalizando, este é apenas meu ponto de vista, baseado na minha experiência em diversas empresas grandes e pequenas, vivenciando problemas, errando muito e principalmente aprendendo com os erros dos outros. Agilidade pode funcionar bem em grandes corporações, desde que haja foco e que todos comprem a idéia. Você pode concordar ou não.</p>
<img src="http://feeds.feedburner.com/~r/1up4dev/OfrU/~4/PAK6UAvwyHA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://1up4dev.org/2009/12/agile-enterprise-edition/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://1up4dev.org/2009/12/agile-enterprise-edition/</feedburner:origLink></item>
		<item>
		<title>Ruby, Rubygems e $LOAD_PATH ou Como funciona o require de gems</title>
		<link>http://feedproxy.google.com/~r/1up4dev/OfrU/~3/V4Jrd6kZUXk/</link>
		<comments>http://1up4dev.org/2009/12/ruby-rubygems-e-load_path-ou-como-funciona-o-require-de-gems/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 10:30:15 +0000</pubDate>
		<dc:creator>Roger Leite</dc:creator>
				<category><![CDATA[quick tips]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[load_path]]></category>
		<category><![CDATA[rubygems]]></category>

		<guid isPermaLink="false">http://1up4dev.org/?p=589</guid>
		<description><![CDATA[Na madrugada passada, andei &#8220;brincando&#8221; com o fonte do Rubygems. Logo de cara posso te dizer que não consegui fazer o que queria, e pra amenizar o sentimento de &#8220;perda de tempo&#8221;, resolvi postar alguns truques aprendidos.
Baixei o fonte do rubygems, como faço pra rodá-lo sem alterar o meu sistema?
Foi a primeira pergunta que fiz. [...]]]></description>
			<content:encoded><![CDATA[<p>Na madrugada passada, andei &#8220;brincando&#8221; com o fonte do <a href="http://rubyforge.org/projects/rubygems/">Rubygems</a>. Logo de cara posso te dizer que não consegui fazer o que queria, e pra amenizar o sentimento de &#8220;perda de tempo&#8221;, resolvi postar alguns truques aprendidos.</p>
<h2>Baixei o fonte do rubygems, como faço pra rodá-lo sem alterar o meu sistema?</h2>
<p>Foi a primeira pergunta que fiz. Percebi que com o google não iria encontrar a resposta, mas consegui uma dica importante: $LOAD_PATH.</p>
<pre>$ irb</pre>
<pre>irb(main):001:0&gt; $LOAD_PATH</pre>
<p>No meu Ubuntu, obtive:</p>
<pre>["/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/i486-linux", "/usr/local/lib/site_ruby/1.8/i386-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i486-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i486-linux", "/usr/lib/ruby/1.8/i386-linux", "."]</pre>
<pre>$ ls /usr/local/lib/site_ruby/1.8/</pre>
<p>Exatamente nesta pasta que se encontra o rubygems.rb. Bingo!<br />
Para rodar o fonte do rubygems, só é necessário adicionar ao $LOAD_PATH a pasta lib do projeto. Dado que estou na raiz do projeto rubygems baixado, execute:</p>
<pre>~/rubygems$ ruby -I $PWD/lib ./bin/gem -v</pre>
<p>O paramêtro -I permite adicionar diretório ao $LOAD_PATH. Simples e prático. Primeiro problema resolvido, comecei a programar.</p>
<h2>Afinal, como funciona o &#8220;require de gems&#8221;?</h2>
<p>Bom, já sabemos que o require &#8220;rubygems&#8221; fuciona pois encontra-se no $LOAD_PATH do ruby, no caso do meu Ubuntu em &#8220;/usr/local/lib/site_ruby/1.8&#8243;.</p>
<p>Basicamente (e muito), o Rubygems faz duas coisas no Kernel do Ruby.</p>
<ul>
<li>Adiciona o metodo Kernel#gem.</li>
<li>Faz um <a href="http://en.wikipedia.org/wiki/Monkey_patch">Monkey Patch</a> no Kernel#require</li>
</ul>
<h3>Kernel#gem</h3>
<p>Permite &#8220;acionar&#8221; uma versão específica de gem. Note que este acionar, traduz-se para, adicionar a lib da gem no $LOAD_PATH. Segue um trecho do comentário do Kernel#gem:</p>
<p style="padding-left: 30px;">##</p>
<p style="padding-left: 30px;"># Use Kernel#gem to activate a specific version of +gem_name+.</p>
<p style="padding-left: 30px;">#</p>
<p style="padding-left: 30px;"># +version_requirements+ is a list of version requirements that the</p>
<p style="padding-left: 30px;"># specified gem must match, most commonly &#8220;= example.version.number&#8221;.  See</p>
<p style="padding-left: 30px;"># Gem::Requirement for how to specify a version requirement.</p>
<p style="padding-left: 30px;">#</p>
<p style="padding-left: 30px;"># If you will be activating the latest version of a gem, there is no need to</p>
<p style="padding-left: 30px;"># call Kernel#gem, Kernel#require will do the right thing for you.</p>
<p style="padding-left: 30px;">#</p>
<p style="padding-left: 30px;"># Kernel#gem returns true if the gem was activated, otherwise false.  If the</p>
<p style="padding-left: 30px;"># gem could not be found, didn&#8217;t match the version requirements, or a</p>
<p style="padding-left: 30px;"># different version was already activated, an exception will be raised.<br />
[...]</p>
<h3>Kernel#require</h3>
<p>No final do rubygems.rb encontramos:</p>
<p>if RUBY_VERSION &lt; &#8216;1.9&#8242; then</p>
<p>require &#8216;rubygems/custom_require&#8217;</p>
<p>end</p>
<p>Não consegui descobrir o que acontece com o ruby 1.9, mas no 1.8, o monkey patch executa os seguintes passos:</p>
<ul>
<li>Chama o &#8220;original&#8221; require;</li>
<li>Em caso de LoadError;
<ul>
<li>Executa o &#8220;Gem.searcher.find(path)&#8221;;</li>
<li>Se <em>true</em>
<ul>
<li>Chama o activate (novamente traduz-se para adiciona a gem no $LOAD_PATH)</li>
<li>Executa o &#8220;original&#8221; require novamente;</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>Exemplos com o IRB</h3>
<p>Para finalizar legal e comprovar tudo isso, fiz alguns testes:</p>
<pre>$ gem list json</pre>
<p style="padding-left: 30px;">*** LOCAL GEMS ***</p>
<p style="padding-left: 30px;">json (1.2.0, 1.1.9)</p>
<p style="padding-left: 30px;">json_pure (1.2.0)</p>
<p style="padding-left: 30px;">
<pre>$ irb</pre>
<pre>irb(main):001:0&gt; $LOAD_PATH</pre>
<p style="padding-left: 30px;">=&gt; ["/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/i486-linux", "/usr/local/lib/site_ruby/1.8/i386-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i486-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i486-linux", "/usr/lib/ruby/1.8/i386-linux", "."]</p>
<pre>irb(main):004:0&gt; require "json"</pre>
<p style="padding-left: 30px;">LoadError: no such file to load &#8212; json</p>
<p style="padding-left: 30px;">from (irb):4:in `require&#8217;</p>
<p style="padding-left: 30px;">from (irb):4</p>
<p style="padding-left: 30px;">from :0</p>
<pre>irb(main):005:0&gt; gem "json", "= 1.2.0"</pre>
<p style="padding-left: 30px;">NoMethodError: undefined method `gem&#8217; for main:Object</p>
<p style="padding-left: 30px;">from (irb):5<br />
from :0</p>
<p>O require &#8220;json&#8221; por si só, carrega a versão mais atual da gem.</p>
<pre>irb(main):006:0&gt; require "rubygems"</pre>
<p>=&gt; true</p>
<pre>irb(main):007:0&gt; require "json"</pre>
<p>=&gt; true</p>
<pre>irb(main):008:0&gt; JSON::VERSION</pre>
<p>=&gt; &#8220;1.2.0&#8243;</p>
<pre>irb(main):009:0&gt; $LOAD_PATH</pre>
<p>=&gt; ["/usr/lib/ruby/gems/1.8/gems/gemcutter-0.1.8/lib", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/bin", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/ext/json/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/lib", "/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/i486-linux", "/usr/local/lib/site_ruby/1.8/i386-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i486-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i486-linux", "/usr/lib/ruby/1.8/i386-linux", "."]</p>
<pre>irb(main):010:0&gt; quit</pre>
<p>Após o require &#8220;json&#8221;, as pastas foram adicionadas no $LOAD_PATH.</p>
<pre>"/usr/lib/ruby/gems/1.8/gems/json-1.2.0/bin", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/ext/json/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.2.0/lib"</pre>
<p>Agora olhe que <strong>interessante</strong> este <strong>último teste</strong>:</p>
<pre>$ irb

irb(main):001:0&gt; require "rubygems"</pre>
<p>=&gt; true</p>
<pre>irb(main):002:0&gt; $LOAD_PATH</pre>
<p>=&gt; ["/usr/lib/ruby/gems/1.8/gems/gemcutter-0.1.8/lib", "/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/i486-linux", "/usr/local/lib/site_ruby/1.8/i386-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i486-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i486-linux", "/usr/lib/ruby/1.8/i386-linux", "."]</p>
<pre>irb(main):003:0&gt; gem "json", "= 1.1.9"</pre>
<p>=&gt; true</p>
<pre>irb(main):004:0&gt; $LOAD_PATH</pre>
<p>=&gt; ["/usr/lib/ruby/gems/1.8/gems/gemcutter-0.1.8/lib", "/usr/lib/ruby/gems/1.8/gems/json-1.1.9/bin", "/usr/lib/ruby/gems/1.8/gems/json-1.1.9/ext/json/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.1.9/ext", "/usr/lib/ruby/gems/1.8/gems/json-1.1.9/lib", "/usr/local/lib/site_ruby/1.8", "/usr/local/lib/site_ruby/1.8/i486-linux", "/usr/local/lib/site_ruby/1.8/i386-linux", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/1.8", "/usr/lib/ruby/vendor_ruby/1.8/i486-linux", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/1.8", "/usr/lib/ruby/1.8/i486-linux", "/usr/lib/ruby/1.8/i386-linux", "."]</p>
<pre>irb(main):005:0&gt; JSON</pre>
<p>NameError: uninitialized constant JSON<br />
from (irb):5</p>
<pre>irb(main):006:0&gt; require "json"</pre>
<p>=&gt; true</p>
<pre>irb(main):007:0&gt; JSON::VERSION</pre>
<p>=&gt; &#8220;1.1.9&#8243;</p>
<pre>irb(main):008:0&gt; quit</pre>
<p>Note que após o gem &#8220;json&#8221;, &#8220;= 1.1.9&#8243; &#8230; a versao 1.1.9 foi adicionada no $LOAD_PATH mas não foi carregada. Ao executar o require &#8220;json&#8221;, como este já estava no $LOAD_PATH, a versão 1.1.9 é usada.</p>
<p>Espero que com estas explicações, você use com mais segurança o rubygems.</p>
<img src="http://feeds.feedburner.com/~r/1up4dev/OfrU/~4/V4Jrd6kZUXk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://1up4dev.org/2009/12/ruby-rubygems-e-load_path-ou-como-funciona-o-require-de-gems/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://1up4dev.org/2009/12/ruby-rubygems-e-load_path-ou-como-funciona-o-require-de-gems/</feedburner:origLink></item>
		<item>
		<title>Rails Summit 2009</title>
		<link>http://feedproxy.google.com/~r/1up4dev/OfrU/~3/vv432dHKuVc/</link>
		<comments>http://1up4dev.org/2009/10/rails-summit-2009/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 13:21:22 +0000</pubDate>
		<dc:creator>Rodrigo Panachi</dc:creator>
				<category><![CDATA[eventos]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[railssummit]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://1up4dev.org/?p=558</guid>
		<description><![CDATA[Estamos de volta depois de algumas semanas de correria e muito trabalho, o que nos impediu de postar sobre vários assuntos atuais e experiências recentes. Também migramos de empresa. Agora o Roger e eu estamos trabalhando em uma empresa maior, focada em conteúdo digital, desenvolvendo aplicações de grande porte com Ruby e Rails  
O [...]]]></description>
			<content:encoded><![CDATA[<p>Estamos de volta depois de algumas semanas de correria e muito trabalho, o que nos impediu de postar sobre vários assuntos atuais e experiências recentes. Também migramos de empresa. Agora o <a href="http://1up4dev.org/author/rogerbarreto/">Roger</a> e eu estamos trabalhando em uma empresa maior, focada em conteúdo digital, desenvolvendo aplicações de grande porte com Ruby e Rails <img src='http://1up4dev.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h1>O evento</h1>
<p>Se você não soube do <a href="http://www.railssummit.com.br/">Rails Summit 2009</a> ou não sabe nem o que é Rails recomendo que acesse <a href="http://pbskids.org/teletubbies/">este site</a>. Deixando o sarcasmo de lado, a edição 2009 do Rails Summit foi muito boa. As palestras foram excelentes (com algumas poucas exceções). Os coffe-breaks e as <a href="http://github.com/railssummit/morena_opensource/tree/master/RailsSummit2009/">locagirls</a> também!</p>
<p><img class="alignnone size-full wp-image-567" title="Rails Summit 2009 Locaweb" src="http://1up4dev.org/wp-content/uploads/2009/10/4013425175_68b7b78b6f_original.jpg" alt="Rails Summit 2009 Locaweb" width="500" height="333" /></p>
<p>Quem não conseguiu ir este ano pode conferir o que aconteceu e assistir a algumas palestras nos seguintes links:</p>
<p><a href="http://github.com/leonardoborges/railssummit09">http://akitaonrails.com/2009/10/17/rails-summit-2009-retrospectiva</a></p>
<p><a href="http://andrefaria.com/2009/10/15/rails-summit-2009-chad-fowler/">http://andrefaria.com/2009/10/15/rails-summit-2009-chad-fowler/</a></p>
<p><a href="http://andrefaria.com/2009/10/19/rails-summit-gregg-pollack/">http://andrefaria.com/2009/10/19/rails-summit-gregg-pollack/</a></p>
<p><a href="http://marciotrindade.com/2009/10/13/rails-summit-2009-parte-1">http://marciotrindade.com/2009/10/13/rails-summit-2009-parte-1</a></p>
<p><a href="http://marciotrindade.com/2009/10/14/rails-summit-2009-parte-2">http://marciotrindade.com/2009/10/14/rails-summit-2009-parte-2</a></p>
<p><a href="http://marciotrindade.com/2009/10/16/rails-summit-2009-parte-3">http://marciotrindade.com/2009/10/16/rails-summit-2009-parte-3</a></p>
<h1>Rails não escala</h1>
<p>Das palestras técnicas, focadas em Ruby e Rails, destaco a do <a href="http://blog.envylabs.com">Gregg Pollac</a>: On The Edge of Rails Performance, que falou sobre algumas <a href="http://andrefaria.com/2009/10/19/rails-summit-gregg-pollack/">ferramentas e plugins</a> para ajudar a melhorar a performance de aplicações Rails.</p>
<p>O estreiante <a href="http://m.onkey.org/2009/10/18/railssummit-slides">Pratik Naik</a> também deu algumas dicas muito boas para melhoar a performance e falou um bouco sobre suas experiências com Rails.</p>
<p>Para finalizar, o <a href="http://brunomiranda.com/">Bruno Miranda</a> fechou falando sobre sua experiência com o desenvolvimento do <a href="http://br.msn.cyloop.com/">Cyloop</a>, uma rede social de música, mostrando os problemas enfrentados com escalabilidade e as estratégias utilizadas para resolvê-los.</p>
<p>E claro que não podia deixar de falar da excelente palestra do <a href="http://www.slideshare.net/fabiokung/dsls-internas-e-ruby">Fábio Kung</a> sobre metaprogramação com Ruby, apresentando um hands-on, ou seja, &lt;faustao&gt;quem sabe faz ao vivo&lt;/faustao&gt;, para criar uma DSL em Ruby e outras técnicas de magia negra como <a href="http://coderrr.wordpress.com/2008/11/22/super-simple-callbacks-in-ruby/">Callbacks</a>, que pretendo abordar com mais detalhes aqui no blog.</p>
<p>Resumindo, projetar aplicações Rails escaláveis não é uma tarefa trivial e deve ser pensada com muito cuidado. Pretendo explorar mais este assunto nos próximos posts do blog.</p>
<h1>Agilidade a seu favor</h1>
<p>Apesar de ser um evento sobre Rails, um tema predominante foi agile. A <a href="http://andrefaria.com/2009/10/15/rails-summit-2009-chad-fowler/">largada</a> foi dada pelo <a href="http://chadfowler.com/">Chad Fowler</a> que falou sobre a insurgência Ruby on Rails, incentivando o movimento ágil a &#8220;quebrar as regras&#8221;, <a href="http://chadfowler.com/2006/12/27/the-big-rewrite">parar de fazer as coisas que sabemos que estão erradas</a>! Também ressaltou que é preciso ter coragem e atitude para rejeitar os moldes corporativos e lutar contra os <a href="http://akitaonrails.com/2009/03/30/off-topic-net-negative-producing-programmer">trolls</a>, os <a href="http://1up4dev.org/2008/11/os-guardioes-da-cascata/">guardiões da cascata</a>.</p>
<p>O <a href="http://akitaonrails.com/">Akita</a> realmente surpreendeu com sua <a href="http://vimeo.com/7099091">palestra</a> &#8220;Agile, beyond chaos&#8221;. Explicou os princípios do <a href="http://agilemanifesto.org/">manifesto ágil</a> e comprovou cientificamente o &#8220;porque&#8221; agile funciona!</p>
<p>A palestra sobre empreendedorismo do <a href="http://improveit.com.br/empresa/vinicius">Vinícius Teles</a> foi uma verdadeira aula, contando um pouco da sua história, as dificuldades e obstáculos superados até conseguir transformar o <a href="http://beonthe.net/">Be on the Net</a> em realidade. Resumindo: ganhe dinheiro fazendo o que você gosta e ajudando as outras pessoas a ganhar dinheiro!</p>
<p>Finalizando com chave de ouro, o <a href="http://obiefernandez.com/">Obie Fernandez</a> falou sobre a &#8220;arte&#8221; do desenvolvimento de aplicações. Assim como um artista que precisa praticar muito para atingir a excelência, um programador precisa praticar e codificar muito&#8230; &#8220;O que você está esperando? Fuck the enterprise!&#8221;</p>
<p>Resumindo, falou-se muito sobre agilidade usando ruby e rails como uma ferramenta pragmática. As empresas de software sérias já estão usando Ruby. É a <a href="http://1up4dev.org/2009/08/ruby-quando-a-linguagem-de-programacao-faz-diferenca/">linguagem ideal para o modelo ágil</a>.</p>
<h2>Comentários do Roger</h2>
<p>Tomei a liberdade de adicionar uma nota neste post do <a href="http://1up4dev.org/author/rodrigopanachi/">Panachi</a>, pois como participante do <a href="http://1up4dev.org/2008/10/rails-summit-eu-fui/">Rails Summit 2008</a>, resumidamente notei três coisas do evento:</p>
<ul>
<li>A infra estrutura do evento estava muito melhor, mais espaço, mais organização e sem o calor infernal do ano passado. Parabéns para o Akita e o pessoal da Locaweb pelo ótimo trabalho e evento mais uma vez!</li>
<li>Tivemos ótimas palestras técnicas sobre como melhorar a performance de aplicações Ruby!</li>
<li>Em 2008 a grande mensagem foi &#8220;Participe!&#8221;. Ficou bem claro a importância de participar de projetos e contribuir. Este ano, a grande mensagem foi &#8220;<em>Fuck the Enterprise!</em>&#8220;. <img src='http://1up4dev.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </li>
</ul>
<img src="http://feeds.feedburner.com/~r/1up4dev/OfrU/~4/vv432dHKuVc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://1up4dev.org/2009/10/rails-summit-2009/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://1up4dev.org/2009/10/rails-summit-2009/</feedburner:origLink></item>
		<item>
		<title>Ruby: quando a linguagem de programação faz diferença!</title>
		<link>http://feedproxy.google.com/~r/1up4dev/OfrU/~3/WJ_Qlhell38/</link>
		<comments>http://1up4dev.org/2009/08/ruby-quando-a-linguagem-de-programacao-faz-diferenca/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 11:25:58 +0000</pubDate>
		<dc:creator>Rodrigo Panachi</dc:creator>
				<category><![CDATA[rails]]></category>
		<category><![CDATA[real world]]></category>
		<category><![CDATA[agilidade]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://1up4dev.org/?p=545</guid>
		<description><![CDATA[Pretendo neste post falar um pouco da minha evolução na programação e como Ruby e Rails agregaram mais conhecimento e me tornaram um melhor desenvolvedor.
A gente se forma na faculdade e de repente estamos trabalhando como programador em alguma empresa de software. A primeira coisa que você vai concluir é que nada a maioria das [...]]]></description>
			<content:encoded><![CDATA[<p>Pretendo neste post falar um pouco da minha evolução na programação e como Ruby e Rails agregaram mais conhecimento e me tornaram um melhor desenvolvedor.</p>
<p>A gente se forma na <a href="http://gc.blog.br/2009/05/18/o-que-eu-acho-sobre-faculdades-de-informatica/" target="_blank">faculdade</a> e de repente estamos trabalhando como programador em alguma empresa de <a href="http://1up4dev.org/2008/10/software-e-sobre-investimento/" target="_blank">software</a>. A primeira coisa que você vai concluir é que <span style="text-decoration: line-through;">nada</span> a maioria das coisas que foram ensinadas na <a href="http://akitaonrails.com/2009/04/17/off-topic-devo-fazer-faculdade" target="_blank">faculdade</a> não se aplicam na vida real. Triste realidade&#8230;</p>
<p>Mas como um bom programador (que você é) logo começará a se questionar e se interessar por novos assuntos, aprender novos conceitos e técnicas de programação, pois você não se sentirá <a href="http://1up4dev.org/2008/06/a-importancia-de-estudar-constantemente/" target="_blank">confortável</a> fazendo as mesmas tarefas repetitivas ou que não sejam otimizadas.</p>
<h2>Orientação a objetos</h2>
<p>Nada de cachorrinhos ou pessoas com ações como andar, comer, etc. No mundo real, seus problemas são faturas, notas fiscais, relatórios, importadores de arquivos, planilhas&#8230; e por aí vai. Seu primeiro desafio será de entender a orientação a objetos de verdade. Mas não se preocupe se isto demorar um pouco pois logo a &#8220;lâmpada&#8221; acenderá e tudo ficará <a href="http://domaindrivendesign.org/" target="_blank">claro como o dia</a>.</p>
<h2>Linguagem e frameworks</h2>
<p>Agora você consegue modelar os objetos da sua aplicação mas se depara com assuntos técnicos que podem ser solucionados prontamente utilizando-se <a href="http://guilher.me/inovacao/frameworks-ageis-para-projetos-de-web20/" target="_blank">frameworks</a> e alguns recursos avançados da linguagem em questão. Logo você estará visitando os sites da documentação do Struts, do Hibernate, do Ant&#8230; e descobrirá que o nome <a href="http://www.apache.org/" target="_blank">Apache</a>, além de tribo indígena, é muito mais do que um servidor Web. Após muitas provas de conceito e algumas noites sem dormir, você será um programador muito produtivo e confiante.</p>
<h2>Análise e documentação</h2>
<p>Parabéns! Aqui você já pode ser considerado um desenvolvedor. Logo seu destaque na equipe será recompensado com mais trabalho <span style="text-decoration: line-through;">de corno</span> desafiador. Nesta fase sua empresa se parece com uma <a href="http://1up4dev.org/2009/04/agilidade-e-a-buzzword-do-momento/" target="_blank">padaria</a>: &#8220;Me vê meio quilo do relatório X&#8221;, &#8220;Faz dois webservices pra viagem!&#8221;, &#8220;Aí, saindo uma fornada de casos de uso&#8230;&#8221;, etc. Logo <a href="http://1up4dev.org/2008/11/os-guardioes-da-cascata/" target="_blank">alguém</a> tem a brilhante <a href="http://1up4dev.org/2008/11/arquiteto-cascateiro/" target="_blank">idéia</a> de &#8220;documentar&#8221; tudo desde uma simples alteração no CSS do sistema até complexos e numerosos <a href="http://blog.fragmental.com.br/2008/07/25/uh-eme-ele/" target="_blank">diagramas</a> e notações daquele novo sistema para integração. No começo a novidade até parece ser uma boa idéia, mas logo você vai <a href="http://1up4dev.org/2009/07/cuidado-com-casos-de-uso/" target="_blank">descobrir</a> que o que realmente importa é <a href="http://1up4dev.org/2008/11/foco-no-problema/" target="_blank">ouvir os problemas dos clientes</a>.</p>
<h2>Testes</h2>
<p>Se você não teve a sorte de ser orientado desde o começo da sua carreira sobre desenvolvimento guiado por testes, você aprende a importância de testes da melhor maneira possível: <a href="http://www.nomedojogo.com/2009/04/06/so-os-imaturos-nao-testam/" target="_blank">tomando na cabeça</a>! Os problemas começam a ficar mais claros. Você fica mais focado na tarefa que está desempenhando e felizmente também cresce profissionalmente com este aprendizado. Você se pergunta como conseguia desenvolver sem testes e por que a linguagem que você <a href="http://gc.blog.br/2008/10/19/java-e-ruim/" target="_blank">utiliza</a> não tem um suporte mais &#8220;nativo&#8221; a testes.</p>
<h2>Metodologia</h2>
<p>No decorrer da sua experiência você tentará desempenhar suas atividades de <a href="http://1up4dev.org/2008/10/a-perpetuacao-da-especie/" target="_blank">várias maneiras</a>. Quando você faz de tudo um pouco acha que o melhor seria fazer apenas uma tarefa específica mas depois descobre que estava enganado. Neste ponto você provavelmente já experimentou pelo menos duas metodologias de desenvolvimento e saberá identificar as vantagens e <a href="http://1up4dev.org/2008/06/guerrilha-agile-parte-1/" target="_blank">desvantagens</a> em cada uma.</p>
<h2>Agilidade</h2>
<p>Felizmente sua <a href="http://1up4dev.org/2009/01/tpw-dicas-para-a-qualidade-do-software/" target="_blank">experiência</a> o guia para um caminho mais <a href="http://1up4dev.org/2008/12/agilidade-cascateira/" target="_blank">ágil</a>. Após aprender e aplicar os mandamentos do <a href="http://agilemanifesto.org/" target="_blank">manifesto ágil</a> e aprimorar seus conceitos e habilidades técnicas, desenvolver aplicações torna-se uma tarefa &#8220;natural&#8221; que você desempenha com fluência independente da linguagem ou tecnologia utilizada. Suas maiores conquistas se resumem em conseguir contornar um problema tecnológico ou limitação da linguagem, negociar o escopo do projeto com o cliente, implementar a maior cobertura de testes possíveis, <a href="http://1up4dev.org/2009/02/tpw-testando-sistemas-legados-automatizando-build/" target="_blank">automatizar</a> processos durante o desenvolvimento, etc.</p>
<p>Neste ponto você começa a se questionar: o que devo fazer agora para <a href="http://akitaonrails.com/2009/07/23/tradu--o-o-que-faz-um-bom-programador" target="_blank">evoluir</a> profissionalmente?</p>
<h2>Ruby!</h2>
<p>Eis que você conhece Ruby e Rails. A linguagem parece estranha a primeira vista mas após algum tempo dedicado e muito estudo você descobre que é uma ferramenta muito poderosa e produtiva, onde você pode &#8220;fluir&#8221; com seu desenvolvimento. Você pensa no que quer fazer e faz! Escreve sua &#8220;feature&#8221;, implementa e roda! Simples e <a href="http://1up4dev.org/2009/04/business-bingo-generator/" target="_blank">divertido</a>!</p>
<p>Ruby e Rails vieram suprir uma necessidade e/ou carência dos desenvolvedores por <a href="http://www.nomedojogo.com/2009/05/06/como-ruby-on-rails-pode-o-tornar-um-programador-pior/" target="_blank">simplicidade</a>. Até seu surgimento, desenvolver aplicações nas linguagens populares do mercado era uma tarefa complicada e trabalhosa. Ruby é uma linguagem poderosa. Rails é simples e muito produtivo. Combinação perfeita!</p>
<p>O que você tá <a href="http://pt.wikipedia.org/wiki/Procrastinar" target="_blank">esperando</a>? <a href="http://why.nomedojogo.com/" target="_blank">Comece</a> agora <a href="http://akitaonrails.com/" target="_blank">mesmo</a> a <a href="http://www.rubyinside.com.br/" target="_blank">estudar</a> <a href="http://www.ruby-lang.org/" target="_blank">Ruby</a> e <a href="http://www.rubyonrails.pro.br/" target="_blank">Rails</a> e seja feliz!</p>
<p>UPDATE: para não causar confusão, alterei o título. Lembre-se: Ruby é linguagem e Rails é framework!</p>
<img src="http://feeds.feedburner.com/~r/1up4dev/OfrU/~4/WJ_Qlhell38" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://1up4dev.org/2009/08/ruby-quando-a-linguagem-de-programacao-faz-diferenca/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://1up4dev.org/2009/08/ruby-quando-a-linguagem-de-programacao-faz-diferenca/</feedburner:origLink></item>
	</channel>
</rss>
