<?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>Keep Learning &#187; Rails</title>
	<atom:link href="http://blog.lucashungaro.com/category/rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.lucashungaro.com</link>
	<description>Conhecimento nunca é o bastante</description>
	<lastBuildDate>Tue, 10 Apr 2012 17:18:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Capistrano and whenever: updating the crontab of the runner user</title>
		<link>http://blog.lucashungaro.com/2012/04/10/capistrano-and-whenever-updating-the-crontab-of-the-runner-user/</link>
		<comments>http://blog.lucashungaro.com/2012/04/10/capistrano-and-whenever-updating-the-crontab-of-the-runner-user/#comments</comments>
		<pubDate>Tue, 10 Apr 2012 17:15:06 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Deploy]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.lucashungaro.com/?p=432</guid>
		<description><![CDATA[When deploying Rails applications with Capistrano it&#8217;s a common practice to use two separated users: a deployer (the user who actually does the deploy process, copying files and all that) and a runner (the user that runs the application on the server). If you need cronjobs you probably use the whenever gem. It&#8217;s an awesome [...]]]></description>
			<content:encoded><![CDATA[<p>When deploying Rails applications with <a href="https://github.com/capistrano/capistrano" title="Capistrano">Capistrano</a> it&#8217;s a common practice to use two separated users: a deployer (the user who actually does the deploy process, copying files and all that) and a runner (the user that runs the application on the server).</p>
<p>If you need cronjobs you probably use the <a href="https://github.com/javan/whenever" title="whenever">whenever</a> gem. It&#8217;s an awesome tool to configure your scheduled jobs with a nice and easy DSL. It also has built-in integration with Capistrano, but there&#8217;s a caveat: it will update the crontab of the <strong>deployer</strong>, not the <strong>runner</strong>&#8216;s one.</p>
<p>To solve that issue, I&#8217;ve dropped the &#8220;automatic&#8221; integration (just a simple require &#8220;whenever/capistrano&#8221;) and used a hook to invoke whenever passing a user option to specify which user&#8217;s crontab to update. Here&#8217;s the relevant code:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">after <span style="color:#996600;">&quot;deploy:update_code&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  run <span style="color:#996600;">&quot;cd #{release_path} &amp;&amp; #{try_sudo} GEM_HOME=/opt/local/ruby/gems RAILS_ENV=production bundle exec whenever --clear-crontab #{application} --user #{runner}&quot;</span>
  run <span style="color:#996600;">&quot;cd #{release_path} &amp;&amp; #{try_sudo} GEM_HOME=/opt/local/ruby/gems RAILS_ENV=production bundle exec whenever --update-crontab #{application} --user #{runner}&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>The code above sets some env vars for sanity sake and runs whenever specifying the runner user as the crontab owner.</p>
<p>There&#8217;s another small tweak you&#8217;ll need. On your schedule.rb file, add the following code on the very first line:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">env <span style="color:#996600;">&quot;PATH&quot;</span>, ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;PATH&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
every <span style="color:#006666;">10</span>.<span style="color:#9900CC;">minutes</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  <span style="color:#008000; font-style:italic;"># ...</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This will avoid nasty path-related errors (the cronjobs won&#8217;t find the gem&#8217;s bins and all that). And… that&#8217;s it! Have fun! <img src='http://blog.lucashungaro.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2012/04/10/capistrano-and-whenever-updating-the-crontab-of-the-runner-user/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Compilando uma versão local do Rails Guides</title>
		<link>http://blog.lucashungaro.com/2012/03/06/compilando-uma-versao-local-do-rails-guides/</link>
		<comments>http://blog.lucashungaro.com/2012/03/06/compilando-uma-versao-local-do-rails-guides/#comments</comments>
		<pubDate>Tue, 06 Mar 2012 03:48:41 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Tutoriais]]></category>

		<guid isPermaLink="false">http://blog.lucashungaro.com/?p=429</guid>
		<description><![CDATA[Para compilar uma versão local do Rails Guides, você pode fazer o seguinte processo: 1) Descubra qual o seu &#8220;gem path&#8221;, o local onde suas gems estão instaladas. No meu caso, o Rails está instalado diretamente no sistema e não utilizo rvm ou rbenv. Para encontrar essa informação, utilizei o comando &#8220;gem env&#8221; diretamente no [...]]]></description>
			<content:encoded><![CDATA[<p>Para compilar uma versão local do Rails Guides, você pode fazer o seguinte processo:</p>
<p>1) Descubra qual o seu &#8220;gem path&#8221;, o local onde suas gems estão instaladas. No meu caso, o Rails está instalado diretamente no sistema e não utilizo rvm ou rbenv. Para encontrar essa informação, utilizei o comando &#8220;gem env&#8221; diretamente no terminal. Meu path é &#8220;/usr/local/lib/ruby/gems/1.9.1/gems/&#8221;.</p>
<p>2) Acesse o diretório da gem railties. Essa gem é como um &#8220;rails-core&#8221;, sendo o núcleo e o &#8220;hub&#8221; em que todas as outras gems que compõe o framework (e também extensões de terceiros) se registram para serem carregadas:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">lucashungaro<span style="color: #000000; font-weight: bold;">@</span>IronMan:<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>ruby<span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span>1.9.1<span style="color: #000000; font-weight: bold;">/</span>gems
$ <span style="color: #7a0874; font-weight: bold;">cd</span> railties-3.2.2<span style="color: #000000; font-weight: bold;">/</span>guides
&nbsp;
lucashungaro<span style="color: #000000; font-weight: bold;">@</span>IronMan:<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>ruby<span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span>1.9.1<span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span>railties-3.2.2<span style="color: #000000; font-weight: bold;">/</span>guides <span style="color: #7a0874; font-weight: bold;">&#40;</span>master<span style="color: #7a0874; font-weight: bold;">&#41;</span>
$ gem <span style="color: #c20cb9; font-weight: bold;">install</span> RedCloth
&nbsp;
lucashungaro<span style="color: #000000; font-weight: bold;">@</span>IronMan:<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>ruby<span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span>1.9.1<span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span>railties-3.2.2<span style="color: #000000; font-weight: bold;">/</span>guides <span style="color: #7a0874; font-weight: bold;">&#40;</span>master<span style="color: #7a0874; font-weight: bold;">&#41;</span>
$ ruby rails_guides.rb
&nbsp;
lucashungaro<span style="color: #000000; font-weight: bold;">@</span>IronMan:<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>ruby<span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span>1.9.1<span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span>railties-3.2.2<span style="color: #000000; font-weight: bold;">/</span>guides <span style="color: #7a0874; font-weight: bold;">&#40;</span>master<span style="color: #7a0874; font-weight: bold;">&#41;</span>
$ <span style="color: #c20cb9; font-weight: bold;">mv</span> output ~<span style="color: #000000; font-weight: bold;">/</span>projects<span style="color: #000000; font-weight: bold;">/</span>documentation<span style="color: #000000; font-weight: bold;">/</span>rails_guides_3.2.2</pre></div></div>

<p>Isso irá compilar os guias no diretório local &#8220;output&#8221;, o qual movemos para uma localização mais familiar. Não encontrei uma forma de mudar o diretório com argumentos na linha de comando. Você pode fazer isso se chamar o gerador via código, no entanto. O script aceita outras opções via linha de comando, como a opção de gerar guias para o Edge Rails ou versão Kindle, entre outras.</p>
<p>3) Ao término do processo, teremos os guias compilados em HTML no diretório indicado. Para acessá-los você pode criar um bookmark em seu browser ou utilizar um SSB. Prefiro a segunda maneira e, para isso, utilizo o <a href="http://fluidapp.com/">Fluid</a> (para encontrar alguns ótimos ícones visite <a href="http://www.flickr.com/groups/fluid_icons/">esse grupo no Flickr</a>. Basta criar uma nova aplicação e apontar para o diretório em que geramos os guias, iniciando pelo arquivo index.html.</p>
<div class="wp-caption aligncenter" style="width: 500px"><a href="http://blog.lucashungaro.com/wp-content/uploads/2012/03/guides.png"><img src="http://blog.lucashungaro.com/wp-content/uploads/2012/03/guides.png" title="Rails Guides com Fluid" width="490" height="328" class="size-full" /></a><p class="wp-caption-text">Rails Guides com Fluid</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2012/03/06/compilando-uma-versao-local-do-rails-guides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modularity on Rails</title>
		<link>http://blog.lucashungaro.com/2012/03/01/modularity-on-rails/</link>
		<comments>http://blog.lucashungaro.com/2012/03/01/modularity-on-rails/#comments</comments>
		<pubDate>Fri, 02 Mar 2012 01:06:06 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Opinião]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://blog.lucashungaro.com/?p=424</guid>
		<description><![CDATA[Following my last article I&#8217;d like to elaborate on my opinions. First, let&#8217;s review some things: Yes, I know you can deactivate a lot of the bundled stuff in Rails; that doesn&#8217;t solve any of the issues. Yes, I&#8217;m aware of Railties; It&#8217;s nice, well built, a good step forward; still doesn&#8217;t solve any of [...]]]></description>
			<content:encoded><![CDATA[<p>Following my last article I&#8217;d like to elaborate on my opinions. </p>
<p>First, let&#8217;s review some things:</p>
<ul>
<li>Yes, I know you <a href="https://gist.github.com/1942658">can deactivate a lot of the bundled stuff in Rails</a>; that doesn&#8217;t solve any of the issues.</li>
<li>Yes, I&#8217;m aware of Railties; It&#8217;s nice, well built, a good step forward; still doesn&#8217;t solve any of the isses.</li>
<li>Most of the people who reacted badly to my article (and <a href="http://twitter.com/merbist">@merbist</a>&#8216;s one) pointed out that, to use and understand Rails&#8217; &#8220;modularity&#8221; you&#8217;re supposed to <a href="http://www.amazon.com/Crafting-Rails-Applications-Development-Programmers/dp/1934356735/ref=sr_1_1?ie=UTF8&#038;qid=1330648115&#038;sr=8-1">buy a book</a>; I don&#8217;t think it should be necessary (nothing against the book, it&#8217;s very good)</li>
<p>The issues I pointed out converge to one thing: modularity <strong>isn&#8217;t</strong> configurability. Yeah, I can edit my default generated Rails app and remove all sorts of things, including using some hackish code to remove middlewares from its stack. This isn&#8217;t modularity on the application-level.</p>
<p>I know that Rails&#8217;s <strong>internals</strong> are more modular on Rails 3 than they&#8217;ve ever been. I&#8217;ve saw Jose Valim&#8217;s <a href="http://en.oreilly.com/rails2011/public/schedule/detail/19579"> talk about how they&#8217;ve applied SOLID principles to achieve that</a>, it&#8217;s really nice (read the slides if you can, it pays off). I&#8217;m not talking about that. I&#8217;d like to emphasize that I&#8217;m talking about modularity at the application level, not at internal code level.</p>
<p>Here&#8217;s an example (hypothetical context, of course):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ rails new my_app <span style="color: #666666; font-style: italic;"># generates a lean app (not a Sinatra-style app, a Rails app without the unneeded stuff)</span>
&nbsp;
... <span style="color: #666666; font-style: italic;"># days after</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Hmmm, I need to send e-mails!</span>
$ <span style="color: #7a0874; font-weight: bold;">cd</span> my_app
$ rails add actionmailer <span style="color: #666666; font-style: italic;"># adds and installs actionmailer, generates the boilerplate needed</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Hmmm, I need to speed up my assets load time!</span>
$ rails add rails-assets-pipeline</pre></div></div>

<p><strong>Modular</strong>. <strong>Apps</strong>. Things I can incrementally build upon. Now, mailer should probably be there by default, but you get the idea.</p>
<p>These gems would be separated from Rails core. I really don&#8217;t care if a &#8220;full&#8221; Rails app ends up installing 100 gems as long as I&#8217;m in control of that and can start with way less.</p>
<p>What&#8217;s the advantages?</p>
<ul>
<li>Easier to learn: beginners will have a better experience since they can learn the framework gradually;</li>
<li>Still powerful: that doesn&#8217;t force you to dumb it down, as many suggest. Modular apps suit the needs of novices and experienced developers as well;</li>
<li>Goodbye clutter and unneeded code: the framework will only load the code I need. Boot time will be decreased as well as memory consumption. Yes, I know that if you deactivate something today, most of the code won&#8217;t be loaded, which gets us to&#8230;</li>
<li>Less code to understand: it will be easier to contribute to the framework as it will have way less code and I can gradually dig in. I can contribute with the core without stumbling into the assets pipeline, for example.</li>
</ul>
<p>Well, I could elaborate more on that, but it&#8217;s the main idea. Rails&#8217; internals are way better, yes, and that&#8217;s awesome. But the framework still lags behind on many things I think should receive priority instead of adding built-in support for SASS, CoffeeScript and things like that. I&#8217;m currently taking a look at Rails&#8217; codebase to see how I can fit these ideas in. I hope to have some pull requests ready soon. If you&#8217;re interested in helping, please contact me.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2012/03/01/modularity-on-rails/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Rails has entered the framework death spiral</title>
		<link>http://blog.lucashungaro.com/2012/03/01/rails-has-entered-the-framework-death-spiral/</link>
		<comments>http://blog.lucashungaro.com/2012/03/01/rails-has-entered-the-framework-death-spiral/#comments</comments>
		<pubDate>Thu, 01 Mar 2012 04:44:52 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Opinião]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://blog.lucashungaro.com/?p=423</guid>
		<description><![CDATA[I usually write here in Brazilian Portuguese but this post is written in English in the hope of getting some useful attention and discussion going on (yes, wishful thinking). Before we start this, let&#8217;s make some things clear. When I criticize Rails there&#8217;s two common reactions: The Lovers: &#8220;OMG, DHH and the Core Team are [...]]]></description>
			<content:encoded><![CDATA[<p>I usually write here in Brazilian Portuguese but this post is written in English in the hope of getting some useful attention and discussion going on (yes, wishful thinking).</p>
<p>Before we start this, let&#8217;s make some things clear. When I criticize Rails there&#8217;s two common reactions:</p>
<p>  <strong>The Lovers</strong>:</p>
<ul>
<li>&#8220;OMG, DHH and the Core Team are awesome, they know what&#8217;s better for you, stop crying!&#8221;</li>
<li>&#8220;Well, stop using Rails and create something better!&#8221;</li>
<li>&#8220;You should not criticize the tool that pays your bills!&#8221;</li>
</ul>
<p>  <strong>The Haters</strong>:</p>
<ul>
<li>&#8220;Yes! Yes! Let&#8217;s burn these motherfuckers!&#8221;</li>
</ul>
<p>Let me be totally clear here: Rails is very useful and I like it a lot (although I used to like it way more). <a href="http://caremad.com">Otherwise I would just dismiss it and don&#8217;t even bother trying to get some attention to the issues I&#8217;ll describe</a>. I respect the work and effort of so many people that keep the framework going fixing bugs and adding features. You should too, it&#8217;s not a walk in the park and very few people actually get some time to do this kind of work. A special mention goes to Aaron Patterson (<a href="http://twitter.com/tenderlove">@tenderlove</a>), a guy who relentlessly keeps cleaning up the mess that Rails&#8217; codebase has become while still keeping his humility (sadly, a rare trait in our community).</p>
<p>Some days ago, when talking with a friend, he said &#8220;Rails has entered the framework death spiral &#8211; it&#8217;s now adding features for feature-sake&#8221;. I agree. The &#8220;Rails is opinionated software&#8221; idea is clearly lost as it&#8217;s trying to embrace everything and has turned into a playground for some people (not the entire team, to be clear) instead of a framework that shapes the way web applications are created (that paradigm is shifting and meanwhile Rails is messing around with CoffeeScript and SASS).</p>
<p>One example of this &#8220;playground theory&#8221;? Releasing a piece of crap like the assets pipeline, clearly rushed and so fucked up that it makes me think if it&#8217;s the worse thing I ever had to use to build software, occupying a honorable spot besides the Struts framework, ASP and JavaServer Faces.</p>
<p>The main problem, in my humble opinion, is: Rails has turned into bloatware. I see the problem from two angles: as a potential contributor and as a user of the framework.</p>
<p><strong>As a contributor</strong></p>
<p>Rails has so many things included by default now that the code is really big. I tried to understand it some time ago and got quickly frustrated by the massive amount of coupled code and features that distract you from the main workflow of the framework. Yes, I could probably just get some ticket and solve a bug, but I like to understand the whole before going around throwing code like crazy to get some commits in. OSS activists will probably bash me for this, calling me lazy, but it&#8217;s the way I work, sorry.</p>
<p>The solution? Well, my suggestion is this: the rails gem should contain only the core, the request processing cycle and hooks for the other parts to hang in (ORMs, template engines, other gems in general). It already has this in some form, a framework called Railties, but all the things that hook into it are still in the same codebase, divided in a few other gems. </p>
<p>The asset pipeline is a main offender here and the easiest example to bring to the surface. This thing should *really* be into its own gem and out of Rails. It could be included in Rails&#8217; default Gemfile, I don&#8217;t care, but please do not throw more code into the mess. I won&#8217;t even start the discussion about the quality of the pipeline per se, but I digress. If you want the default approach, the one the Core Team chose, just generate a full app and install de default gems. Otherwise we could have a lean application generator that remove all the uneeded dependencies without hacks. Better yet if that one could be the default.</p>
<p>If my memory isn&#8217;t failing me, I believe Merb did things this way. Besides lessening the burden on contributors it should force people to write decoupled code, something the Rails Core Team has been improving on for some time now, by the way.</p>
<p>Yes, I know Rails included extra things like ActionMailer and ActiveRecord from the beginning and they&#8217;re independent gems. As I said before, I&#8217;m fine with default choices, but I also think that Rails&#8217; starting point should be a lean and simple mini-stack that could be easily incremented as the user needs it to be.</p>
<p><strong>As a user</strong></p>
<p>People who are experienced with Rails tend to forget that beginners do exist. Most of the so called &#8220;Railers&#8221; I know see themselves as a kind of superior being surfing the waves of awesomeness, forgetting that legacy must be supported and new people will try Rails. Funny thing is that the developers that use Rails as a mere tool (what it is) see this issue clearly, while people that see it as a religious cult dismiss it.</p>
<p>The first issue is legacy. Rails completely ignore this (as is common with frameworks in so called &#8220;non-enterprise&#8221; ecosystems) and makes no effort to support people that work with legacy code. The community itself fails hard at this, as we don&#8217;t even talk about that as we should. Think about how rare it is to see a talk about legacy applications on conferences in contrast to the plethora of talks about new features/libraries or how you should be writing your code. We fail hard here.</p>
<p>The second issue is that, as of today, Rails is incredibly hard for beginners to learn and use effectively. It&#8217;s slow, has a freaking unbelievable amount of dependencies right of the bat (this can be normal down the road, not by default), it&#8217;s cumbersome to set up (don&#8217;t you love some gem version hell?), it&#8217;s not quick to get up and running anymore. I usually joke that the &#8220;15 minutes blog&#8221; today should be called &#8220;the 1 hour and 30 minutes blog&#8221;. That&#8217;s not to mention the big disparity between the official literature and documentation (&#8220;the DHH way&#8221;) and the way real Rails apps are developed.</p>
<p><strong>EDIT</strong>: to be fair, I installed the latest Rails and generated a new app. No version hell this time, hurray! The last three times I did it, it was a nightmare. Things are still slow though. You can generage your application with &#8220;rails new my_app &#8211;skip-sprockets &#8211;skip-test-unit&#8221; to drop the generation time from ~2 minutes to about ~30 seconds. Other flags like &#8211;skip-active-record and &#8211;skip-javascript are available to bypass some default dependencies.</p>
<p>It&#8217;s hard for people who already knows Rails to imagine how it is to begin with the framework today. I&#8217;ve seen beginners trying it and it was ugly. Think about how many unrelated things someone has to go through to understand a simple &#8220;Hello World&#8221; in a default Rails application today.</p>
<p>What got me interested in Rails was the &#8220;batteries included&#8221; approach, yes. But there was a thin line and, to me, that line has been crossed. Rails went past the line of &#8220;including everything you need for a quick start&#8221; to &#8220;including everything the Core Team thinks you need to build a gigantic web application following every techniques they find appropriate&#8221;. Yes, I know it&#8217;s best practice to minify my JavaScript but I&#8217;m a grow up, let me do it the way I want without clogging up the framework with a lot of useless code (yes, I can deactivate it, but it&#8217;s still useless since I won&#8217;t use it and it will slow my boot time and bloat the framework code, hence the idea of splitting Rails into more gems and do not install them by default nor include them in the same codebase).</p>
<p><strong>Conclusion</strong></p>
<p>The Rails framework should really get trimmed down. Non-fundamental trinket should be separated and, maybe, we could have two application generators: a &#8220;lean&#8221; (maybe just ActionPack and Railties, something like that) one and a &#8220;full&#8221; one. That way it would be a lot easier to grasp the framework code and contribute while allowing newcomers to taste the goodies gradually, learning instead of being drowned into a lot of concerns that really doesn&#8217;t relate to the core of developing a well built application.</p>
<p><strong>EDIT</strong>: Yes, the title of the article is harsh and I recognize it does not reflect what I wanted to suggest here. It was wrong and tabloid style. It was chosen out of frustration, which shouldn&#8217;t be a reason to do it. The intention of the article is to spark a good discussion, not to be alarmist and accusatory, which the title makes it sound like.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2012/03/01/rails-has-entered-the-framework-death-spiral/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>SOLID Ruby: Single Responsibility Principle</title>
		<link>http://blog.lucashungaro.com/2011/05/04/solid-ruby-single-responsibility-principle/</link>
		<comments>http://blog.lucashungaro.com/2011/05/04/solid-ruby-single-responsibility-principle/#comments</comments>
		<pubDate>Wed, 04 May 2011 05:34:38 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.lucashungaro.com/?p=409</guid>
		<description><![CDATA[Utilizamos BDD e técnicas do programação orientada a objetos não apenas para obter código mais limpo e bonito. Na verdade, essas são consequências do principal objetivo: criar código que tenha baixo custo de manutenção, isto é, não demande muito tempo e pessoas para correções e melhorias. Um conjunto de técnicas que podemos utilizar para atingir [...]]]></description>
			<content:encoded><![CDATA[<p>Utilizamos BDD e técnicas do programação orientada a objetos não apenas para obter código mais limpo e bonito. Na verdade, essas são consequências do principal objetivo: criar código que tenha baixo custo de manutenção, isto é, não demande muito tempo e pessoas para correções e melhorias.</p>
<p>Um conjunto de técnicas que podemos utilizar para atingir esse objetivo é chamada de <a href="http://en.wikipedia.org/wiki/Solid_(object-oriented_design)">SOLID</a>, um acrônimo que representa cinco técnicas:</p>
<ul>
<li>Single Responsibility Principle</li>
<li>Open-Closed Principle</li>
<li>Liskov Substitution Principle</li>
<li>Interface Segregation Principle</li>
<li>Dependency Inversion Principle</li>
</ul>
<p>O objetivo desses princípios é fazer com que alterações necessárias sejam feitas no menor número possível de locais no código. Em outras palavras, é diminuir o custo dessas mudanças através de um design que reduz os efeitos colaterais das modificações.</p>
<p>Nesse artigo vou mostrar um pouco sobre a aplicação do <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">Single Responsibility Principle</a> em Ruby.</p>
<p>Esse princípio nos diz que uma classe deve ter apenas uma responsabilidade e deve executá-la por completo (não devem haver outras classes que executem partes dela). É uma forma de conseguir alta <a href="http://en.wikipedia.org/wiki/Cohesion_(computer_science)">coesão</a>, uma qualidade desejável em código orientado a objetos. Uma classe coesa executa completamente uma responsabilidade, ou seja, essa responsabilidade não fica fragmentada e espalhada entre diferentes entidades no domínio.</p>
<p>Uma forma de pensar sobre o que é uma responsabilidade para facilitar a absorção do conceito é que esta representa <em>uma razão para mudar</em>. Então podemos definir o princípio como: uma classe tem uma e apenas uma razão para mudar.</p>
<p>Vamos a um exemplo de um modelo ActiveRecord que viola esse princípio (alerta para pseudo-código que nem deve funcionar, é apenas um exemplo):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Game <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;">:category</span>
  validates_presence_of <span style="color:#ff3333; font-weight:bold;">:title</span>, <span style="color:#ff3333; font-weight:bold;">:category_id</span>, <span style="color:#ff3333; font-weight:bold;">:description</span>,
                        <span style="color:#ff3333; font-weight:bold;">:price</span>, <span style="color:#ff3333; font-weight:bold;">:platform</span>, <span style="color:#ff3333; font-weight:bold;">:year</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> get_official_price
    <span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;http://thegamedatabase.com/api/game/#{name}/price?api_key=ek2o1je&quot;</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;">def</span> <span style="color:#CC0066; font-weight:bold;">print</span>
    <span style="color:#006600; font-weight:bold;">&lt;&lt;-</span>EOF
      <span style="color:#008000; font-style:italic;">#{name}, #{platform}, #{year} </span>
      current value is <span style="color:#008000; font-style:italic;">#{get_official_price}</span>
    EOF
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Esse modelo tem como sua responsabilidade principal cuidar da lógica de negócio ligada à entidade Game. Porém, como podemos ver aqui, ele também está responsável por consultar um webservice para obter a cotação do jogo e por formatar sua exibição. Essa implementação possui baixa coesão pois essa classe possui mais de um motivo para mudar. Ela será alterada se os requisitos de validação de dados mudarem, se algum detalhe da chamada do webservice mudar ou se precisarmos exibir seus dados numa formatação diferente.</p>
<p>Uma forma de resolver isso seria desmembrar essa classe tendo esse resultado:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Game <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;">:category</span>
  validates_presence_of <span style="color:#ff3333; font-weight:bold;">:title</span>, <span style="color:#ff3333; font-weight:bold;">:category_id</span>, <span style="color:#ff3333; font-weight:bold;">:description</span>,
                        <span style="color:#ff3333; font-weight:bold;">:price</span>, <span style="color:#ff3333; font-weight:bold;">:platform</span>, <span style="color:#ff3333; font-weight:bold;">:year</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> GamePriceService
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:game</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># we could use a config file</span>
  BASE_URL = <span style="color:#996600;">&quot;http://thegamedatabase.com/api/game&quot;</span>
  API_KEY = <span style="color:#996600;">&quot;ek2o1je&quot;</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>game<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">game</span> = game
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> get_price
    data = <span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{BASE_URL}/#{game.name}/price?api_key=#{API_KEY}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    JsonParserLib.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span>data<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>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> GamePrinter
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:game</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>game<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">game</span> = game
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#CC0066; font-weight:bold;">print</span>
    price_service = GamePriceService.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>game<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#006600; font-weight:bold;">&lt;&lt;-</span>EOF
      <span style="color:#008000; font-style:italic;">#{game.name}, #{game.platform}, #{game.year} </span>
      current value is <span style="color:#008000; font-style:italic;">#{price_service.get_price[:value]}</span>
    EOF
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Assim aumentamos bastante a coesão de nosso sofware. Cada classe possui apenas uma razão para mudar e atende ao SRP.</p>
<p>Um exemplo mais real pode ser visto no modelo <a href="https://github.com/spree/spree/blob/master/core/app/models/creditcard.rb">Creditcard</a> do <a href="http://spreecommerce.com/">Spree</a>. Note que, entre outras coisas, o modelo também é responsável pelos processos de compra e autorização do cartão (métodos purchase e authorize). Note como esse métodos implementam parte do processo e delegam outras partes para outros componentes quando a responsabilidade deveria ser 100% realizada em outra parte. Isso cria baixa coesão (múltiplas responsabilidades por classe) e alto acoplamento (uma responsabilidade dividida por várias classes interdependentes).</p>
<p>Como um exercício a parte podemos pensar sobre até que ponto modelos do ActiveRecord quebram o SRP por serem responsáveis por persistência e lógica de negócios (que inclui validação de dados). Há muitos desenvolvedores dos dois lados nessa questão. Acredito que há pequenas violações mas de uma forma não prejudicial, já que a persistência é implementada por uma classe especializada e apenas herdada em nossos modelos, de forma que essa é delegada ao framework (que cuida de possíveis modificações necessárias à persistência).</p>
<p>É preciso ter em mente que ser muito extremista com esses princípios também pode levar à problemas e a um excesso de preciosismo que torna-se prejudicial.</p>
<p>Bom, a partir daqui vamos para outros artigos onde serão explorados os outros princípios. O pseudo-código utilizado no exemplo acima ainda tem algumas coisas a ganhar através da aplicação de outros princípios.</p>
<p>Leitura recomendada:</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Cohesion_(computer_science)">Cohesion</a></li>
<li><a href="http://en.wikipedia.org/wiki/Coupling_(computer_science)">Coupling</a></li>
<li><a href="http://en.wikipedia.org/wiki/Separation_of_concerns">Separation of concerns</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2011/05/04/solid-ruby-single-responsibility-principle/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Dica rápida: formatação da saída do Test::Unit com a gem turn</title>
		<link>http://blog.lucashungaro.com/2011/01/26/dica-rapida-formatacao-da-saida-do-test-unit-com-a-gem-turn/</link>
		<comments>http://blog.lucashungaro.com/2011/01/26/dica-rapida-formatacao-da-saida-do-test-unit-com-a-gem-turn/#comments</comments>
		<pubDate>Wed, 26 Jan 2011 20:06:23 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Gem]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://blog.lucashungaro.com/?p=402</guid>
		<description><![CDATA[Recentemente voltei a brincar com um pet project para atualizá-lo do Rails 2.3 para o Rails 3. A suíte de testes do projeto foi escrita com Test::Unit e Shoulda e, quando a executei sob Ruby 1.9.2, vi que a saída não estava formatada, isto é, não havia alinhamento, as falhas não ficavam em vermelho e [...]]]></description>
			<content:encoded><![CDATA[<p>Recentemente voltei a brincar com um pet project para atualizá-lo do Rails 2.3 para o Rails 3. A suíte de testes do projeto foi escrita com Test::Unit e Shoulda e, quando a executei sob Ruby 1.9.2, vi que a saída não estava formatada, isto é, não havia alinhamento, as falhas não ficavam em vermelho e os sucessos em verde. Pelo que me lembro, quando rodava esses testes no Ruby 1.8, a saída era formatada e com cores. Provavelmente algo que foi retirado do Ruby 1.9, talvez na mudança de Test::Unit para MiniTest.</p>
<p>Bem, não me preocupei muito com o motivo disso. Busquei algumas maneiras de formatar essa saída e, entre outras, encontrei a gem <a href="https://github.com/TwP/turn">turn</a>. Configurei-a no Gemfile do projeto e tudo funcionou perfeitamente de primeira, sem nenhum incômodo. Além da formatação, uma feature interessante é que, ao invés de mostrar pontinhos e letras (ex: …..F…F.), o turn vai mostrando as descrições dos testes e seu status (passou/falhou) à medida que a suite é executada. Feedback bem mais útil.</p>
<p>Veja um exemplo de como fica a formatação através desse link: <a href="http://d.pr/mWPe">http://d.pr/mWPe</a> (assim não quebro todo o layout do blog). <img src='http://blog.lucashungaro.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2011/01/26/dica-rapida-formatacao-da-saida-do-test-unit-com-a-gem-turn/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Utilizando rack-debug para debugging com Passenger</title>
		<link>http://blog.lucashungaro.com/2009/09/10/utilizando-rack-debug-para-debugging-com-passenger/</link>
		<comments>http://blog.lucashungaro.com/2009/09/10/utilizando-rack-debug-para-debugging-com-passenger/#comments</comments>
		<pubDate>Thu, 10 Sep 2009 20:06:27 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=294</guid>
		<description><![CDATA[Desenvolver aplicações Rails utilizando o Phusion Passenger (principalmente no Mac OS X com o Passenger preference pane) é muito prático. Porém, uma coisa que logo senti falta foi a possibilidade de utilizar a gem ruby-debug quando precisava de breakpoints para debuggar o código. Uma maneira de conseguir isso é através da gem/plugin rack-debug. Para utilizá-la, [...]]]></description>
			<content:encoded><![CDATA[<p>Desenvolver aplicações Rails utilizando o <a target="_blank" href="http://www.modrails.com/">Phusion Passenger</a> (principalmente no Mac OS X com o <a target="_blank" href="http://www.fngtps.com/passenger-preference-pane">Passenger preference pane</a>) é muito prático. Porém, uma coisa que logo senti falta foi a possibilidade de utilizar a gem <a target="_blank" href="http://rubyforge.org/projects/ruby-debug/">ruby-debug</a> quando precisava de breakpoints para <em>debuggar</em> o código.</p>
<p>Uma maneira de conseguir isso é através da gem/plugin <a target="_blank" href="http://github.com/ddollar/rack-debug/tree/master">rack-debug</a>. Para utilizá-la, segui os passos abaixo.</p>
<p>1. Instalação</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"> $ script<span style="color: #000000; font-weight: bold;">/</span>plugin <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #c20cb9; font-weight: bold;">git</span>:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>ddollar<span style="color: #000000; font-weight: bold;">/</span>rack-debug.git
&nbsp;
 <span style="color: #666666; font-style: italic;"># config/environments/development.rb</span>
 config.middleware.use <span style="color: #ff0000;">&quot;Rack::Debug&quot;</span></pre></div></div>

<p>2. Chamar o debugger onde necessário:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> create
    <span style="color:#0066ff; font-weight:bold;">@status</span> = current_user.<span style="color:#9900CC;">statuses</span>.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:status</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    debugger
    <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@status</span>.<span style="color:#9900CC;">valid</span>?
...</pre></div></div>

<p>3. Conectar-se ao debugger</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"> <span style="color: #666666; font-style: italic;"># No diretório da aplicação, chamar a task rake</span>
 $ rake debug
 Connected.</pre></div></div>

<p>4. Ao executar a linha onde o debugger foi chamado, a aplicação para e você tem acesso ao console do debugger</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"> <span style="color:#006600; font-weight:bold;">&#40;</span>rdb:<span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#0066ff; font-weight:bold;">@status</span>
 <span style="color:#008000; font-style:italic;">#&lt;status id: 231, text: &quot;Testing rack-debug&quot;, user_id: 4, ...&gt;</span></pre></div></div>

<p>Pronto. Happy debugging! <img src='http://blog.lucashungaro.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Update</strong>: ao chamar a task rake, pode ocorrer um erro com a mensagem &#8220;Server is not running or Passenger has spooled down&#8221;. Neste caso, reinicie o Apache e tudo deve funcionar normalmente.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2009/09/10/utilizando-rack-debug-para-debugging-com-passenger/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Testes envolvendo tempo: usando a gem time-warp</title>
		<link>http://blog.lucashungaro.com/2009/08/28/testes-envolvendo-tempo-usando-a-gem-time-warp/</link>
		<comments>http://blog.lucashungaro.com/2009/08/28/testes-envolvendo-tempo-usando-a-gem-time-warp/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 16:46:23 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=269</guid>
		<description><![CDATA[É comum que precisemos &#8220;manipular o tempo&#8221; quando escrevendo testes para código cujo comportamento depende do momento no tempo. Uma técnica comum é utilizar um mock ou stub na classe Time do Ruby para manipular o horário de acordo com o desejado. Isso vai contra um princípio importante do uso de fake objects em testes: [...]]]></description>
			<content:encoded><![CDATA[<p>É comum que precisemos &#8220;manipular o tempo&#8221; quando escrevendo testes para código cujo comportamento depende do momento no tempo.</p>
<p>Uma técnica comum é utilizar um mock ou stub na classe Time do Ruby para manipular o horário de acordo com o desejado. Isso vai contra um princípio importante do uso de fake objects em testes: &#8220;<a target="_blank" href="http://www.infoq.com/news/2008/08/Mock-Roles-Pryce-and-Freeman">Não use fakes em objetos que não são seus</a>&#8220;. Na maioria do tempo isso pode não causar problemas, mas alterar o comportamento de uma classe usada internamente pela linguagem não soa bem e pode causar bugs difíceis de rastrear.</p>
<p>Aí entra a gem <a target="_blank" href="http://github.com/iridesco/time-warp/tree/master">time-warp</a>. Ela ainda trabalha sobre as classes do Ruby, mas provê uma camada específica para testes para todo código executado em um bloco definido pelo programador. Um exemplo de uso (da <a target="_blank" href="http://twtapp.info/">nossa aplicação feita para o Rails Rumble</a>):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">it <span style="color:#996600;">&quot;should only silence tweets with the desired word inside the configured time interval&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  pretend_now_is<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>.<span style="color:#9900CC;">utc</span>.<span style="color:#9900CC;">beginning_of_day</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span>.<span style="color:#9900CC;">hour</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    tweet1.<span style="color:#9900CC;">sent_at</span> = <span style="color:#006666;">2</span>.<span style="color:#9900CC;">minutes</span>.<span style="color:#9900CC;">ago</span>
    tweet2.<span style="color:#9900CC;">sent_at</span> = <span style="color:#006666;">32</span>.<span style="color:#9900CC;">minutes</span>.<span style="color:#9900CC;">from_now</span>
    tweet3.<span style="color:#9900CC;">sent_at</span> = <span style="color:#006666;">1</span>.<span style="color:#9900CC;">hour</span>.<span style="color:#9900CC;">from_now</span>
&nbsp;
    collection = <span style="color:#006600; font-weight:bold;">&#91;</span>tweet1, tweet2, tweet3<span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
    Silencer.<span style="color:#9900CC;">apply</span><span style="color:#006600; font-weight:bold;">&#40;</span>collection, <span style="color:#006600; font-weight:bold;">&#123;</span>:word <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;soccer&quot;</span>, :<span style="color:#9966CC; font-weight:bold;">until</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">30</span>.<span style="color:#9900CC;">minutes</span>.<span style="color:#9900CC;">from_now</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;">end</span>
&nbsp;
  tweet1.<span style="color:#9900CC;">should</span> be_filtered
  tweet2.<span style="color:#9900CC;">should</span> be_filtered
  tweet3.<span style="color:#9900CC;">should_not</span> be_filtered
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>A gem adiciona o método &#8220;pretend_now_is&#8221;, que recebe um parâmetro com o horário desejado e um bloco. Dentro desse bloco, todo código executado é &#8220;transportado no tempo&#8221; para o horário definido. Além de tornar a manipulação das classes de tempo mais segura, o código fica muito mais elegante.</p>
<p>Veja mais detalhes no <a target="_blank" href="http://github.com/iridesco/time-warp/blob/884623fec90687c7f3c28b8e8074a39c96946cbb/README.md">README da gem</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2009/08/28/testes-envolvendo-tempo-usando-a-gem-time-warp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides e notas da minha sessão no FISL10</title>
		<link>http://blog.lucashungaro.com/2009/06/25/slides-e-notas-da-minha-sessao-no-fisl10/</link>
		<comments>http://blog.lucashungaro.com/2009/06/25/slides-e-notas-da-minha-sessao-no-fisl10/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 16:52:25 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Apresentações]]></category>
		<category><![CDATA[Eventos]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Test-Driven Development]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=228</guid>
		<description><![CDATA[Pessoal, abaixo está o link para download, em formato PDF, dos slides com notas que eu utilizei na minha sessão ontem no FISL10, entitulada &#8220;TDD e Rails: Mais rápido, mais forte e melhor&#8221;. Download. Obrigado a todos que apareceram por lá! Qualquer feedback é muito bem-vindo.]]></description>
			<content:encoded><![CDATA[<p>Pessoal, abaixo está o link para download, em formato PDF, dos slides com notas que eu utilizei na minha sessão ontem no FISL10, entitulada &#8220;TDD e Rails: Mais rápido, mais forte e melhor&#8221;.</p>
<p><a href="http://makemesimple.com/files/fisl10.pdf" target="_blank">Download</a>.</p>
<p>Obrigado a todos que apareceram por lá! Qualquer feedback é muito bem-vindo. <img src='http://blog.lucashungaro.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2009/06/25/slides-e-notas-da-minha-sessao-no-fisl10/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Ruby Quick Tip: Aprendendo através de testes</title>
		<link>http://blog.lucashungaro.com/2009/02/08/ruby-quick-tip-aprendendo-atraves-de-testes/</link>
		<comments>http://blog.lucashungaro.com/2009/02/08/ruby-quick-tip-aprendendo-atraves-de-testes/#comments</comments>
		<pubDate>Sun, 08 Feb 2009 21:07:09 +0000</pubDate>
		<dc:creator>Lucas Húngaro</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.makemesimple.com/blog/?p=156</guid>
		<description><![CDATA[Se você não conhece (completamente ou pacialmente) alguma biblioteca, uma boa forma de fazer isso é através de um caso de testes. Um benefício resultante dessa prática é poder executar os testes contra várias versões do Ruby e, assim, verificar alterações em sua estrutura. Se você usa o TextMate, é muito fácil criar um caso [...]]]></description>
			<content:encoded><![CDATA[<p>Se você não conhece (completamente ou pacialmente) alguma biblioteca, uma boa forma de fazer isso é através de um caso de testes.</p>
<p>Um benefício resultante dessa prática é poder executar os testes contra várias versões do Ruby e, assim, verificar alterações em sua estrutura.</p>
<p>Se você usa o TextMate, é muito fácil criar um caso de testes. Basta abrir uma janela do editor, ativar o bundle do Ruby, digitar <em>tc</em> e pressionar a tecla <em>tab</em>:</p>
<p><img src="http://blog.lucashungaro.com/wp-content/uploads/2009/02/ishot-1.jpg" alt="TextMate" title="TextMate" width="475" height="449" class="aligncenter size-full wp-image-161" /></p>
<p><img src="http://blog.lucashungaro.com/wp-content/uploads/2009/02/ishot-2.jpg" alt="test case scaffold" title="test case scaffold" width="475" height="449" class="aligncenter size-full wp-image-162" /></p>
<p>Com isso temos um &#8220;esqueleto&#8221; de um caso de testes pronto. Pressionando tab, o foco do cursor passa por pontos importantes, como o require da biblioteca a ser testada, o nome do caso de testes etc. Agora, basta modificar de acordo com o que queremos testar e, através do atalho command+R, executar os testes e verificar o resultado:</p>
<p><img src="http://blog.lucashungaro.com/wp-content/uploads/2009/02/ishot-3.jpg" alt="test" title="test" width="475" height="449" class="aligncenter size-full wp-image-163" /></p>
<p><img src="http://blog.lucashungaro.com/wp-content/uploads/2009/02/ishot-41.jpg" alt="ishot-41" title="ishot-41" width="500" height="331" class="aligncenter size-full wp-image-174" /></p>
<p><strong>Veja também</strong>:</p>
<p><a href="http://www.makemesimple.com/blog/2007/08/27/aprendizado-orientado-por-testes/">Aprendizado orientado por testes</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lucashungaro.com/2009/02/08/ruby-quick-tip-aprendendo-atraves-de-testes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

