<?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:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0" xml:base="http://mediumexposure.com">
<channel>
 <title>hakunin's blog</title>
 <link>http://mediumexposure.com/techblog</link>
 <description />
 <language>en</language>
<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/mediumexposure" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
 <title>Testing Helpers That Use Scoped Translations</title>
 <link>http://feedproxy.google.com/~r/mediumexposure/~3/0Pw0ODvO9Gk/testing-helpers-use-scoped-translations</link>
 <description>&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; While this technique is useful when you actually need to bind a template to your helper test, most of the time you can simply stub the helper right there, using something like &lt;span class="geshifilter"&gt;&lt;code class="geshifilter-text"&gt;stub(self).t('.title') { &amp;quot;Title&amp;quot; }&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Once on a beautiful day the sun was shining and the room was full of pleasant warmth. I was whistling a tune happily to myself while writing the following rails helper.&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="rails geshifilter-rails" style="font-family:monospace;"&gt;  &lt;span style="color:#9966CC; font-weight:bold;"&gt;def&lt;/span&gt; title&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;page_title, show_title = &lt;span style="color:#0000FF; font-weight:bold;"&gt;true&lt;/span&gt;&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt;
    &lt;span style="color:#5A0A0A; font-weight:bold;"&gt;content_for&lt;/span&gt;&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#ff3333; font-weight:bold;"&gt;:title&lt;/span&gt;&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#123;&lt;/span&gt; t&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#996600;"&gt;'.title'&lt;/span&gt;, &lt;span style="color:#ff3333; font-weight:bold;"&gt;:default&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;=&amp;gt;&lt;/span&gt; page_title&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#125;&lt;/span&gt;
    &lt;span style="color:#0066ff; font-weight:bold;"&gt;@show_title&lt;/span&gt; = show_title
  &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;It's so neat and simple. It allows you to write `title "English Title"` and provides a way to override title with translation scoped like `pages.index.title`.&lt;/p&gt;
&lt;p&gt;Then came the test (apologies, TDD purists). Whistling along with the chirping birds I put the following in my helper test.&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="rails geshifilter-rails" style="font-family:monospace;"&gt;  &lt;span style="color:#CC0066; font-weight:bold;"&gt;require&lt;/span&gt; &lt;span style="color:#996600;"&gt;'test_helper'&lt;/span&gt;
&amp;nbsp;
  &lt;span style="color:#9966CC; font-weight:bold;"&gt;class&lt;/span&gt; LayoutHelperTest &lt;span style="color:#006600; font-weight:bold;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#6666ff; font-weight:bold;"&gt;ActionView::TestCase&lt;/span&gt;
    context &lt;span style="color:#996600;"&gt;&amp;quot;#title helper&amp;quot;&lt;/span&gt; &lt;span style="color:#9966CC; font-weight:bold;"&gt;do&lt;/span&gt;
      should &lt;span style="color:#996600;"&gt;&amp;quot;create content for title&amp;quot;&lt;/span&gt; &lt;span style="color:#9966CC; font-weight:bold;"&gt;do&lt;/span&gt;
        title&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#996600;"&gt;&amp;quot;foobar&amp;quot;&lt;/span&gt;&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt;
        &lt;span style="color:#5A0A0A; font-weight:bold;"&gt;assert_equal&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;foobar&amp;quot;&lt;/span&gt;, &lt;span style="color:#0066ff; font-weight:bold;"&gt;@content_for_title&lt;/span&gt;
      &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;
    &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;
  &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Suddenly the birds went silent. The room got colder and darker. I got an error.&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="text geshifilter-text" style="font-family:monospace;"&gt;  NameError: undefined local variable or method `template' for #&amp;lt;LayoutHelperTest:0x102e8ab40&amp;gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Here's what happened. Using scoped translations such as `t('.title')` requires a template. It makes perfect sense because scope can only be looked up for a particular template's path. After some research I found that it's quite easy to stub a template for tests to work. You can put something like this in your setup method.&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="rails geshifilter-rails" style="font-family:monospace;"&gt;  &lt;span style="color:#008000; font-style:italic;"&gt;# Using RR (&lt;a href="http://github.com/btakita/rr" title="http://github.com/btakita/rr"&gt;http://github.com/btakita/rr&lt;/a&gt;) for stubbing.&lt;/span&gt;
  &lt;span style="color:#008000; font-style:italic;"&gt;# Easy to convert to equivalent in mocha/flexmock/etc.&lt;/span&gt;
  stub&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#0000FF; font-weight:bold;"&gt;self&lt;/span&gt;&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt;.&lt;span style="color:#9900CC;"&gt;template&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color:#6666ff; font-weight:bold;"&gt;ActionView::Template&lt;/span&gt;.&lt;span style="color:#5A0A0A; font-weight:bold;"&gt;new&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;app/views/index.html.haml&amp;quot;&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;This is the kind of usefulness that could easily be made into a helper. You can put this in your test_helper.rb.&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="rails geshifilter-rails" style="font-family:monospace;"&gt;  &lt;span style="color:#9966CC; font-weight:bold;"&gt;def&lt;/span&gt; use_template&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;path&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt;
    stub&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#0000FF; font-weight:bold;"&gt;self&lt;/span&gt;&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt;.&lt;span style="color:#9900CC;"&gt;template&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color:#6666ff; font-weight:bold;"&gt;ActionView::Template&lt;/span&gt;.&lt;span style="color:#5A0A0A; font-weight:bold;"&gt;new&lt;/span&gt; &lt;span style="color:#CC00FF; font-weight:bold;"&gt;File&lt;/span&gt;.&lt;span style="color:#9900CC;"&gt;join&lt;/span&gt;&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#996600;"&gt;&amp;quot;app&amp;quot;&lt;/span&gt;, &lt;span style="color:#996600;"&gt;&amp;quot;views&amp;quot;&lt;/span&gt;, path&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#125;&lt;/span&gt;
  &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Now my test looks very neat.&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="rails geshifilter-rails" style="font-family:monospace;"&gt;  &lt;span style="color:#CC0066; font-weight:bold;"&gt;require&lt;/span&gt; &lt;span style="color:#996600;"&gt;'test_helper'&lt;/span&gt;
&amp;nbsp;
  &lt;span style="color:#9966CC; font-weight:bold;"&gt;class&lt;/span&gt; LayoutHelperTest &lt;span style="color:#006600; font-weight:bold;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#6666ff; font-weight:bold;"&gt;ActionView::TestCase&lt;/span&gt;
    context &lt;span style="color:#996600;"&gt;&amp;quot;#title helper&amp;quot;&lt;/span&gt; &lt;span style="color:#9966CC; font-weight:bold;"&gt;do&lt;/span&gt;
      setup &lt;span style="color:#9966CC; font-weight:bold;"&gt;do&lt;/span&gt;
        use_template &lt;span style="color:#996600;"&gt;&amp;quot;pages/index.html.haml&amp;quot;&lt;/span&gt;
      &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;
&amp;nbsp;
      should &lt;span style="color:#996600;"&gt;&amp;quot;create content for title&amp;quot;&lt;/span&gt; &lt;span style="color:#9966CC; font-weight:bold;"&gt;do&lt;/span&gt;
        title&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#996600;"&gt;&amp;quot;foobar&amp;quot;&lt;/span&gt;&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt;
        &lt;span style="color:#5A0A0A; font-weight:bold;"&gt;assert_equal&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;foobar&amp;quot;&lt;/span&gt;, &lt;span style="color:#0066ff; font-weight:bold;"&gt;@content_for_title&lt;/span&gt;
      &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;
    &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;
  &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Running tests... Green! And birds are back!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mediumexposure/~4/0Pw0ODvO9Gk" height="1" width="1"/&gt;</description>
 <comments>http://mediumexposure.com/2009/11/02/testing-helpers-use-scoped-translations#comments</comments>
 <category domain="http://mediumexposure.com/tag/rails">rails</category>
 <category domain="http://mediumexposure.com/tag/ruby">ruby</category>
 <category domain="http://mediumexposure.com/taxonomy/term/3">solutions</category>
 <pubDate>Mon, 02 Nov 2009 21:00:03 +0000</pubDate>
 <dc:creator>hakunin</dc:creator>
 <guid isPermaLink="false">63 at http://mediumexposure.com</guid>
<feedburner:origLink>http://mediumexposure.com/2009/11/02/testing-helpers-use-scoped-translations</feedburner:origLink></item>
<item>
 <title>Off Github</title>
 <link>http://feedproxy.google.com/~r/mediumexposure/~3/_z2Bw7AC6pc/github</link>
 <description>&lt;p&gt;Right about now everyone is switching away from &lt;a href="http://gems.github.com"&gt;GitHub gem host&lt;/a&gt;. It&amp;#8217;s crappy enough that you have to edit environments in your config files — you also have to reinstall the big pile of gems on your machines. Cleaning up my big old gem list doesn&amp;#8217;t strike me as a fun leisure time.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://github.com/maxim/off_github"&gt;Off Github&lt;/a&gt; is there to make this process less painful. Run it on the machines where you have gems installed and it will help you get rid of github legacy.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mediumexposure/~4/_z2Bw7AC6pc" height="1" width="1"/&gt;</description>
 <comments>http://mediumexposure.com/2009/10/28/github#comments</comments>
 <category domain="http://mediumexposure.com/tag/rails">rails</category>
 <category domain="http://mediumexposure.com/tag/ruby">ruby</category>
 <category domain="http://mediumexposure.com/taxonomy/term/3">solutions</category>
 <pubDate>Wed, 28 Oct 2009 16:36:10 +0000</pubDate>
 <dc:creator>hakunin</dc:creator>
 <guid isPermaLink="false">62 at http://mediumexposure.com</guid>
<feedburner:origLink>http://mediumexposure.com/2009/10/28/github</feedburner:origLink></item>
<item>
 <title>Drier gem configs</title>
 <link>http://feedproxy.google.com/~r/mediumexposure/~3/cQUXvV4LzgQ/drier-gem-configs</link>
 <description>&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; This article is obsolete. Gemcutter should take first place in your gem sources. This way there is no reason to use :source option at all.&lt;/p&gt;
&lt;p&gt;Now is the worst time for duplication in gem configs with all the changes going on. &lt;a href="http://github.com"&gt;GitHub&lt;/a&gt; is not a gem host anymore. Soon &lt;a href="http://rubyforge.org"&gt;RubyForge&lt;/a&gt; may follow the same path.&lt;/p&gt;
&lt;p&gt;&lt;span class="geshifilter"&gt;&lt;code class="geshifilter-text"&gt;with_options&lt;/code&gt;&lt;/span&gt; provides a perfect way to minimize this duplication. I personally forgot it even existed until now. Watch how this mess:&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="rails geshifilter-rails" style="font-family:monospace;"&gt;  config.&lt;span style="color:#9900CC;"&gt;gem&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;settingslogic&amp;quot;&lt;/span&gt;, &lt;span style="color:#ff3333; font-weight:bold;"&gt;:source&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;http://gemcutter.org&amp;quot;&lt;/span&gt;
  config.&lt;span style="color:#9900CC;"&gt;gem&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;authlogic&amp;quot;&lt;/span&gt;, &lt;span style="color:#ff3333; font-weight:bold;"&gt;:source&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;http://gemcutter.org&amp;quot;&lt;/span&gt;
  config.&lt;span style="color:#9900CC;"&gt;gem&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;compass&amp;quot;&lt;/span&gt;, &lt;span style="color:#ff3333; font-weight:bold;"&gt;:source&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;http://gemcutter.org&amp;quot;&lt;/span&gt;
  config.&lt;span style="color:#9900CC;"&gt;gem&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;will_paginate&amp;quot;&lt;/span&gt;, &lt;span style="color:#ff3333; font-weight:bold;"&gt;:source&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;http://gemcutter.org&amp;quot;&lt;/span&gt;
  config.&lt;span style="color:#9900CC;"&gt;gem&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;inherited_resources&amp;quot;&lt;/span&gt;, &lt;span style="color:#ff3333; font-weight:bold;"&gt;:source&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;http://gemcutter.org&amp;quot;&lt;/span&gt;
  config.&lt;span style="color:#9900CC;"&gt;gem&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;haml&amp;quot;&lt;/span&gt;, &lt;span style="color:#ff3333; font-weight:bold;"&gt;:source&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;http://gemcutter.org&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;becomes dry&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="rails geshifilter-rails" style="font-family:monospace;"&gt;  config.&lt;span style="color:#9900CC;"&gt;with_options&lt;/span&gt; &lt;span style="color:#ff3333; font-weight:bold;"&gt;:source&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;http://gemcutter.org&amp;quot;&lt;/span&gt; &lt;span style="color:#9966CC; font-weight:bold;"&gt;do&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;|&lt;/span&gt;c&lt;span style="color:#006600; font-weight:bold;"&gt;|&lt;/span&gt;
    c.&lt;span style="color:#9900CC;"&gt;gem&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;settingslogic&amp;quot;&lt;/span&gt;
    c.&lt;span style="color:#9900CC;"&gt;gem&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;authlogic&amp;quot;&lt;/span&gt;
    c.&lt;span style="color:#9900CC;"&gt;gem&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;compass&amp;quot;&lt;/span&gt;
    c.&lt;span style="color:#9900CC;"&gt;gem&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;will_paginate&amp;quot;&lt;/span&gt;
    c.&lt;span style="color:#9900CC;"&gt;gem&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;inherited_resources&amp;quot;&lt;/span&gt;
    c.&lt;span style="color:#9900CC;"&gt;gem&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;haml&amp;quot;&lt;/span&gt;
  &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Forgot to mention that you need to &lt;span class="geshifilter"&gt;&lt;code class="geshifilter-text"&gt;require &amp;quot;active_support&amp;quot;&lt;/code&gt;&lt;/span&gt; in order for this to work in tests, etc. Thanks daeltar in comments.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mediumexposure/~4/cQUXvV4LzgQ" height="1" width="1"/&gt;</description>
 <comments>http://mediumexposure.com/2009/10/27/drier-gem-configs#comments</comments>
 <category domain="http://mediumexposure.com/tag/obsolete">obsolete</category>
 <category domain="http://mediumexposure.com/tag/rails">rails</category>
 <category domain="http://mediumexposure.com/taxonomy/term/3">solutions</category>
 <pubDate>Tue, 27 Oct 2009 22:32:12 +0000</pubDate>
 <dc:creator>hakunin</dc:creator>
 <guid isPermaLink="false">61 at http://mediumexposure.com</guid>
<feedburner:origLink>http://mediumexposure.com/2009/10/27/drier-gem-configs</feedburner:origLink></item>
<item>
 <title>My Tools of the Trade</title>
 <link>http://feedproxy.google.com/~r/mediumexposure/~3/W4kvHI3P72g/my-tools-trade</link>
 <description>&lt;p&gt;I used to be somewhat settled, living my stationary life in a Brooklyn apartment. Circumstances have changed in 2009, when I started to spend a lot of time on the go. This was the point at which all of the commitments, contracts, and physical commodities I had been piling up over the years have emerged in the form of monumental pain. It felt like a greasy, sticky pile of goo keeping me in place. There were car lease, apartment rent, phone contract to name a few. Each one is very costly to terminate.  Above realizations have effectively changed the way I think. What used to be a passive crawl towards comfort-in-the-goo has now morphed into an active strive to achieve compactness and simplicity. A strive for &amp;#8220;life in a backpack&amp;#8221; if you will.&lt;/p&gt;
&lt;p&gt;Certainly these changes have reflected on my tools of trade.&lt;/p&gt;
&lt;h2&gt;Backpack&lt;/h2&gt;
&lt;p&gt;&lt;img src="http://dl.getdropbox.com/u/2274503/tools_of_trade/backpack.jpg" alt="backpack" title="" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Incase backpack &lt;/p&gt;
&lt;p&gt;I had to search through half Manhattan for it (urgent at that moment). It fits everything I need to carry, which is essentially everything I listed here shy of the &amp;#8220;Stationary Hardware&amp;#8221; section.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Mobile Hardware&lt;/h2&gt;
&lt;p&gt;&lt;img src="http://dl.getdropbox.com/u/2274503/tools_of_trade/computers.jpg" alt="computers" title="" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Late 2007 17&amp;#8221; MacBook Pro&lt;/p&gt;
&lt;p&gt;It has 2.6Ghz Core 2 Duo, 4GB RAM, and 200GB 7200RPM HDD. I do vast majority of the work on it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Acer Aspire One&lt;/p&gt;
&lt;p&gt;My &amp;#8220;backup&amp;#8221; computer (with 16Gb SSD and 16Gb SD card) running both WinXP and &lt;a href="http://www.canonical.com/projects/ubuntu/unr"&gt;Ubuntu Netbook Remix&lt;/a&gt;. I use it primarily for leisure as I happen to be a fan of pre-2004 computer RPGs and strategies which netbooks are perfect for. Acer is good for programming too, since it sports an incredible 9hr battery which is perfect for long travels (although most would hate the small size constraint.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://www.amazon.com/Logitech-Optical-Notebook-Mouse-Plus/dp/B0001LTT5K"&gt;Logitech Optical Notebook Mouse Plus&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When it comes to mouse, I never understood wireless. Mouse is not a remote control, you only use it close to the screen, so why care about batteries or recharging? For me it&amp;#8217;s just extra mental/physical weight. Therefore my choice is this neat, wire-wrapping simple mouse.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;iPhone 3G&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Nintendo DS&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Stationary Hardware&lt;/h2&gt;
&lt;p&gt;Since I had some hardware accumulated over the years, and getting rid of it all wouldn&amp;#8217;t make sense, I keep a couple of things in places where I spend most of the time. Mostly it comes down to the following two:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;24&amp;#8221; Samsung monitor&lt;/p&gt;
&lt;p&gt;Located at &lt;a href="http://attic.mediumexposure.com/data/island_workspace.jpg"&gt;one of my destinations&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://www.overclockersclub.com/reviews/freeagent_pro_1tb/"&gt;1TB Seagate FreeAgent Pro&lt;/a&gt; HDD&lt;/p&gt;
&lt;p&gt;Stationed at another location. I use it for time machine backups.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Misc&lt;/h2&gt;
&lt;p&gt;&lt;img src="http://dl.getdropbox.com/u/2274503/tools_of_trade/misc.jpg" alt="misc" title="" /&gt;&lt;/p&gt;
&lt;p&gt;In this small pocket I keep all kinds of misc SD cards, USB thumb drives, and DS games.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://dl.getdropbox.com/u/2274503/tools_of_trade/sketchbooks.jpg" alt="sketchbooks" title="" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.moleskines.com/klmrl717.html"&gt;Moleskine sketchbook&lt;/a&gt; — I&amp;#8217;m not a proponent of using Balsamiq or other wireframe solutions, todo, or time management software. Instead I prefer a small sketchbook (notes and small drawings), a big sketchbook (wire-framing, mind-mapping), and a pencil. I like that particular linked sketchbook because IMHO reporter-style is more comfortable than normal book-style. Besides, I hate any kind of grid on the pages, hence plain.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Software&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://firefox.com"&gt;Firefox&lt;/a&gt; — I use it with (and because of) following extensions.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://agilewebsolutions.com/products/1Password"&gt;1Password&lt;/a&gt; — no more looking for wallet, and no more reusing of the same password.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://adblockplus.org/en/"&gt;Adblock Plus&lt;/a&gt; — block ads (duh).&lt;/li&gt;
&lt;li&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1027"&gt;All-in-One Sidebar&lt;/a&gt; — replaces all the meddling firefox popups (downloads/extensions/history panels) with a neat sidebar.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.customizegoogle.com/"&gt;CustomizeGoogle&lt;/a&gt; — tons of Google search customizations.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.downloadhelper.net/"&gt;DownloadHelper&lt;/a&gt; — because sometimes online flash players suck.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://getfirebug.com/"&gt;Firebug&lt;/a&gt; — ultimate front-end debugger.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/5791"&gt;Flagfox&lt;/a&gt; — I always found it fun to know in which country a website is hosted.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/189"&gt;GooglePreview&lt;/a&gt; — helps browse results and quickly know what to expect.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://addons.mozilla.org/firefox/addon/2036"&gt;Server Spy&lt;/a&gt; — quick and convenient way to know which server is running on visited websites. One more curiosity satisfier.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/5447"&gt;Tab Kit&lt;/a&gt; — primary reason I&amp;#8217;m sticking with Firefox. When you have &gt; 30 tabs open at a time, and you&amp;#8217;re using widescreen — vertical tabs are the way to go. Additionally, this plugin also does nesting and coloring which is incredibly useful for relating tabs to one-another (ie: links opened from this blog post will appear in tabs nested under the post&amp;#8217;s tab).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://labs.mozilla.com/ubiquity/"&gt;Ubiquity&lt;/a&gt; — this extension contains tons of awesomeness - you better see their screencast. However, I primarily use it as QuickSilver of Firefox. Opt+Space, type some words from the needed tab, Enter, the tab focuses. Incredibly useful when you have &gt;30 tabs open.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/60"&gt;Web Developer&lt;/a&gt; — mostly for &amp;#8220;disable cache&amp;#8221; feature, different enable/disable shortcuts for javascript, css, etc, and cleaning cookies.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.xmarks.com/"&gt;XMarks&lt;/a&gt; — former Foxmarks for bookmark sync across browsers and computers.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://developer.yahoo.com/yslow/"&gt;YSlow&lt;/a&gt; — a treasure chest of optimization tips and benchmarks for improving site performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://macromates.com"&gt;TextMate&lt;/a&gt; — This is my code editor of choice. I also recently got interested in vim, and have been learning it, but haven&amp;#8217;t really gotten comfortable enough to use it for most tasks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://www.newsgator.com/INDIVIDUALS/NETNEWSWIRE/"&gt;NetNewsWire&lt;/a&gt; — This is a great RSS reader which syncs with Google Reader as well as its complementary iPhone app. Definitely my favorite.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://wiki.github.com/koroshiya1/pwitter"&gt;Pwitter&lt;/a&gt; — I&amp;#8217;m not a heavy twitterer. I want a simple, resource-friendly mac client which works with growl and has all basic features. Pwitter has met and exceeded (in a good way) everything I wanted from a twitter client. I think it&amp;#8217;s pretty underestimated.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://www.mozillamessaging.com/en-US/thunderbird/early_releases/"&gt;Thunderbird 3&lt;/a&gt; — this is my shaky ground right now. I grew tired of how primitive Mail.app is. At the same time, I can&amp;#8217;t keep gmail.com open. It runs flash which keeps crashing my browser under Snow Leopard. I was pleasantly surprised by the new features of Thunderbird 3. Among other additions, Mozilla taught it to speak the Gmail language (archiving, all mail, etc). This wasn&amp;#8217;t the case in previous versions, which I disliked. It also serves as a great newsgroups reader, which I use to read &lt;a href="http://groups.google.com/group/comp.lang.ruby"&gt;comp.lang.ruby&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Terminal — this is another treasure chest of irreplaceable tools some of which have existed since Unix inception.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://www.apple.com/itunes/"&gt;iTunes&lt;/a&gt; — helps me stay updated with podcasts such as &lt;a href="http://railscasts.com"&gt;Railscasts&lt;/a&gt;, &lt;a href="http://railsenvy.com"&gt;RailsEnvy&lt;/a&gt;, and &lt;a href="http://ruby5.envylabs.com/"&gt;Ruby5&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://gitx.frim.nl/"&gt;GitX&lt;/a&gt; — Awesome git browser for mac with some repo-manipulating capabilities. However, I mostly use it for its staging convenience. Sometimes I do too much at once. GitX provides very convenient GUI to split all the unstaged mess into separate neat commits.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.photoshop.com/"&gt;Photoshop&lt;/a&gt; — I&amp;#8217;ve become quite comfortable with photoshop. Use it for any non-batch image tasks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://cyberduck.ch/"&gt;Cyberduck&lt;/a&gt; — this is my sftp client of choice. It&amp;#8217;s free and works well for me.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://getdropbox.com"&gt;Dropbox&lt;/a&gt; — great for quick file upload/sync/backup. Pics for this blog post were taken on iPhone, synced through dropbox, and are linked directly from there.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://www.apple.com/macosx/what-is-macosx/mail-ical-address-book.html"&gt;iCal&lt;/a&gt; — I tend to use reminders a lot. I also keep track of bills and projects this way. However, I prefer my physical notepad for daily goals.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://blacktree.com/"&gt;QuickSilver&lt;/a&gt; — this is definitely my Swiss Army Knife. Irreplaceable for navigation and file operations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://www.ironstarmedia.co.uk/osx-image-resizer/"&gt;ImageResizer&lt;/a&gt; — convenient little tool for batch image resizing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Communication&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.skype.com/download/skype/macosx/"&gt;Skype&lt;/a&gt; — I work remotely a lot as you can imagine.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://adium.im"&gt;Adium&lt;/a&gt; — looks like the best AOL/ICQ/YIM/MSN/GTK mac client out there.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://limechat.net/mac/"&gt;LimeChat&lt;/a&gt; - I used to like Colloquy, but its resource-hogging habits forced me to look for better alternatives. So far this has been incredibly nice and lightweight sporting all the features I need in an IRC client.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Hosting&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://dreamhost.com/"&gt;Dreamhost&lt;/a&gt; — this is my sandbox environment. I don&amp;#8217;t use it for anything but hosting this blog and some personal side-projects. The occasional bumpy service is justified by the price though.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://webfaction.com/"&gt;WebFaction&lt;/a&gt; — a very easy-to-use, affordable, and incredibly fast/stable shared hosting. Currently runs two projects (&lt;a href="http://scripteka.com"&gt;Scripteka&lt;/a&gt; and &lt;a href="http://wehike.net"&gt;Wehike&lt;/a&gt;) on one account without any problems.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://linode.com"&gt;Linode&lt;/a&gt; — our first stage heavy-weight. If an app is expected to have any significant load, this is where we start developing.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.turnkeyinternet.net/"&gt;Turnkey Internet&lt;/a&gt; — we use this for dedicated servers because they seem to be the most affordable while having well-performing network. However, most of sysadmin burden goes on your shoulders. There are options with more support, but they aren&amp;#8217;t cheap.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://heroku.com"&gt;Heroku&lt;/a&gt; — lately this is the place I go for my personal Rails projects. The deployment strategy there is pretty freaking incredible.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Simplifying and compacting your life is not easy. I mostly try to have fewer tools covering broader range of tasks. This helps portability and keeps me sane. As opposed to &lt;a href="http://afreshcup.com/2009/10/11/my-tools-of-the-trade-2009/"&gt;Mike Gunderloy&amp;#8217;s Tools of Trade&lt;/a&gt; my set tends to have very little overlap in functionality. Single image editor, single organizational tool, etc. Interestingly, I don&amp;#8217;t  actively pursue this concept. I just don&amp;#8217;t feel the need for more yet. Surely this list will expand in the future.&lt;/p&gt;
&lt;p&gt;This post was inspired by &lt;a href="http://afreshcup.com/2009/10/11/my-tools-of-the-trade-2009/"&gt;Mike Gunderloy&amp;#8217;s Tools of Trade&lt;/a&gt;. I&amp;#8217;d like to join him in encouraging you to write your own &amp;#8220;Tools of Trade&amp;#8221; post.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mediumexposure/~4/W4kvHI3P72g" height="1" width="1"/&gt;</description>
 <comments>http://mediumexposure.com/2009/10/11/my-tools-trade#comments</comments>
 <category domain="http://mediumexposure.com/taxonomy/term/11">concepts</category>
 <category domain="http://mediumexposure.com/taxonomy/term/3">solutions</category>
 <pubDate>Mon, 12 Oct 2009 02:00:54 +0000</pubDate>
 <dc:creator>hakunin</dc:creator>
 <guid isPermaLink="false">60 at http://mediumexposure.com</guid>
<feedburner:origLink>http://mediumexposure.com/2009/10/11/my-tools-trade</feedburner:origLink></item>
<item>
 <title>Rake script for managing Rails plugins with Git submodules</title>
 <link>http://feedproxy.google.com/~r/mediumexposure/~3/PhdKS4fpHO8/rake-script-managing-rails-plugins-git-submodules</link>
 <description>&lt;h2&gt;Problem with gitmodules and rails plugins&lt;/h2&gt;
&lt;p&gt;Submodules aren&amp;#8217;t very easy. You have to know a few things before messing with them. When installing you have to follow a bunch of steps in order to get them properly registered within git. Uninstalling is even sadder. You need to manually edit a couple of git config files, and perform some more git operations.  When dealing with Rails plugins - you should also remember to check if plugin contains an install.rb/uninstall.rb hook and run them manually. This is enough repetitive crap for me to justify some automation.&lt;/p&gt;
&lt;h2&gt;Solution: Automation with Rake&lt;/h2&gt;
&lt;p&gt;Note: &lt;strong&gt;This solution is specifically for rails plugins hosted on &lt;a href="http://github.com"&gt;github&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When I think &lt;em&gt;automation&lt;/em&gt; in the context of Rails - I immediately think &lt;strong&gt;rake&lt;/strong&gt;. Without further ado I present &lt;a href="http://gist.github.com/185746"&gt;a rake script&lt;/a&gt; which takes care of all the aforementioned problems for you.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Automated module install - no need to run any git commands.&lt;/li&gt;
&lt;li&gt;Automated module uninstall - no need to edit git config files by hand.&lt;/li&gt;
&lt;li&gt;Automated running of install.rb/uninstall.rb plugin hooks.&lt;/li&gt;
&lt;li&gt;Automated module updates.&lt;/li&gt;
&lt;li&gt;Automatically uses github.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The usage is as simple as it gets. Read comments on top for list of available tasks.&lt;/p&gt;
&lt;h2&gt;Grab&lt;/h2&gt;
&lt;p&gt;Grab it here: &lt;a href="http://gist.github.com/185746"&gt;http://gist.github.com/185746&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mediumexposure/~4/PhdKS4fpHO8" height="1" width="1"/&gt;</description>
 <comments>http://mediumexposure.com/2009/09/12/rake-script-managing-rails-plugins-git-submodules#comments</comments>
 <category domain="http://mediumexposure.com/tag/rails">rails</category>
 <category domain="http://mediumexposure.com/tag/ruby">ruby</category>
 <category domain="http://mediumexposure.com/taxonomy/term/3">solutions</category>
 <pubDate>Sat, 12 Sep 2009 18:47:59 +0000</pubDate>
 <dc:creator>hakunin</dc:creator>
 <guid isPermaLink="false">59 at http://mediumexposure.com</guid>
<feedburner:origLink>http://mediumexposure.com/2009/09/12/rake-script-managing-rails-plugins-git-submodules</feedburner:origLink></item>
<item>
 <title>Getting Rails 2.3.3 and Mocha &gt;=0.9.6 to play nice with Test::Unit and Shoulda</title>
 <link>http://feedproxy.google.com/~r/mediumexposure/~3/KyKVYCEdZUU/getting-rails-233-and-mocha-096-play-nice-testunit-and-shoulda</link>
 <description>&lt;p&gt;Simultaneous changes in Rails 2.3.3 and Mocha &amp;gt;=0.9.6 have caused some headaches in test::unit (or shoulda) tests. In my case I saw anomalies such as expectations persisting across tests. You put expects(:foo).never in test A and get &amp;#8220;unsatisfied expectation&amp;#8221; failure in test B where you happen to call :foo. This is due to unfortunate dependency on load order which could cause runner logic to be erroneously overridden. Here&amp;#8217;s the steps you need to take to tidy up this setup to make sure it works correctly.&lt;/p&gt;
&lt;h3&gt;Update mocha to &gt;= 0.9.7&lt;/h3&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="bash geshifilter-bash" style="font-family:monospace;"&gt;  ~&lt;span style="color: #000000; font-weight: bold;"&gt;%&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; gem update mocha&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;h3&gt;Install test-unit gem&lt;/h3&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="bash geshifilter-bash" style="font-family:monospace;"&gt;  ~&lt;span style="color: #000000; font-weight: bold;"&gt;%&lt;/span&gt; &lt;span style="color: #c20cb9; font-weight: bold;"&gt;sudo&lt;/span&gt; gem &lt;span style="color: #c20cb9; font-weight: bold;"&gt;install&lt;/span&gt; test-unit&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;h3&gt;Don't load mocha yourself&lt;/h3&gt;
&lt;p&gt;If you had anything like this line in your test environment, &lt;span class="caps"&gt;REMOVE IT&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;del&gt;&lt;span class="geshifilter"&gt;&lt;code class="geshifilter-text"&gt;config.gem &amp;quot;mocha&amp;quot;&lt;/code&gt;&lt;/span&gt;&lt;/del&gt;&lt;/p&gt;
&lt;h3&gt;Ensure correct load order&lt;/h3&gt;
&lt;p&gt;If using Shoulda, make sure your test.rb environment loads test-unit before shoulda.&lt;br /&gt;
&lt;div class="geshifilter"&gt;&lt;pre class="rails geshifilter-rails" style="font-family:monospace;"&gt;  config.&lt;span style="color:#9900CC;"&gt;gem&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;test-unit&amp;quot;&lt;/span&gt;, &lt;span style="color:#ff3333; font-weight:bold;"&gt;:lib&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;test/unit&amp;quot;&lt;/span&gt;, &lt;span style="color:#ff3333; font-weight:bold;"&gt;:version&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;&amp;gt;=2.0.3&amp;quot;&lt;/span&gt; 
  config.&lt;span style="color:#9900CC;"&gt;gem&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;thoughtbot-shoulda&amp;quot;&lt;/span&gt;, &lt;span style="color:#ff3333; font-weight:bold;"&gt;:lib&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;shoulda&amp;quot;&lt;/span&gt;, &lt;span style="color:#ff3333; font-weight:bold;"&gt;:source&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;http://gems.github.com&amp;quot;&lt;/span&gt;, &lt;span style="color:#ff3333; font-weight:bold;"&gt;:version&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#996600;"&gt;&amp;quot;&amp;gt;=2.10.1&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;This should hopefully fix mocha issues with rails 2.3.3.&lt;/p&gt;
&lt;p&gt;For more explanation check out &lt;a href="http://groups.google.com/group/mocha-developer/browse_thread/thread/bd76e2f0ec28459a"&gt;this message&lt;/a&gt; on mocha&amp;#8217;s mail list and &lt;a href="https://rails.lighthouseapp.com/projects/8994/tickets/2858"&gt;this lighthouse ticket&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mediumexposure/~4/KyKVYCEdZUU" height="1" width="1"/&gt;</description>
 <comments>http://mediumexposure.com/2009/08/02/getting-rails-233-and-mocha-096-play-nice-testunit-and-shoulda#comments</comments>
 <category domain="http://mediumexposure.com/tag/rails">rails</category>
 <category domain="http://mediumexposure.com/tag/ruby">ruby</category>
 <category domain="http://mediumexposure.com/taxonomy/term/3">solutions</category>
 <pubDate>Sun, 02 Aug 2009 14:59:33 +0000</pubDate>
 <dc:creator>hakunin</dc:creator>
 <guid isPermaLink="false">58 at http://mediumexposure.com</guid>
<feedburner:origLink>http://mediumexposure.com/2009/08/02/getting-rails-233-and-mocha-096-play-nice-testunit-and-shoulda</feedburner:origLink></item>
<item>
 <title>Avoiding nested blocks</title>
 <link>http://feedproxy.google.com/~r/mediumexposure/~3/a274OMFxHyU/avoiding-nested-blocks</link>
 <description>&lt;p&gt;Today I had to silence some output streams so that messages don&amp;#8217;t pollute the &lt;span class="caps"&gt;STDOUT&lt;/span&gt;. I used the &lt;span class="geshifilter"&gt;&lt;code class="geshifilter-text"&gt;silence_stream&lt;/code&gt;&lt;/span&gt; method built into Rails, described well in &lt;a href="http://www.misuse.org/science/2007/08/01/suppressing-output-in-rubyrails/"&gt;this article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="ruby geshifilter-ruby" style="font-family:monospace;"&gt;  silence_stream&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;STDOUT&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#9966CC; font-weight:bold;"&gt;do&lt;/span&gt;
    &lt;span style="color:#008000; font-style:italic;"&gt;# ...my code...&lt;/span&gt;
  &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Very nice, except I also wanted to filter &lt;span class="caps"&gt;STDERR&lt;/span&gt; output. Not a problem.&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="ruby geshifilter-ruby" style="font-family:monospace;"&gt;  silence_stream&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;STDOUT, STDERR&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#9966CC; font-weight:bold;"&gt;do&lt;/span&gt;
    &lt;span style="color:#008000; font-style:italic;"&gt;# ...my code...&lt;/span&gt;
  &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Well, shit. Here I got a &amp;#8220;too many arguments&amp;#8221; error. So it doesn&amp;#8217;t support multiple streams. I guess it wants me to be ugly.&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="ruby geshifilter-ruby" style="font-family:monospace;"&gt;  silence_stream&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;STDOUT&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#9966CC; font-weight:bold;"&gt;do&lt;/span&gt;
    silence_stream&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;STDERR&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#9966CC; font-weight:bold;"&gt;do&lt;/span&gt;
      &lt;span style="color:#008000; font-style:italic;"&gt;# ...my code...&lt;/span&gt;
    &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;
  &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;I personally don&amp;#8217;t take kindly this level of suckiness around here. I want example #2 to work. Well, after lighting some candles and praying to the Ruby gods, I came up with a scary implementation. In fact it&amp;#8217;s so spooky that it may have the same effect as glancing at the &lt;a href="http://en.wikipedia.org/wiki/The_Mexican_Staring_Frog_of_Southern_Sri_Lanka"&gt;Mexican Starting Frog of Southern Sri Lanka&lt;/a&gt;. You may then throw a chair at me on the Jerry Springer show, so I rather not show it to you.&lt;/p&gt;
&lt;p&gt;However, after having cleansed my .rb file with some broc flowers and xander roots I came up with a better solution. Recursion is the key. See if you can understand what is happening.&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="ruby geshifilter-ruby" style="font-family:monospace;"&gt;&lt;span style="color:#9966CC; font-weight:bold;"&gt;def&lt;/span&gt; silence_streams&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#006600; font-weight:bold;"&gt;*&lt;/span&gt;streams, &lt;span style="color:#006600; font-weight:bold;"&gt;&amp;amp;&lt;/span&gt;blk&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt;
  silence_stream&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;streams.&lt;span style="color:#9900CC;"&gt;pop&lt;/span&gt;&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#9966CC; font-weight:bold;"&gt;do&lt;/span&gt;
    &lt;span style="color:#9966CC; font-weight:bold;"&gt;if&lt;/span&gt; streams.&lt;span style="color:#9900CC;"&gt;empty&lt;/span&gt;?
      &lt;span style="color:#9966CC; font-weight:bold;"&gt;yield&lt;/span&gt;
    &lt;span style="color:#9966CC; font-weight:bold;"&gt;else&lt;/span&gt;
      silence_streams&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color:#006600; font-weight:bold;"&gt;*&lt;/span&gt;streams, &lt;span style="color:#006600; font-weight:bold;"&gt;&amp;amp;&lt;/span&gt;blk&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt;
    &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;
  &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;
&lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;This is a basic use of recursion, which is not immediately clear when dealing with nested Ruby blocks. When multiple streams are passed in I&amp;#8217;m popping out the last stream and silencing it alone, then calling the same method with the remaining streams. This is happening until only one stream left to silence. The last one gets silenced with the original block passed in, which means that the original block is executed at the deepest nesting level, where all passed streams are silenced. As a result I got this much desired functionality without resorting to eval, yay.&lt;/p&gt;
&lt;p&gt;&lt;div class="geshifilter"&gt;&lt;pre class="ruby geshifilter-ruby" style="font-family:monospace;"&gt;  silence_streams&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#40;&lt;/span&gt;STDOUT, STDERR&lt;span style="color:#006600; font-weight:bold;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color:#9966CC; font-weight:bold;"&gt;do&lt;/span&gt;
    &lt;span style="color:#008000; font-style:italic;"&gt;# ...my code...&lt;/span&gt;
  &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;There we go. This solution can be applied to cases where you&amp;#8217;d rather avoid overriding stuff (thus keeping out of method implementation details).&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update:&lt;/strong&gt; Made recursion more concise thanks to apeiros on #railsbridge.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mediumexposure/~4/a274OMFxHyU" height="1" width="1"/&gt;</description>
 <comments>http://mediumexposure.com/2009/07/15/avoiding-nested-blocks#comments</comments>
 <category domain="http://mediumexposure.com/tag/rails">rails</category>
 <category domain="http://mediumexposure.com/tag/ruby">ruby</category>
 <category domain="http://mediumexposure.com/taxonomy/term/3">solutions</category>
 <pubDate>Thu, 16 Jul 2009 05:48:32 +0000</pubDate>
 <dc:creator>hakunin</dc:creator>
 <guid isPermaLink="false">57 at http://mediumexposure.com</guid>
<feedburner:origLink>http://mediumexposure.com/2009/07/15/avoiding-nested-blocks</feedburner:origLink></item>
<item>
 <title>Dumb tester_elf</title>
 <link>http://feedproxy.google.com/~r/mediumexposure/~3/WbmnaX3-FGg/dumb-testerelf</link>
 <description>&lt;p&gt;This tester_elf script is very dumb, which is uncharacteristic of elves in general. Why did I name it tester_elf? Well, it&amp;#8217;s a &lt;em&gt;Santa&amp;#8217;s little helper&lt;/em&gt; type of elf as opposed to an individual of Tolkien&amp;#8217;s highly cultural race. I do crave some nice D&amp;#38;D &lt;span class="caps"&gt;RPG&lt;/span&gt; experience but there aren&amp;#8217;t any good new games in that direction. Everything gets dumbed down nowadays.&lt;/p&gt;
&lt;p&gt;Anyhow, &lt;a href="http://bit.ly/c4JpZ"&gt;here&amp;#8217;s the gist of it&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It just runs a test file every time you save it. Stupid but useful when autotest is too bulky. Instructions are in the gist.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mediumexposure/~4/WbmnaX3-FGg" height="1" width="1"/&gt;</description>
 <comments>http://mediumexposure.com/2009/06/21/dumb-testerelf#comments</comments>
 <category domain="http://mediumexposure.com/tag/rails">rails</category>
 <category domain="http://mediumexposure.com/tag/ruby">ruby</category>
 <category domain="http://mediumexposure.com/taxonomy/term/3">solutions</category>
 <pubDate>Sun, 21 Jun 2009 20:23:40 +0000</pubDate>
 <dc:creator>hakunin</dc:creator>
 <guid isPermaLink="false">56 at http://mediumexposure.com</guid>
<feedburner:origLink>http://mediumexposure.com/2009/06/21/dumb-testerelf</feedburner:origLink></item>
<item>
 <title>yui_compressor_fu</title>
 <link>http://feedproxy.google.com/~r/mediumexposure/~3/YjKXjdJJMy8/yuicompressorfu</link>
 <description>&lt;p&gt;Please welcome a new thingie I just released &amp;#8211; &lt;a href="http://github.com/maxim/yui_compressor_fu"&gt;yui_compressor_fu&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Point&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://github.com/maxim/yui_compressor_fu"&gt;yui_compressor_fu&lt;/a&gt; delicately minifies all your assets (linked with &lt;span class="geshifilter"&gt;&lt;code class="geshifilter-text"&gt;javascript_include_tag&lt;/code&gt;&lt;/span&gt;, &lt;span class="geshifilter"&gt;&lt;code class="geshifilter-text"&gt;stylesheet_link_tag&lt;/code&gt;&lt;/span&gt; helpers) with &lt;a href="http://developer.yahoo.com/yui/compressor/"&gt;&lt;span class="caps"&gt;YUI&lt;/span&gt; Compressor&lt;/a&gt;. It abides Rails caching rules. All you have to do is install the plugin, and minifying will automatically kick-in when rails performs its normal caching routines.&lt;/p&gt;
&lt;h3&gt;Tale&lt;/h3&gt;
&lt;p&gt;Today I was having my usual cup of Earl Grey with lemon while trying to find some JS/CSS minifying solution. Nowadays Rails provides built-in concatenation and caching, but not compression. I wanted to find something that transparently adds some minifying to the mix. Well, not so fast.&lt;/p&gt;
&lt;p&gt;After flipping through quite a few choices, I wasn&amp;#8217;t impressed at all. Available plugins either require too much configuration (why do I have to list all my assets again, asset_packager?) or they use inferior compression algorithms (Packer/MinJS). According to my research (don&amp;#8217;t quote me) &amp;#8211; &lt;a href="http://developer.yahoo.com/yui/compressor/"&gt;&lt;span class="caps"&gt;YUI&lt;/span&gt; Compressor&lt;/a&gt; kicks some major ass. A few minutes of fruitless digging later I decided to make this plugin instead.&lt;/p&gt;
&lt;p&gt;Feel free to try it out and &lt;a href="http://github.com/maxim/yui_compressor_fu/issues"&gt;let me know of any issues&lt;/a&gt; you encounter.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mediumexposure/~4/YjKXjdJJMy8" height="1" width="1"/&gt;</description>
 <comments>http://mediumexposure.com/2009/05/29/yuicompressorfu#comments</comments>
 <category domain="http://mediumexposure.com/tag/rails">rails</category>
 <category domain="http://mediumexposure.com/tag/ruby">ruby</category>
 <category domain="http://mediumexposure.com/taxonomy/term/3">solutions</category>
 <pubDate>Sat, 30 May 2009 06:08:30 +0000</pubDate>
 <dc:creator>hakunin</dc:creator>
 <guid isPermaLink="false">55 at http://mediumexposure.com</guid>
<feedburner:origLink>http://mediumexposure.com/2009/05/29/yuicompressorfu</feedburner:origLink></item>
<item>
 <title>Better in-memory associations with :inverse_of</title>
 <link>http://feedproxy.google.com/~r/mediumexposure/~3/-d4J_3s9mXQ/better-memory-associations-inverseof</link>
 <description>&lt;p&gt;Today &lt;a href="http://rubyonrails.com"&gt;Rails&lt;/a&gt; gained a very interesting &lt;a href="http://github.com/rails/rails/commit/ccea98389abbf150b886c9f964b1def47f00f237"&gt;commit&lt;/a&gt; from &lt;a href="http://github.com/h-lame"&gt;h-lame&lt;/a&gt;. It&amp;#8217;s the first major step towards making associations aware of their parent model while still in-memory.  A few days ago I started &lt;a href="http://groups.google.com/group/rubyonrails-core/browse_thread/thread/eaba411bb69c58d8?fwc=1"&gt;this discussion&lt;/a&gt; which revealed to me that it had been a long time coming, just no one bothered.&lt;/p&gt;
&lt;p&gt;Well, finally someone did.  I would like to thank &lt;a href="http://github.com/h-lame"&gt;h-lame&lt;/a&gt; for making &lt;a href="http://github.com/rails/rails/commit/ccea98389abbf150b886c9f964b1def47f00f237"&gt;this commit&lt;/a&gt; happen. Here&amp;#8217;s the excerpt from the commit message.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can now add an :inverse_of option to has_one, has_many and belongs_to associations. This is best described with an example:&lt;br /&gt;
    &lt;div class="geshifilter"&gt;&lt;pre class="rails geshifilter-rails" style="font-family:monospace;"&gt;      &lt;span style="color:#9966CC; font-weight:bold;"&gt;class&lt;/span&gt; Man &lt;span style="color:#006600; font-weight:bold;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#6666ff; font-weight:bold;"&gt;ActiveRecord::Base&lt;/span&gt;
        &lt;span style="color:#5A0A0A; font-weight:bold;"&gt;has_one&lt;/span&gt; &lt;span style="color:#ff3333; font-weight:bold;"&gt;:face&lt;/span&gt;, &lt;span style="color:#ff3333; font-weight:bold;"&gt;:inverse_of&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#ff3333; font-weight:bold;"&gt;:man&lt;/span&gt;
      &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;
&amp;nbsp;
      &lt;span style="color:#9966CC; font-weight:bold;"&gt;class&lt;/span&gt; Face &lt;span style="color:#006600; font-weight:bold;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#6666ff; font-weight:bold;"&gt;ActiveRecord::Base&lt;/span&gt;
        &lt;span style="color:#5A0A0A; font-weight:bold;"&gt;belongs_to&lt;/span&gt; &lt;span style="color:#ff3333; font-weight:bold;"&gt;:man&lt;/span&gt;, &lt;span style="color:#ff3333; font-weight:bold;"&gt;:inverse_of&lt;/span&gt; &lt;span style="color:#006600; font-weight:bold;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#ff3333; font-weight:bold;"&gt;:face&lt;/span&gt;
      &lt;span style="color:#9966CC; font-weight:bold;"&gt;end&lt;/span&gt;
&amp;nbsp;
      m = Man.&lt;span style="color:#5A0A0A; font-weight:bold;"&gt;first&lt;/span&gt;
      f = m.&lt;span style="color:#9900CC;"&gt;face&lt;/span&gt;
&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
    Without :inverse_of m and f.man would be different instances of the same object (f.man being pulled from the database again).&lt;/p&gt;
&lt;/blockquote&gt;&lt;img src="http://feeds.feedburner.com/~r/mediumexposure/~4/-d4J_3s9mXQ" height="1" width="1"/&gt;</description>
 <comments>http://mediumexposure.com/2009/05/04/better-memory-associations-inverseof#comments</comments>
 <category domain="http://mediumexposure.com/tag/edge">edge</category>
 <category domain="http://mediumexposure.com/tag/rails">rails</category>
 <category domain="http://mediumexposure.com/tag/ruby">ruby</category>
 <pubDate>Tue, 05 May 2009 04:21:32 +0000</pubDate>
 <dc:creator>hakunin</dc:creator>
 <guid isPermaLink="false">54 at http://mediumexposure.com</guid>
<feedburner:origLink>http://mediumexposure.com/2009/05/04/better-memory-associations-inverseof</feedburner:origLink></item>
</channel>
</rss>
