<?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>Carl Mercier&#039;s blog &#187; Ruby</title>
	<atom:link href="http://blog.carlmercier.com/category/software-development/ruby-software-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.carlmercier.com</link>
	<description>me = entrepreneur + hacker;</description>
	<lastBuildDate>Thu, 02 Feb 2012 18:38:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>YAML, ZAML, Marshal &amp; JSON benchmark in Ruby</title>
		<link>http://blog.carlmercier.com/2010/11/19/yaml-zaml-marshal-json-benchmark-in-ruby/</link>
		<comments>http://blog.carlmercier.com/2010/11/19/yaml-zaml-marshal-json-benchmark-in-ruby/#comments</comments>
		<pubDate>Fri, 19 Nov 2010 23:18:42 +0000</pubDate>
		<dc:creator>Carl Mercier</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.carlmercier.com/?p=282</guid>
		<description><![CDATA[At Defensio, we recently needed to find out how slow YAML was compared to Marshal. We also wanted to know how much faster ZAML, an alternative to YAML, is. I ran a few benchmarks under 1.8.7 MRI, 1.8.7 REE, 1.9.2 and Rubinius to see how they compare. I also benchmarked to_json to have an order [...]]]></description>
			<content:encoded><![CDATA[<p>At Defensio, we recently needed to find out how slow YAML was compared to Marshal. We also wanted to know how much faster ZAML, an alternative to YAML, is.</p>
<p>I ran a few benchmarks under 1.8.7 MRI, 1.8.7 REE, 1.9.2 and Rubinius to see how they compare. I also benchmarked to_json to have an order of magnitude. My benchmarks consist of serializing/deserializing a relatively complex Hash (many nested levels). The YAML representation of the Hash is ~3kb.</p>
<p>Conclusions:</p>
<ul>
<li>YAML is really slow</li>
<li>YAML is twice as fast under 1.9.2 vs 1.8.7</li>
<li>ZAML is much faster than YAML under 1.8.7, but about the same in 1.9.2</li>
<li>REE (no GC tweaks) isn&#8217;t faster in this situation</li>
<li>Rubinius is ridiculously slow</li>
<li>Psych under Ruby 1.9.2 is disappointing </li>
</ul>
<p>Here are the results:</p>
<div id="gist-707375" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]</div><div class='line' id='LC2'>--------------------------------------------------------------------</div><div class='line' id='LC3'>YAML.load:	0.7924</div><div class='line' id='LC4'>Marshal.load:	0.0742</div><div class='line' id='LC5'>to_yaml:	5.1661</div><div class='line' id='LC6'>ZAML.dump:	1.4574</div><div class='line' id='LC7'>to_json:	0.1152</div><div class='line' id='LC8'>Marshal.dump:	0.0845</div><div class='line' id='LC9'><br/></div><div class='line' id='LC10'>ruby 1.8.7 (2010-04-19 patchlevel 253) [i686-darwin10.4.0], MBARI 0x6770, Ruby Enterprise Edition 2010.02</div><div class='line' id='LC11'>--------------------------------------------------------------------</div><div class='line' id='LC12'>YAML.load:	0.7976</div><div class='line' id='LC13'>Marshal.load:	0.0864</div><div class='line' id='LC14'>to_yaml:	4.9012</div><div class='line' id='LC15'>ZAML.dump:	1.3508</div><div class='line' id='LC16'>to_json:	0.0940</div><div class='line' id='LC17'>Marshal.dump:	0.0812</div><div class='line' id='LC18'><br/></div><div class='line' id='LC19'>ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.5.0]</div><div class='line' id='LC20'>--------------------------------------------------------------------</div><div class='line' id='LC21'>YAML.load:		0.7079</div><div class='line' id='LC22'>YAML.load (Psych):	2.6055</div><div class='line' id='LC23'>Marshal.load:		0.0928</div><div class='line' id='LC24'>to_yaml:		2.1682</div><div class='line' id='LC25'>to_load (Psych):	2.2924</div><div class='line' id='LC26'>ZAML.dump:		5.0259</div><div class='line' id='LC27'>to_json:		0.1133</div><div class='line' id='LC28'>Marshal.dump:		0.0908</div><div class='line' id='LC29'><br/></div><div class='line' id='LC30'><br/></div><div class='line' id='LC31'><br/></div><div class='line' id='LC32'>rubinius 1.1.1 (1.8.7 4018ebda 2010-11-16 JI) [x86_64-apple-darwin10.5.0]</div><div class='line' id='LC33'>--------------------------------------------------------------------</div><div class='line' id='LC34'>YAML.load:	2.7777</div><div class='line' id='LC35'>Marshal.load:	0.8560</div><div class='line' id='LC36'>to_yaml:	23.5828</div><div class='line' id='LC37'>ZAML.dump:	4.0745</div><div class='line' id='LC38'>to_json:	3.6620</div><div class='line' id='LC39'>Marshal.dump:	3.3797</div><div class='line' id='LC40'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/707375/8d21fe844733da7ff00e650103c08dcda34d1b9d/yaml_benchmark_results.txt" style="float:right;">view raw</a>
            <a href="https://gist.github.com/707375#file_yaml_benchmark_results.txt" style="float:right;margin-right:10px;color:#666">yaml_benchmark_results.txt</a>
            <a href="https://gist.github.com/707375">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>If you want to benchmark on your machine, here&#8217;s the source code. Sorry, I couldn&#8217;t include the YAML string as it is confidential data.</p>
<div id="gist-707372" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nb">require</span> <span class="s1">&#39;rubygems&#39;</span></div><div class='line' id='LC2'><span class="nb">require</span> <span class="s1">&#39;benchmark&#39;</span></div><div class='line' id='LC3'><span class="nb">require</span> <span class="s1">&#39;yaml&#39;</span></div><div class='line' id='LC4'><span class="nb">require</span> <span class="s1">&#39;zaml&#39;</span></div><div class='line' id='LC5'><span class="nb">require</span> <span class="s1">&#39;json&#39;</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'><span class="n">yaml_str</span> <span class="o">=</span> <span class="o">&lt;&lt;-</span><span class="no">eos</span></div><div class='line' id='LC8'><span class="sh">yaml goes here</span></div><div class='line' id='LC9'><span class="no">eos</span></div><div class='line' id='LC10'><br/></div><div class='line' id='LC11'><span class="n">h</span> <span class="o">=</span> <span class="kp">nil</span></div><div class='line' id='LC12'><span class="no">GC</span><span class="o">.</span><span class="n">start</span></div><div class='line' id='LC13'><span class="n">yaml_load_time</span> <span class="o">=</span> <span class="no">Benchmark</span><span class="o">::</span><span class="n">realtime</span> <span class="p">{</span></div><div class='line' id='LC14'><span class="mi">1000</span><span class="o">.</span><span class="n">times</span> <span class="p">{</span> <span class="n">h</span> <span class="o">=</span> <span class="no">YAML</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">yaml_str</span><span class="p">)</span> <span class="p">}</span></div><div class='line' id='LC15'><span class="p">}</span></div><div class='line' id='LC16'><br/></div><div class='line' id='LC17'><span class="no">GC</span><span class="o">.</span><span class="n">start</span></div><div class='line' id='LC18'><span class="n">to_yaml_time</span> <span class="o">=</span> <span class="no">Benchmark</span><span class="o">::</span><span class="n">realtime</span> <span class="p">{</span></div><div class='line' id='LC19'><span class="mi">1000</span><span class="o">.</span><span class="n">times</span> <span class="p">{</span> <span class="n">h</span><span class="o">.</span><span class="n">to_yaml</span> <span class="p">}</span></div><div class='line' id='LC20'><span class="p">}</span></div><div class='line' id='LC21'><br/></div><div class='line' id='LC22'><span class="k">begin</span></div><div class='line' id='LC23'>&nbsp;&nbsp;<span class="no">YAML</span><span class="o">::</span><span class="no">ENGINE</span><span class="o">.</span><span class="n">yamler</span> <span class="o">=</span> <span class="s1">&#39;psych&#39;</span> <span class="k">if</span> <span class="no">RUBY_VERSION</span> <span class="o">==</span> <span class="s2">&quot;1.9.2&quot;</span></div><div class='line' id='LC24'><span class="k">rescue</span></div><div class='line' id='LC25'>&nbsp;&nbsp;<span class="nb">puts</span> <span class="s2">&quot;Cannot load Psych. Is libyaml installed? Install it and recompile Ruby.&quot;</span></div><div class='line' id='LC26'>&nbsp;&nbsp;<span class="nb">puts</span> <span class="s2">&quot;On OS X with RVM, install it with MacPorts and run:&quot;</span></div><div class='line' id='LC27'>&nbsp;&nbsp;<span class="nb">puts</span> <span class="s2">&quot;rvm install ruby-1.9.2 -C --with-libyaml-dir=/opt/local&quot;</span></div><div class='line' id='LC28'>&nbsp;&nbsp;<span class="nb">exit</span> <span class="mi">1</span></div><div class='line' id='LC29'><span class="k">end</span></div><div class='line' id='LC30'><br/></div><div class='line' id='LC31'><span class="no">GC</span><span class="o">.</span><span class="n">start</span></div><div class='line' id='LC32'><span class="n">psych_load_time</span> <span class="o">=</span> <span class="no">Benchmark</span><span class="o">::</span><span class="n">realtime</span> <span class="p">{</span></div><div class='line' id='LC33'>&nbsp;&nbsp;<span class="mi">1000</span><span class="o">.</span><span class="n">times</span> <span class="p">{</span> <span class="no">YAML</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">yaml_str</span><span class="p">)</span> <span class="p">}</span></div><div class='line' id='LC34'><span class="p">}</span></div><div class='line' id='LC35'><br/></div><div class='line' id='LC36'><span class="no">GC</span><span class="o">.</span><span class="n">start</span></div><div class='line' id='LC37'><span class="n">to_yaml_psych_time</span>  <span class="o">=</span> <span class="no">Benchmark</span><span class="o">::</span><span class="n">realtime</span> <span class="p">{</span></div><div class='line' id='LC38'>&nbsp;&nbsp;<span class="mi">1000</span><span class="o">.</span><span class="n">times</span> <span class="p">{</span> <span class="n">h</span><span class="o">.</span><span class="n">to_yaml</span> <span class="p">}</span></div><div class='line' id='LC39'><span class="p">}</span></div><div class='line' id='LC40'><br/></div><div class='line' id='LC41'><span class="no">GC</span><span class="o">.</span><span class="n">start</span></div><div class='line' id='LC42'><span class="n">to_json_time</span> <span class="o">=</span> <span class="no">Benchmark</span><span class="o">::</span><span class="n">realtime</span> <span class="p">{</span></div><div class='line' id='LC43'><span class="mi">1000</span><span class="o">.</span><span class="n">times</span> <span class="p">{</span> <span class="n">h</span><span class="o">.</span><span class="n">to_json</span> <span class="p">}</span></div><div class='line' id='LC44'><span class="p">}</span></div><div class='line' id='LC45'><br/></div><div class='line' id='LC46'><span class="no">GC</span><span class="o">.</span><span class="n">start</span></div><div class='line' id='LC47'><span class="n">zaml_dump_time</span> <span class="o">=</span> <span class="no">Benchmark</span><span class="o">::</span><span class="n">realtime</span> <span class="p">{</span></div><div class='line' id='LC48'><span class="mi">1000</span><span class="o">.</span><span class="n">times</span> <span class="p">{</span> <span class="no">ZAML</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">h</span><span class="p">)</span> <span class="p">}</span></div><div class='line' id='LC49'><span class="p">}</span></div><div class='line' id='LC50'><br/></div><div class='line' id='LC51'><span class="n">marshaled</span> <span class="o">=</span> <span class="kp">nil</span></div><div class='line' id='LC52'><span class="no">GC</span><span class="o">.</span><span class="n">start</span></div><div class='line' id='LC53'><span class="n">marshal_dump_time</span> <span class="o">=</span> <span class="no">Benchmark</span><span class="o">::</span><span class="n">realtime</span> <span class="p">{</span></div><div class='line' id='LC54'><span class="mi">1000</span><span class="o">.</span><span class="n">times</span> <span class="p">{</span> <span class="n">marshaled</span> <span class="o">=</span> <span class="no">Marshal</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">h</span><span class="p">)</span> <span class="p">}</span></div><div class='line' id='LC55'><span class="p">}</span></div><div class='line' id='LC56'><br/></div><div class='line' id='LC57'><span class="no">GC</span><span class="o">.</span><span class="n">start</span></div><div class='line' id='LC58'><span class="n">marshall_load_time</span> <span class="o">=</span> <span class="no">Benchmark</span><span class="o">::</span><span class="n">realtime</span> <span class="p">{</span></div><div class='line' id='LC59'><span class="mi">1000</span><span class="o">.</span><span class="n">times</span> <span class="p">{</span> <span class="n">h</span> <span class="o">=</span> <span class="no">Marshal</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">marshaled</span><span class="p">)</span> <span class="p">}</span></div><div class='line' id='LC60'><span class="p">}</span></div><div class='line' id='LC61'><br/></div><div class='line' id='LC62'><span class="nb">puts</span> <span class="sb">`ruby -v`</span></div><div class='line' id='LC63'><span class="nb">puts</span> <span class="s2">&quot;--------------------------------------------------------------------&quot;</span></div><div class='line' id='LC64'><span class="nb">puts</span> <span class="s2">&quot;YAML.load:</span><span class="se">\t\t</span><span class="si">#{</span><span class="s1">&#39;%.4f&#39;</span> <span class="o">%</span> <span class="n">yaml_load_time</span><span class="si">}</span><span class="s2">&quot;</span></div><div class='line' id='LC65'><span class="nb">puts</span> <span class="s2">&quot;YAML.load (Psych):</span><span class="se">\t</span><span class="si">#{</span><span class="s1">&#39;%.4f&#39;</span> <span class="o">%</span> <span class="n">psych_load_time</span><span class="si">}</span><span class="s2">&quot;</span> <span class="k">if</span> <span class="no">RUBY_VERSION</span> <span class="o">==</span> <span class="s2">&quot;1.9.2&quot;</span></div><div class='line' id='LC66'><span class="nb">puts</span> <span class="s2">&quot;Marshal.load:</span><span class="se">\t\t</span><span class="si">#{</span><span class="s1">&#39;%.4f&#39;</span> <span class="o">%</span> <span class="n">marshall_load_time</span><span class="si">}</span><span class="s2">&quot;</span></div><div class='line' id='LC67'><span class="nb">puts</span> <span class="s2">&quot;to_yaml:</span><span class="se">\t\t</span><span class="si">#{</span><span class="s1">&#39;%.4f&#39;</span> <span class="o">%</span> <span class="n">to_yaml_time</span><span class="si">}</span><span class="s2">&quot;</span></div><div class='line' id='LC68'><span class="nb">puts</span> <span class="s2">&quot;to_load (Psych):</span><span class="se">\t</span><span class="si">#{</span><span class="s1">&#39;%.4f&#39;</span> <span class="o">%</span> <span class="n">to_yaml_psych_time</span><span class="si">}</span><span class="s2">&quot;</span> <span class="k">if</span> <span class="no">RUBY_VERSION</span> <span class="o">==</span> <span class="s2">&quot;1.9.2&quot;</span></div><div class='line' id='LC69'><span class="nb">puts</span> <span class="s2">&quot;ZAML.dump:</span><span class="se">\t\t</span><span class="si">#{</span><span class="s1">&#39;%.4f&#39;</span> <span class="o">%</span> <span class="n">zaml_dump_time</span><span class="si">}</span><span class="s2">&quot;</span></div><div class='line' id='LC70'><span class="nb">puts</span> <span class="s2">&quot;to_json:</span><span class="se">\t\t</span><span class="si">#{</span><span class="s1">&#39;%.4f&#39;</span> <span class="o">%</span> <span class="n">to_json_time</span><span class="si">}</span><span class="s2">&quot;</span></div><div class='line' id='LC71'><span class="nb">puts</span> <span class="s2">&quot;Marshal.dump:</span><span class="se">\t\t</span><span class="si">#{</span><span class="s1">&#39;%.4f&#39;</span> <span class="o">%</span> <span class="n">marshal_dump_time</span><span class="si">}</span><span class="s2">&quot;</span></div><div class='line' id='LC72'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/707372/400b94c19fdde194dd3a52e666a981be1a566dd1/yaml_benchmark.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/707372#file_yaml_benchmark.rb" style="float:right;margin-right:10px;color:#666">yaml_benchmark.rb</a>
            <a href="https://gist.github.com/707372">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://blog.carlmercier.com/2010/11/19/yaml-zaml-marshal-json-benchmark-in-ruby/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Changes at IsItJRuby.com</title>
		<link>http://blog.carlmercier.com/2009/12/14/changes-at-isitjruby-com/</link>
		<comments>http://blog.carlmercier.com/2009/12/14/changes-at-isitjruby-com/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 04:56:45 +0000</pubDate>
		<dc:creator>Carl Mercier</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Sites I like]]></category>
		<category><![CDATA[Software development]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[jruby]]></category>

		<guid isPermaLink="false">http://blog.carlmercier.com/?p=276</guid>
		<description><![CDATA[I&#8217;ve been ridiculously busy lately. Way too busy. Too busy to sleep, to hit the gym, and definitely maintain yet another website. Unfortunately, IsItJRuby.com didn&#8217;t get the love it deserved so I started hunting for someone to take my place. Alex Coles (@myabc) volunteered and is now the new maintainer. He already shared with me [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been ridiculously busy lately. Way too busy. Too busy to sleep, to hit the gym, and definitely maintain yet another website. Unfortunately, <a href="http://IsItJRuby.com" target="_blank">IsItJRuby.com</a> didn&#8217;t get the love it deserved so I started hunting for someone to take my place.</p>
<p>Alex Coles (<a href="http://twitter.com/myabc" target="_blank">@myabc</a>) volunteered and is now the new maintainer. He already shared with me a couple good ideas for the site, which he&#8217;ll hopefully implement soon.</p>
<p>Thank you, Alex, and congrats!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carlmercier.com/2009/12/14/changes-at-isitjruby-com/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Running Merb on JRuby 1.2 and Glassfish 2.1</title>
		<link>http://blog.carlmercier.com/2009/03/30/running-merb-on-jruby-12-and-glassfish-21/</link>
		<comments>http://blog.carlmercier.com/2009/03/30/running-merb-on-jruby-12-and-glassfish-21/#comments</comments>
		<pubDate>Mon, 30 Mar 2009 19:50:31 +0000</pubDate>
		<dc:creator>Carl Mercier</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[glassfish]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jruby]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rubyonrails]]></category>

		<guid isPermaLink="false">http://blog.carlmercier.com/?p=219</guid>
		<description><![CDATA[So I&#8217;ve been trying to get Merb running on JRuby a good part of last night. I don&#8217;t know jack about Java, so this has been a little bit more challenging than it should have been. Most (if not all) of the tutorials I found were old and obsolete, so I decided to throw out [...]]]></description>
			<content:encoded><![CDATA[<p>So I&#8217;ve been trying to get Merb running on JRuby a good part of last night. I don&#8217;t know jack about Java, so this has been a little bit more challenging than it should have been.  Most (if not all) of the tutorials I found were old and obsolete, so I decided to throw out my very own.</p>
<p>I need to give credit to <a href="http://blog.nodeta.fi/2008/05/22/living-on-the-edge-jruby-merb-glassfish/" target="_blank">this page</a>, without which I&#8217;d still be fighting with this whole thing.</p>
<p>This tutorial uses JRuby 1.2, Glassfish 2.1, Merb 1.0.10 and Ubuntu 8.04 LTS. To make my life easy, I simply fired an EC2 instance based on ami-71fd1a18. I recommend you do the same.  However, it should work from just any vanilla Ubuntu 8.04.</p>
<p>Some important comments are in the script below, make sure to read them. Enjoy!</p>
<div class="code">
<!--start_raw--><br />
<textarea rows=30 cols=80><br />
# Setup the scene<br />
apt-get update<br />
apt-get upgrade<br />
# this is the Corporate World, folks, you&#8217;ll need to accept some license agreement in the next step<br />
apt-get install -y vim-full build-essential git-core sun-java6-jdk ant<br />
apt-get install -y mysql-server mysql-client</p>
<p># Install JRuby<br />
cd /tmp<br />
wget http://dist.codehaus.org/jruby/1.2.0/jruby-bin-1.2.0.tar.gz<br />
tar xzvf jruby-bin*<br />
mv jruby-1.2.0 /opt/jruby<br />
echo &#8220;export PATH=&#8221;/opt/jruby/bin:$PATH&#8221;" >> ~/.bashrc<br />
export PATH=&#8221;/opt/jruby/bin:$PATH&#8221;</p>
<p># By now, &#8216;jirb&#8217; should start IRB on JRuby!</p>
<p># Let&#8217;s now install some gems<br />
jruby -S gem install erubis rake json_pure rspec rack mime-types rubigen &#8211;no-rdoc &#8211;no-ri<br />
jruby -S gem install hpricot &#8211;no-rdoc &#8211;no-ri &#8211;version &#8216;~>0.6.1&#8242; # version 7 doesn&#8217;t work with JRuby as of now<br />
jruby -S gem install merb-core merb-more &#8211;no-rdoc &#8211;no-ri</p>
<p># Test to see if Merb is installed:<br />
jruby -S merb help</p>
<p># Create an Hello World app<br />
cd ~<br />
jruby -S merb-gen core hello_world<br />
cd hello_world<br />
jruby -S merb-gen controller hello<br />
echo &#8220;<br />
<h1>This is a Merb app running on JRuby. w00t!</h1>
<p>&#8221; > app/views/hello/index.html.erb<br />
# Freeze Merb into your app<br />
jruby -S gem install merb-core merb-more &#8211;no-rdoc &#8211;no-ri -i gems</p>
<p># Install Glassfish<br />
cd /tmp<br />
wget http://java.net/download/javaee5/v2.1_branch/promoted/Linux/glassfish-installer-v2.1-b60e-linux.jar<br />
# and yet more licensing!<br />
java -Xmx256m -jar glassfish-installer-v2.1-b60e-linux.jar<br />
mv glassfish /opt/<br />
cd /opt/glassfish<br />
ant -f setup.xml</p>
<p># Start Glassfish server, it might take some time.<br />
./bin/asadmin start-domain domain1</p>
<p># Warbler and friends<br />
jruby -S gem install rails warbler activerecord-jdbc-adapter &#8211;no-rdoc &#8211;no-ri<br />
cd ~/hello_world<br />
jruby -S warble config</p>
<p># Make sure frozen gems are included in your .war file.<br />
# edit config/warble.rb and add &#8220;gems&#8221; to the config.dirs line</p>
<p># create some missing directories, otherwise, warble will complain.<br />
mkdir -p lib log vendor<br />
# create a .war file<br />
jruby -S warble war<br />
# copy it to Glassfish.<br />
cp hello_world.war /opt/glassfish/domains/domain1/autodeploy/</p>
<p># Glassfish finds your app and starts it automatically.  Give it a few seconds.<br />
# Then, go to http://{server-ip}:4848<br />
# User: admin    Pass: adminadmin        Sounds like a good idea to change this for production!!!!!<br />
# Click &#8220;Web Applications&#8221;, then &#8220;hello_world&#8221;.  Change &#8220;Context Root&#8221; to &#8220;/&#8221; and Save.  Saving was slow for me.</p>
<p>#<br />
# That&#8217;s it!!!<br />
#<br />
# Now go see your l33t web 2.0 app in action:<br />
# Go to http://{server-ip}:8080/<br />
# and http://{server-ip}:8080/hello<br />
</textarea><br />
<!--end_raw-->
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.carlmercier.com/2009/03/30/running-merb-on-jruby-12-and-glassfish-21/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Announcing install_gems.rb</title>
		<link>http://blog.carlmercier.com/2008/10/13/announcing-install_gemsrb/</link>
		<comments>http://blog.carlmercier.com/2008/10/13/announcing-install_gemsrb/#comments</comments>
		<pubDate>Mon, 13 Oct 2008 15:50:53 +0000</pubDate>
		<dc:creator>Carl Mercier</dc:creator>
				<category><![CDATA[Defensio]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software development]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[install_gems]]></category>
		<category><![CDATA[install_gems.rb]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rubygems]]></category>
		<category><![CDATA[rubyonrails]]></category>

		<guid isPermaLink="false">http://blog.carlmercier.com/?p=154</guid>
		<description><![CDATA[Over the weekend, I was rethinking the way we should deploy our Merb application (our API) for Defensio. Everything I&#8217;ll say here applies to Rails as well. Managing gems has been painful lately. Like most people, we&#8217;re freezing them, which helps tremendously. However, there&#8217;s a few problems with this approach: We can&#8217;t freeze C extensions [...]]]></description>
			<content:encoded><![CDATA[<p>Over the weekend, I was rethinking the way we should deploy our Merb application (our API) for <a href="http://defensio.com" target="_blank">Defensio</a>.  Everything I&#8217;ll say here applies to Rails as well.</p>
<p>Managing gems has been painful lately.  Like most people, we&#8217;re freezing them, which helps tremendously.  However, there&#8217;s a few problems with this approach:</p>
<ul>
<li>We can&#8217;t freeze C extensions because they need to be compiled for the target platform.  We develop on OS X and Linux 64, but deploy to Linux i386.  As a workaround, we currently freeze but recompile them on every deployment.  Definitely not optimal.</li>
<li>Our frozen gems directory is getting huge.</li>
<li>It&#8217;s becoming complicated and quite a mess to manage multiple gem versions for different branches/tags.</li>
<li>We never quite know which branch needs which gem.</li>
</ul>
<p>Of course, we could manually install the gems we need on our servers.  But the word &#8220;manually&#8221; generally leads to &#8220;epic fail&#8221;.</p>
<p>So I thought, why not install them at deployment time, just before restarting the Mongrels, with Capistrano?  That seemed like a pretty good idea!  The only problem is that Rubygems will always install a gem when asked to do so, even if it&#8217;s already installed.</p>
<p>That&#8217;s where <a href="http://github.com/karabunga/install_gems/tree/master" target="_blank">install_gems.rb</a> comes in.  install_gems.rb takes a file name as an argument.  This file contains a simple list of gems along with their version number.  A custom installation command can also be specified.</p>
<p>Here&#8217;s an example:<br />
<code><br />
# This is an example file.  As you can see, it supports comments.<br />
haml 2.0.3<br />
eventmachine 0.12.2<br />
# Notice the custom command specified after the --<br />
termios 0.9.4 -- gem install termios -v 0.9.4 --no-rdoc --no-ri</p></blockquote>
<p></code></p>
<p>To install the above gems, you&#8217;d simply run<br />
<code>./install_gems.rb input_file</code></p>
<p>install_gems.rb has a few advantages over vanilla rubygems:</p>
<ul>
<li>It will only install a gem if the specified version is not already installed. That&#8217;s obviously much faster than reinstalling everything every time.</li>
<li>C extensions will be properly compiled.</li>
<li>Using different gem versions in different branches/tags/releases is now very easy.  You just have to maintain a list of required gems in your Git repository and make sure Capistrano runs install_gems.rb against this list before restarting the application servers.</li>
<li>It forces us to keep an up-to-date list of the gems we need.</li>
</ul>
<p>Of course, for this to work as expected, you&#8217;ll need to require specific gem versions in your application.  Your production server will likely have multiple versions of the same gems installed and if you don&#8217;t specify which version of the gem you want to require, things might (or will) break.</p>
<p>I released <a href="http://github.com/karabunga/install_gems/tree/master" target="_blank">install_gems.rb on GitHub</a> and <a href="http://danielharan.com" target="_blank">Daniel Haran</a> has already submitted a patch.  Feel free to do so as well, I&#8217;m a puller!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carlmercier.com/2008/10/13/announcing-install_gemsrb/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>When Ruby goes wrong</title>
		<link>http://blog.carlmercier.com/2008/05/21/when-ruby-goes-wrong/</link>
		<comments>http://blog.carlmercier.com/2008/05/21/when-ruby-goes-wrong/#comments</comments>
		<pubDate>Wed, 21 May 2008 15:19:13 +0000</pubDate>
		<dc:creator>Carl Mercier</dc:creator>
				<category><![CDATA[Cool/funny/stupid stuff]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.carlmercier.com/?p=123</guid>
		<description><![CDATA[Running the tests, 1 failure. Doesn&#8217;t look like a failure to me Investigating&#8230; 1) Failure: test_new_articles(AnnounceArticleFunctionalTest) [test/functional/announce_article_test.rb:74:in `test_new_articles' /usr/lib/ruby/gems/1.8/gems/mocha-0.5.6/lib/mocha/test_case_adapter.rb:19:in `__send__' /usr/lib/ruby/gems/1.8/gems/mocha-0.5.6/lib/mocha/test_case_adapter.rb:19:in `run']: &#60;Wed, 21 May 2008 15:12:50 +0000&#62; expected but was &#60;Wed, 21 May 2008 15:12:50 +0000&#62;.]]></description>
			<content:encoded><![CDATA[<p>Running the tests, 1 failure.  Doesn&#8217;t look like a failure to me <img src='http://blog.carlmercier.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Investigating&#8230;</p>
<p><code><br />
  1) Failure:<br />
test_new_articles(AnnounceArticleFunctionalTest)<br />
    [test/functional/announce_article_test.rb:74:in `test_new_articles'<br />
     /usr/lib/ruby/gems/1.8/gems/mocha-0.5.6/lib/mocha/test_case_adapter.rb:19:in `__send__'<br />
     /usr/lib/ruby/gems/1.8/gems/mocha-0.5.6/lib/mocha/test_case_adapter.rb:19:in `run']:<br />
&lt;Wed, 21 May 2008 15:12:50 +0000&gt; expected but was<br />
&lt;Wed, 21 May 2008 15:12:50 +0000&gt;.<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carlmercier.com/2008/05/21/when-ruby-goes-wrong/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to fix that Rubygems mess on Leopard</title>
		<link>http://blog.carlmercier.com/2007/12/14/how-to-fix-that-rubygems-mess-on-leopard/</link>
		<comments>http://blog.carlmercier.com/2007/12/14/how-to-fix-that-rubygems-mess-on-leopard/#comments</comments>
		<pubDate>Fri, 14 Dec 2007 19:03:19 +0000</pubDate>
		<dc:creator>Carl Mercier</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software development]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[leopard]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[macports]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[port]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rubygems]]></category>
		<category><![CDATA[rubyonrails]]></category>

		<guid isPermaLink="false">http://blog.carlmercier.com/2007/12/14/how-to-fix-that-rubygems-mess-on-leopard/</guid>
		<description><![CDATA[I love Leopard and I love my Mac. I think Apple made the right decision by bundling Ruby and Rails with Leopard. However, I believe they screwed up big time in the execution. Leopard&#8217;s Rails installation worked great until I updated Rubygems with sudo gem update &#8211;system. After I did that, most of my gems [...]]]></description>
			<content:encoded><![CDATA[<p>I love <a href="http://www.apple.com/macosx/" target="_blank">Leopard</a> and I love <a href="http://www.apple.com/macbookpro/" target="_blank">my Mac</a>.  I think Apple made the right decision by bundling <a href="http://ruby-lang.org" target="_blank">Ruby</a> and <a href="http://rubyonrails.org" target="_blank">Rails</a> with Leopard.  However, I believe they screwed up big time in the execution.</p>
<p>Leopard&#8217;s Rails installation worked great until I updated <a href="http://rubygems.org/" target="_blank">Rubygems</a> with <em>sudo gem update &#8211;system</em>. After I did that, most of my gems were broken, and reinstalling them didn&#8217;t help.   According to Google, <a href="http://discussions.apple.com/thread.jspa?threadID=1202925&amp;tstart=0" target="_blank">I was</a> <a href="http://www.luisdelarosa.com/2007/11/19/reinstalling-rubygems-on-leopard/" target="_blank">not alone</a>.</p>
<p>The right thing to do for Apple would have been to ship Leopard with <a href="http://www.macports.org/" target="_blank">MacPorts</a> and have Ruby and Rubygems installed through it.  Unfortunately, they had to reinvent the wheel&#8230;</p>
<p>This tutorial will guide you through fixing that mess.  We will be reinstalling Ruby and Rails with MacPorts and deleting the original Ruby installation to avoid conflicts.</p>
<p>You might want to backup your system before proceeding as I cannot be held responsible if something goes wrong (my lawyer made me write that).  I tried it on 2 different machines and it worked fine for me.</p>
<p>So let&#8217;s get started already!</p>
<p><strong>Step 1: Install MacPorts </strong></p>
<p>Start by installing <a href="http://www.macports.org/" target="_blank">MacPorts</a> if you don&#8217;t already have it on your machine.  It&#8217;s an awesome must-have piece of software anyways!  It&#8217;s super easy to install with the Leopard package.</p>
<p><strong>Step 2: Install XCode 3.0</strong></p>
<p>You must also have <a href="http://developer.apple.com/tools/download/" target="_blank">XCode 3.0</a> installed. It&#8217;s a huge download so you might want to install it from your Leopard DVD.  It&#8217;s in <em>/Optional Installs/Xcode Tools/XcodeTools.mpkg  </em></p>
<p>Installation will take some time, so go read <a href="http://digg.com" target="_blank">Digg</a>, <a href="http://reddit.com" target="_blank">Reddit</a>, or install <a href="http://defensio.com" target="_blank">Defensio</a> on your blog!</p>
<p><strong>Step 3: List your gems</strong></p>
<p>Get a list of your installed gems and save it to a text file somewhere.  You will need to reinstall them! [source:php]gem list &gt; ~/Desktop/installed_gems.txt[/source]</p>
<p><strong>Step 4: Clean up your Mac</strong></p>
<p>In order to avoid conflicts with your original Ruby installation, I recommend you simply delete it. To do so, run these commands (I know&#8230; scary stuff!):[source:php]sudo rm -r /System/Library/Frameworks/Ruby.framework/<br />
sudo rm -r /Library/Ruby<br />
sudo rm /usr/bin/ruby<br />
sudo rm /usr/bin/gem<br />
[/source]</p>
<p><strong>Step 5: Install Ruby and Rubygems with MacPorts</strong></p>
<p>If you don&#8217;t perform step 4, <strong>you will run into problems </strong>at step 6.</p>
<p>Now go ahead and install Rubygems through MacPorts.  It will automatically install Ruby (and many other things) as it&#8217;s a dependency.  The command is: [source:php]sudo port install rb-rubygems[/source]</p>
<p>This one will also take a while&#8230; When it&#8217;s done, update Rubygems: [source:php]sudo gem update &#8211;system[/source]</p>
<p><strong>Step 6: Install Rails</strong></p>
<p>At this point, you should have a brand new Ruby and Rubygems installation working!   That wasn&#8217;t too hard was it?</p>
<p>Now let&#8217;s install Rails.</p>
<ul>
<li>For Rails 1.2.6, run [source:php]sudo gem install rails -v 1.2.6[/source]</li>
<li>For Rails 2 (aka latest-and-greatest), run [source:php]sudo gem install rails[/source]</li>
</ul>
<p>Note that recent versions of Rubygems no longer requires the &#8211;include-dependencies parameter.</p>
<p><strong>Step 7: Reinstall your gems </strong></p>
<p>Now&#8217;s the time to reinstall your original gems.</p>
<p>To reinstall the gems that shipped with Leopard, execute this command: [source:php]sudo gem install RedCloth acts_as_ferret mongrel fcgi capistrano ruby-openid ferret dnssd hpricot sqlite3-ruby libxml-ruby termios[/source]</p>
<p>Then, you might want to reinstall the other gems you had.  The list is on your desktop in <em>installed_gems.txt</em>.</p>
<p>That&#8217;s it!  You now have a more standard and less prone to problems Rails stack on your Mac!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carlmercier.com/2007/12/14/how-to-fix-that-rubygems-mess-on-leopard/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
		<item>
		<title>A better approach to restarting a Mongrel cluster</title>
		<link>http://blog.carlmercier.com/2007/09/07/a-better-approach-to-restarting-a-mongrel-cluster/</link>
		<comments>http://blog.carlmercier.com/2007/09/07/a-better-approach-to-restarting-a-mongrel-cluster/#comments</comments>
		<pubDate>Fri, 07 Sep 2007 16:21:20 +0000</pubDate>
		<dc:creator>Carl Mercier</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.carlmercier.com/2007/09/07/a-better-approach-to-restarting-a-mongrel-cluster/</guid>
		<description><![CDATA[At Karabunga, we use Mongrel, a lot. As our Rails applications become larger, the startup time of a Mongrel process becomes significant. As you know, restarting your a Mongrel cluster is a matter of issuing this command: /etc/init.d/mongrel_cluster restart. Here&#8217;s what happens for a cluster of 4 Mongrels: For one of our application, the &#8220;stop&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p>At <a href="http://karabunga.com" target="_blank">Karabunga</a>, we use Mongrel, a lot. As our Rails applications become larger, the startup time of a Mongrel process becomes significant.</p>
<p>As you know, restarting your a Mongrel cluster is a matter of issuing this command: <em>/etc/init.d/mongrel_cluster restart</em>.  Here&#8217;s what happens for a cluster of 4 Mongrels:</p>
<p style="text-align: center"><img src="http://blog.carlmercier.com/wp-content/uploads/2007/09/mongrel_cluster_before.png" alt="A typical Mongrel Cluster restart" /></p>
<p>For one of our application, the &#8220;stop&#8221; time is about 2 seconds and the &#8220;start&#8221; time is somewhere around 10 seconds for each Mongrel process.  Which means that for a cluster of 15, we have a window of about 3 minutes where at least 1 and often many Mongrels are innaccessible.  Worse, there&#8217;s even a point where there is no Mongrel running at all.  In a high traffic production environment, this is not acceptable.</p>
<p>With some hacking, I managed to modify mongrel_cluster_ctl (the script called by <em>/etc/init.d/mongrel_cluster</em>) to avoid the above scenario.  My hack also makes sure that at most 1 Mongrel will be down at any given time.  Here&#8217;s a graphical representation of my hack:</p>
<p style="text-align: center"><img src="http://blog.carlmercier.com/wp-content/uploads/2007/09/mongrel_cluster_after.png" alt="A Mongrel Cluster restart with my hack" /></p>
<p>I believe this is much more efficient.  Moreover, when implemented with Swiftiply, downtime is reduced to zero since Swiftiply will detect a &#8220;dead&#8221; Mongrel and route requests to one that is alive.</p>
<p>Links:</p>
<ul>
<li><a href="http://blog.carlmercier.com/wp-content/uploads/mongrel_cluster_ctl.zip"> Download my hacked mongrel_cluster_ctl file</a></li>
<li><a href="http://www.webficient.com/2007/08/how-to-configure-swiftiply-with-nginx.html" target="_blank">How to configure Swiftiply with Nginx</a></li>
<li><a href="http://synaphy.com.au/2007/8/20/seesaw" target="_blank"> Seesaw, an alternative approach to zero-downtime Mongrel restarts</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.carlmercier.com/2007/09/07/a-better-approach-to-restarting-a-mongrel-cluster/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Montreal on Rails 2, tonight!</title>
		<link>http://blog.carlmercier.com/2007/09/04/montreal-on-rails-2-tonight/</link>
		<comments>http://blog.carlmercier.com/2007/09/04/montreal-on-rails-2-tonight/#comments</comments>
		<pubDate>Tue, 04 Sep 2007 18:59:38 +0000</pubDate>
		<dc:creator>Carl Mercier</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.carlmercier.com/2007/09/04/montreal-on-rails-2-tonight/</guid>
		<description><![CDATA[In case you forgot, Montreal on Rails #2 is tonight! Hope to see you there.]]></description>
			<content:encoded><![CDATA[<p>In case you forgot, <a href="http://montrealonrails.com" target="_blank">Montreal on Rails #2</a> is tonight!  Hope to see you there.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carlmercier.com/2007/09/04/montreal-on-rails-2-tonight/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hello, I&#8217;m Ruby on Rails!</title>
		<link>http://blog.carlmercier.com/2007/05/15/hello-im-ruby-on-rails/</link>
		<comments>http://blog.carlmercier.com/2007/05/15/hello-im-ruby-on-rails/#comments</comments>
		<pubDate>Tue, 15 May 2007 17:33:06 +0000</pubDate>
		<dc:creator>Carl Mercier</dc:creator>
				<category><![CDATA[Cool/funny/stupid stuff]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software development]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.carlmercier.com/?p=75</guid>
		<description><![CDATA[Here&#8217;s the geekiest thing I&#8217;ve seen this week (and I love it!) A Rails vs. Java ad, Mac/PC style!]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s the geekiest thing I&#8217;ve seen this week (and I love it!)  A Rails vs. Java ad, Mac/PC style!</p>
<div>
<object width="425" height="350"><param name="movie" value="http://www.youtube.com/v/PQbuyKUaKFo"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/PQbuyKUaKFo" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></object>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.carlmercier.com/2007/05/15/hello-im-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>smart_params: unified id params across your controllers</title>
		<link>http://blog.carlmercier.com/2007/03/01/smart_params-unified-id-params-across-your-controllers/</link>
		<comments>http://blog.carlmercier.com/2007/03/01/smart_params-unified-id-params-across-your-controllers/#comments</comments>
		<pubDate>Thu, 01 Mar 2007 20:14:48 +0000</pubDate>
		<dc:creator>Carl Mercier</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software development]]></category>

		<guid isPermaLink="false">http://blog.carlmercier.com/?p=67</guid>
		<description><![CDATA[I am in a situation where I need a single method to perform miscellaneous operations from different controllers. I am using RESTful routes and I ran into the problem where the last ID in the URL has to be accessed by params[:id] instead of params[:controller_id] like the other IDs of the same URL. In a [...]]]></description>
			<content:encoded><![CDATA[<p>I am in a situation where I need a single method to perform miscellaneous operations from different controllers.  I am using RESTful routes and I ran into the problem where the last ID in the URL has to be accessed by params[:id] instead of params[:controller_id] like the other IDs of the same URL.</p>
<p>In a nutshell, I had:</p>
<p><em>URL: /families/1/people/5</em><br />
[source:ruby]<br />
family_id = params[:family_id]<br />
person_id = params[:id]<br />
[/source]</p>
<p>However, for the sake of simplicity and to be able to use the method in question from other controllers (ex: /families/1/people/5/friends/7) without any modifications, I wanted to do <em>person_id = params[:person_id] </em>regardless of which<em> </em>controller was being accessed.</p>
<p>This was fairly easy to fix and I rolled out a little helper method I call <em>smart_params</em>:</p>
<p>[source:ruby]<br />
def smart_params<br />
&nbsp;&nbsp;if params.key?(:id)<br />
&nbsp;&nbsp;&nbsp;&nbsp;param_name = params[:controller].singularize + &#8216;_id&#8217;<br />
&nbsp;&nbsp;&nbsp;&nbsp;params[param_name.to_sym] = params[:id]<br />
&nbsp;&nbsp;end<br />
end<br />
[/source]</p>
<p>I put it in /app/controllers/application.rb and added <em>before_filter :smart_params</em> to the class.  Voila!  Unified and consistent params for your IDs!</p>
<p>I don&#8217;t know if you&#8217;ll find this useful for anybody else, but it&#8217;s saving me a lot of time.</p>
<p>EDITS:</p>
<p>March 3, 2007: modified smart_params slightly to avoid creating a new nil param when params[:id] does not exist.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carlmercier.com/2007/03/01/smart_params-unified-id-params-across-your-controllers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

