<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Bruce Williams</title>
 <link href="http://codefluency.com/feed/atom.xml" rel="self"/>
 <link href="http://codefluency.com/"/>
 <updated>2009-03-14T13:28:04-07:00</updated>
 <id>http://codefluency.com/</id>
 <author>
   <name>Bruce Williams</name>
   <email>bruce@codefluency.com</email>
 </author>

 
 <entry>
   <title>Living without send(), or trying to</title>
   <link href="http://codefluency.com/2009/03/13/living-without-send.html"/>
   <updated>2009-03-13T00:00:00-07:00</updated>
   <id>http://codefluency.com/2009/03/13/living-without-send</id>
   <content type="html">&lt;p&gt;&lt;code&gt;Object#send&lt;/code&gt; (or &lt;code&gt;__send__&lt;/code&gt;) is a scrappy little tool we Rubyists pull out to ever-so-casually ignore method &lt;code&gt;private&lt;/code&gt; and &lt;code&gt;protected&lt;/code&gt; visibility, and to call methods dynamically.&lt;/p&gt;

&lt;p&gt;Maybe we&amp;#8217;ve gotten into the habit of using it a little too often. Let&amp;#8217;s play with alternatives.&lt;/p&gt;

&lt;h2 id='an_evaluation'&gt;An evaluation&lt;/h2&gt;

&lt;p&gt;Here&amp;#8217;s an example from practically every monkeypatching Rails plugin &lt;code&gt;init.rb&lt;/code&gt; you&amp;#8217;ve ever seen:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='no'&gt;SomeRailsConstant&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:include&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;MagicSauce&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Okay, so &lt;code&gt;include&lt;/code&gt; is a private method, and we&amp;#8217;re breaking through indiscriminately by using &lt;code&gt;send&lt;/code&gt;. If you wanted to do away with &lt;code&gt;send&lt;/code&gt; because it seems &lt;em&gt;weird&lt;/em&gt;, you might try something like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;SomeRailsConstant&lt;/span&gt;
  &lt;span class='kp'&gt;include&lt;/span&gt; &lt;span class='no'&gt;MagicSauce&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Seems nice and simple; basic Ruby, right? Yes. But if you do this in Rails, you&amp;#8217;ll likely ensure the real &lt;code&gt;SomeRailsConstant&lt;/code&gt;, provided by Rails, never gets loaded &amp;#8211; since Rails autoloading is lazy. What you&amp;#8217;ve done here isn&amp;#8217;t to &lt;em&gt;reopen&lt;/em&gt; the class; you&amp;#8217;ve just &lt;em&gt;defined&lt;/em&gt; it. &lt;em&gt;Bad, bad&lt;/em&gt;. You need to try to &lt;em&gt;use&lt;/em&gt; the constant to kick the autoloading into gear for you. Here&amp;#8217;s another approach that does just that.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='no'&gt;SomeRailsConstant&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;instance_eval&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='kp'&gt;include&lt;/span&gt; &lt;span class='no'&gt;MagicSauce&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What&amp;#8217;s this &lt;code&gt;instance_eval&lt;/code&gt; nonsense &amp;#8211; and why is it named &amp;#8220;instance?&amp;#8221; Isn&amp;#8217;t &lt;code&gt;SomeRailsConstant&lt;/code&gt; a &lt;em&gt;class&lt;/em&gt;? Yes, yes it is. Which also means it&amp;#8217;s an &lt;em&gt;instance&lt;/em&gt; of class &lt;code&gt;Class&lt;/code&gt;. Neat (and confusing), right? You can see this easily in &lt;code&gt;irb&lt;/code&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;MyClass&lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='no'&gt;MyClass&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;class&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='no'&gt;Class&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But, stepping away from the foibles of Ruby object hierarchy for a moment, let&amp;#8217;s address this approach; &lt;code&gt;instance_eval&lt;/code&gt;. This method allows you to temporarily change scope; it lets you get &lt;em&gt;inside&lt;/em&gt; an object and call whatever you&amp;#8217;d like.&lt;/p&gt;

&lt;p&gt;Okay, that&amp;#8217;s fine&amp;#8211; but is &lt;code&gt;instance_eval&lt;/code&gt; really better than &lt;code&gt;send&lt;/code&gt;? No, probably not in the strictest sense. It&amp;#8217;s even &lt;em&gt;more typing&lt;/em&gt;. But to my purist brain, &lt;code&gt;send&lt;/code&gt; is for calling methods dynamically &amp;#8211; and I know exactly what I want. &lt;code&gt;instance_eval&lt;/code&gt; is also more flexible, since I can do multiple operations in the block, access instance variables, etc&amp;#8230; which means I get to use it more consistently. Consistency keeps code readable, even in the presence of insane metaprogramming.&lt;/p&gt;

&lt;p&gt;I like &lt;code&gt;instance_eval&lt;/code&gt;. I also like how it&amp;#8217;s not a normal dictionary word that&amp;#8217;s in common use. Want to call &lt;code&gt;send&lt;/code&gt; on a &lt;code&gt;Message&lt;/code&gt; instance? Get ready to use the lamer &lt;code&gt;__send__&lt;/code&gt; name, since the developer of &lt;code&gt;Message&lt;/code&gt; quite reasonably appropriated the name for actual message &lt;em&gt;sending&lt;/em&gt;. It&amp;#8217;s exactly this kind of inconsistent application that drives me up the wall.&lt;/p&gt;

&lt;p&gt;Okay, and next.&lt;/p&gt;

&lt;h2 id='method_acting'&gt;Method acting&lt;/h2&gt;

&lt;p&gt;So, we&amp;#8217;ve gone down the road of glossary consistency for plain, non-dynamic invocations. Let&amp;#8217;s go further. Here&amp;#8217;s another &lt;code&gt;send&lt;/code&gt;; this one for dynamic reasons.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='lineno'&gt;1&lt;/span&gt; &lt;span class='c1'&gt;# `format` is defined somewhere else. Example: &amp;#39;pdf&amp;#39;&lt;/span&gt;
&lt;span class='lineno'&gt;2&lt;/span&gt; &lt;span class='no'&gt;File&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;open&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;report&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;name&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;.&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='nb'&gt;format&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;w&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;file&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
&lt;span class='lineno'&gt;3&lt;/span&gt;   &lt;span class='n'&gt;file&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;write&lt;/span&gt; &lt;span class='n'&gt;report&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;to_&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='nb'&gt;format&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='lineno'&gt;4&lt;/span&gt; &lt;span class='k'&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What are we really doing here? Let&amp;#8217;s convert how the business part of line #3 reads into plain English:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tell the report to &amp;#8220;to_#{format}&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Does that sound right? Let&amp;#8217;s try to make this sound clearer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Invoke a method called &amp;#8220;to_#{format}&amp;#8221; on the report&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There&amp;#8217;s a simple way to put this into code:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='n'&gt;report&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;method&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;to_&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='nb'&gt;format&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;call&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, here we&amp;#8217;re using the arcane &lt;code&gt;Object#method&lt;/code&gt; method to get a &lt;code&gt;Method&lt;/code&gt; instance. These suckers are &lt;em&gt;flexible&lt;/em&gt;. You can reuse &lt;code&gt;Method&lt;/code&gt; objects, pass them around, unbind and rebind their &lt;code&gt;UnboundMethod&lt;/code&gt; counterparts, check their arity, see where they come from using &lt;code&gt;to_s&lt;/code&gt;, and &lt;em&gt;invoke them&lt;/em&gt;. That&amp;#8217;s what we do with &lt;code&gt;call&lt;/code&gt;. Simple.&lt;/p&gt;

&lt;p&gt;Is this good practice? Maybe not. It&amp;#8217;s certainly slower than &lt;code&gt;send&lt;/code&gt;, invocation-to-invocation (though not greatly). It&amp;#8217;s kind of fun, though, and maybe a bit easier to read &amp;amp; document.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Report&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;formatter&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;name&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='nb'&gt;method&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;to_&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='nb'&gt;name&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='n'&gt;report&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Report&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
&lt;span class='n'&gt;report&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;formatter&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:pdf&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;call&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Do I use this frequently? No. But it&amp;#8217;s a nice tool to have in the kit. Kind of &lt;em&gt;functional&lt;/em&gt;, which always makes me happy.&lt;/p&gt;

&lt;h2 id='summary'&gt;Summary&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;m not telling you to stop using &lt;code&gt;send&lt;/code&gt;. It&amp;#8217;s a great little method that&amp;#8217;s easy to grasp, simple to use, and rarely causes any problems. I&amp;#8217;m just telling you to &lt;em&gt;think&lt;/em&gt; about the rough edges a little. Don&amp;#8217;t say &lt;em&gt;yes&lt;/em&gt; just because you see it everywhere.&lt;/p&gt;

&lt;p&gt;Just use it critically.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>A GitHubby config.gem hack</title>
   <link href="http://codefluency.com/2009/02/07/a-githubby-config-gem-hack.html"/>
   <updated>2009-02-07T00:00:00-08:00</updated>
   <id>http://codefluency.com/2009/02/07/a-githubby-config-gem-hack</id>
   <content type="html">&lt;p&gt;I love using gems from my Rails apps, and have been an outspoken proponent for gem plugins from the beginning (you won&amp;#8217;t find any &lt;code&gt;vendor/plugins&lt;/code&gt; in my newer apps at all).&lt;/p&gt;

&lt;p&gt;I also love &lt;a href='http://github.com/bruce'&gt;GitHub&lt;/a&gt;, but lines like this, over and over in my environment files, just annoy me:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;username-foo&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:lib&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
                           &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gems.github.com&amp;#39;&lt;/span&gt;
&lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;username-bar&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:lib&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
                           &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gems.github.com&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, here&amp;#8217;s a quick little hack. It could be smarter, but it works.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;GitHubbyGems&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;gem&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;name&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;options&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{})&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;options&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:github&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
      &lt;span class='n'&gt;default_options&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='ss'&gt;:lib&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nb'&gt;name&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;split&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;last&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
                         &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gems.github.com&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
      &lt;span class='n'&gt;options&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;default_options&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;merge&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;options&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;super&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;name&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;options&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='no'&gt;Rails&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Initializer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;run&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
  &lt;span class='c1'&gt;# ...&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;extend&lt;/span&gt; &lt;span class='no'&gt;GitHubbyGems&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;haml&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;right_aws&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;thoughtbot-paperclip&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:github&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
  &lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;mojombo-god&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:github&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
  &lt;span class='c1'&gt;# ...&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Enjoy.&lt;/p&gt;

&lt;h3 id='updates'&gt;Updates&lt;/h3&gt;

&lt;p&gt;&lt;a href='http://twitter.com/fractious/statuses/1188695109'&gt;James Bebbington&lt;/a&gt; likes an API that supports something like:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem_source&lt;/span&gt; &lt;span class='ss'&gt;:github&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://gems.github.com&amp;#39;&lt;/span&gt;
&lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:source&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:github&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;â€¦ and I agree that&amp;#8217;s far less of a special-case hack.&lt;/p&gt;

&lt;p&gt;Since what we really want to do is affect the configured &lt;code&gt;Rails::Gem::Dependency&lt;/code&gt; (&lt;code&gt;Configuration#gem&lt;/code&gt; just passes on the options to initialize one), that&amp;#8217;s probably what we would &lt;em&gt;really&lt;/em&gt; want to modify â€” and of course an old &lt;code&gt;with_options&lt;/code&gt;-style approach would work, too.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s keep in mind though, that in reality GitHub is a very special case (specifically, the gem naming scheme is), and since we&amp;#8217;re talking about a handful of lines per configuration, it&amp;#8217;s probably not worth it (write a text editor snippet instead, or just copy-paste).&lt;/p&gt;

&lt;p&gt;But it&amp;#8217;s a fun little hack.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>A sleep hack</title>
   <link href="http://codefluency.com/2009/01/09/a-sleep-hack.html"/>
   <updated>2009-01-09T00:00:00-08:00</updated>
   <id>http://codefluency.com/2009/01/09/a-sleep-hack</id>
   <content type="html">&lt;p&gt;A quick aside. I&amp;#8217;m experimenting with the &lt;a href='http://everything2.com/index.pl?node=Everyman%20Sleep%20Schedule'&gt;Everyman&lt;/a&gt; &lt;a href='http://en.wikipedia.org/wiki/Polyphasic_sleep'&gt;polyphasic sleep&lt;/a&gt; schedule for the next 3+ weeks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; The experiment ended early, but was still very successful. Feel free to contact me if you&amp;#8217;re interested in this sort of thing.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>More on super-and-extend</title>
   <link href="http://codefluency.com/2009/01/07/more-on-super-and-extend.html"/>
   <updated>2009-01-07T00:00:00-08:00</updated>
   <id>http://codefluency.com/2009/01/07/more-on-super-and-extend</id>
   <content type="html">&lt;p&gt;A few days ago I posted an article on &lt;a href='/2009/01/03/wrapping-a-method-in-ruby.html'&gt;method wrapping&lt;/a&gt;, and I thought I&amp;#8217;d touch a bit more on the super-and-extend technique; I&amp;#8217;ve had a few questions on it that warrant some clarification.&lt;/p&gt;

&lt;h3 id='multiple_wrappers'&gt;Multiple Wrappers&lt;/h3&gt;

&lt;p&gt;Yes, the technique works with multiple wrappers on a single class; when the class is extended with additional modules, they stack and super works as expected (wrappers are applied on the &amp;#8220;outside,&amp;#8221; so invocations occur in LIFO order).&lt;/p&gt;

&lt;p&gt;You can see a full example of this as &lt;a href='http://gist.github.com/43027'&gt;a Gist&lt;/a&gt;. Here is a sample irb session showing that the multiple wrappers are applied correctly:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;Widget&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='k'&gt;end&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;ancestors&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='no'&gt;BazWrapper&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;BarWrapper&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;FooWrapper&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;Class&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='no'&gt;Module&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;Object&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;Kernel&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;widget&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Widget&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;widget&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='k'&gt;end&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;ancestors&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='no'&gt;BazWrapper&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;WrappingB&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;BazWrapper&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;WrappingA&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='no'&gt;BarWrapper&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Wrapping&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;FooWrapper&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Wrapping&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
&lt;span class='no'&gt;Widget&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;Object&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;Kernel&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;widget&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;render_on&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kp'&gt;nil&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='no'&gt;BazWrapper&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;WrappingB&lt;/span&gt;
&lt;span class='no'&gt;BazWrapper&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;WrappingA&lt;/span&gt;
&lt;span class='no'&gt;BarWrapper&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Wrapping&lt;/span&gt;
&lt;span class='no'&gt;FooWrapper&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Wrapping&lt;/span&gt;
&lt;span class='no'&gt;Original&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id='wrapped_class_inheritance'&gt;Wrapped Class Inheritance&lt;/h3&gt;

&lt;p&gt;If you wrap a class, you wrap inherited classes as well, regardless of whether the classes were defined before or after the point the wrapping is applied.&lt;/p&gt;

&lt;p&gt;Given the following class definitions and placement of the wrapping, all three&lt;/p&gt;

&lt;p&gt;classes would be wrapped as expected.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Widget&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;WidgetSubclassDefinedBeforeWrapping&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;Widget&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='no'&gt;Widget&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;extend&lt;/span&gt; &lt;span class='no'&gt;YourWrapperModule&lt;/span&gt;

&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;WidgetSubclassDefinedAfterWrapping&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;Widget&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There&amp;#8217;s no special sauce here, just the normal laws of inheritance.&lt;/p&gt;

&lt;h3 id='the_vagaries_of_overriding_'&gt;The Vagaries of Overriding &lt;code&gt;new&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;As &lt;a href='http://pixelwareinc.com/'&gt;Eric Anderson&lt;/a&gt; pointed out in comments, super-and-extend will not work if the new class method is defined on the wrapped classâ€¦ but only if super isn&amp;#8217;t called. It&amp;#8217;s not all dire straights; here are the three scenarios for a wrapped class:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The class&amp;#8217; new method is not defined, and the wrapper works as expected. This is the normal case.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;The class&amp;#8217; new method is defined, and super it used (ostensibly to reach Class#new for an instanceâ€¦ and our wrapper intercepts it first). Since we don&amp;#8217;t care about the order that the wrapper&amp;#8217;s new(just a hook to extend the instance) fires, the wrapper works as expected. This is an unusual case. For an example of the scenario, see &lt;a href='http://gist.github.com/44230'&gt;this gist&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;The class&amp;#8217; new method is defined, and does not call super (likely to block instantiation). In this case, the internal wrapping module must be applied manually to an instance.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Luckily, since you&amp;#8217;re likely blocking instantiation to make use of the singleton pattern, the &lt;span&gt;single&lt;/span&gt; instance may be easily accessed anyhow (conventionally, as &lt;code&gt;ClassName.instance&lt;/code&gt;), and something like this may be enough:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='no'&gt;ClassName&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;instance&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;YourWrapper&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;InternalWrapping&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Keep in mind that defining new is generally considered verboten or at least in poor taste. Ask yourself if you actually need&lt;/p&gt;

&lt;p&gt;to use a strict, enforced singleton pattern by sabotaging new; in my opinion it&amp;#8217;s often an unnecessary formal constraint.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Wrapping a Method in Ruby</title>
   <link href="http://codefluency.com/2009/01/03/wrapping-a-method-in-ruby.html"/>
   <updated>2009-01-03T00:00:00-08:00</updated>
   <id>http://codefluency.com/2009/01/03/wrapping-a-method-in-ruby</id>
   <content type="html">&lt;p&gt;Let&amp;#8217;s say you have a Ruby class with a method you&amp;#8217;d like to wrapâ€”for debugging or performance timingâ€”and, since you don&amp;#8217;t control where the class is instantiated (think overriding a method in Rails&amp;#8217; ActionPack), just creating a subclass and using &lt;code&gt;super&lt;/code&gt; isn&amp;#8217;t going to work.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s take a look at two mixin patterns; one a ubiquitous naming hack and one a bit of esoteric Ruby inheritance trickery.&lt;/p&gt;

&lt;p&gt;First, let&amp;#8217;s set the scene. Let&amp;#8217;s say we have a method, &lt;code&gt;Widget#render_on&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Widget
  # Wrap this one
  def render_on(document, options = {})
    # ...
  end
  # ...
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What we want is for each wrapper we write to call a method, which we&amp;#8217;ll call snapshot, that will output some information about the method invocation. Don&amp;#8217;t worry about the implementation too much here; it just takes a block and times the yield:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def snapshot
  start = Time.now
  result = yield
  # You could store these values somewhere
  # for averaging, track the caller, etc
  puts Time.now - start
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, we&amp;#8217;re going to do this two waysâ€¦&lt;/p&gt;

&lt;h3 id='technique_1_'&gt;Technique #1: &lt;code&gt;alias_method_chain&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;ActiveSupport makes this easy. Though arguably a bit of a messy naming hack, it does the job and is a bit self-documenting, forcing you to name a feature. If you&amp;#8217;re using Rails, this is happening all over the place.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module AliasMethodChainWrapper

  def self.included(base)
    base.send(:include, InstanceMethods)
    base.alias_method_chain :render_on, :wrapping
  end

  module InstanceMethods

    def render_on_with_wrapping(*args, &amp;amp;block)
      snapshot { render_on_without_wrapping(*args, &amp;amp;block) }
    end

  end

end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, let&amp;#8217;s mix this baby in.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Widget
  include AliasMethodChainWrapper
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What happens when we do this?&lt;/p&gt;

&lt;p&gt;In the included hook, &lt;code&gt;AliasMethodChainWrapper::InstanceMethods&lt;/code&gt; is included into Widget (meaning &lt;code&gt;Widget&lt;/code&gt; instances now have access to &lt;code&gt;render_on_with_wrapping&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;alias_method_chain&lt;/code&gt; aliases the original &lt;code&gt;render_on&lt;/code&gt; to &lt;code&gt;render_on_without_wrapping&lt;/code&gt; and aliases the just-added &lt;code&gt;render_on_with_wrapping&lt;/code&gt; to &lt;code&gt;render_on&lt;/code&gt;, overriding the original implementation.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s an illustration of what the object hierarchy looks like, and how the method invocation works in this technique.&lt;/p&gt;

&lt;p&gt;&lt;img src='/assets/wrapping-methods-amc.png' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;This allows you to call the original implementation of a method from your wrapper code, if desired (we do, invoking it inside a block that&amp;#8217;s passed to snapshot for reporting).&lt;/p&gt;

&lt;p&gt;You can see the API documentation for &lt;code&gt;alias_method_chain&lt;/code&gt; &lt;a href='http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Module.html#M000905'&gt;here&lt;/a&gt; for more information. There&amp;#8217;s plenty of examples of this common pattern in Rails plugins and the framework itself.&lt;/p&gt;

&lt;p&gt;On we go to purer Ruby pastures.&lt;/p&gt;

&lt;h3 id='technique_2_super_and_extend'&gt;Technique #2: super and extend&lt;/h3&gt;

&lt;p&gt;So now let&amp;#8217;s talk a bit about a technique that relies on Ruby&amp;#8217;s extend and super capabilities to simplify things a bit and get rid of the need for explicit naming. Here&amp;#8217;s the wrapper in question:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module SuperExtendWrapper

  def new(*args, &amp;amp;block)
    super.extend Wrapping
  end

  module Wrapping

    def render_on(*args, &amp;amp;block)
      snapshot { super }
    end

  end

end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Okay, that&amp;#8217;s a fair bit shorter, isn&amp;#8217;t it? Deceptively simple. Now, let&amp;#8217;s hook it into our Widgetâ€¦&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Widget.extend SuperExtendWrapper&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, we use &lt;code&gt;Object#extend&lt;/code&gt; this time, which, according to ri, &amp;#8220;Adds to &lt;span&gt;the object&lt;/span&gt; the instance methods from each module given as a parameter.&amp;#8221; How this happens is a bit tricky, and involves shoehorning the module into the instance&amp;#8217;s metaclass â€” singleton class, if you prefer â€” ancestry. Let&amp;#8217;s see how this happens with our wrapper.&lt;/p&gt;

&lt;p&gt;Widget is extended with SuperExtendWrapper (which defines the new method). We can see that SuperExtendWrapper is now below Widget in the class metaclass using irb:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; (class &amp;lt;&amp;lt; Widget; self; end).ancestors
=&amp;gt; [SuperExtendWrapper, Class, Module, Object, Kernel]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What this means is we can use super to call the vanilla &lt;code&gt;Class#new&lt;/code&gt;. Handy, since we need it to get an instance! We then immediately extend the instance with another module, &lt;code&gt;SuperExtendWrapper::Wrapping&lt;/code&gt;, our real payload.&lt;/p&gt;

&lt;p&gt;As you might guess, extending the Widget instance with &lt;code&gt;SuperExtendWrapper::Wrapping&lt;/code&gt; gave us a similar hierarchy in the instance&amp;#8217;s metaclass. Let&amp;#8217;s take a peek:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; widget = Widget.new &amp;gt;&amp;gt; (class &amp;lt;&amp;lt; widget; self; end).ancestors
=&amp;gt; [SuperExtendWrapper::Wrapping, Widget, Object, Kernel]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This makes invoking the vanilla &lt;code&gt;Widget#render_on&lt;/code&gt; just as easy as &lt;code&gt;Class#new&lt;/code&gt;; it&amp;#8217;s a mere super away. No naming hacks required. Here&amp;#8217;s an illustration showing how the method invocation works using the super-and-extend technique.&lt;/p&gt;

&lt;p&gt;&lt;img src='/assets/wrapping-methods-se.png' alt='' /&gt;&lt;/p&gt;

&lt;p&gt;Keep in mind we&amp;#8217;ve only covered instance methods here; things get substantially more hairy using the super-and-extend approach to wrap class methods â€” whereas &lt;code&gt;alias_method_chain&lt;/code&gt; tackles the problem fairly handily.&lt;/p&gt;

&lt;h3 id='performance_note'&gt;Performance Note&lt;/h3&gt;

&lt;p&gt;You may have noticed that the &lt;code&gt;alias_method_chain&lt;/code&gt; magic only needs to be executed one time, whereas the super-and-extend trick needs to extend every instance.&lt;/p&gt;

&lt;p&gt;The performance characteristics turn out to be a bit tricky here, consideringâ€”at least in MRIâ€”while extend adds overhead, method invocation via super is a good bit snappier than calling arbitrary methods (ie, &lt;code&gt;alias_method_chain&lt;/code&gt;&amp;#8217;s with and without chaining).&lt;/p&gt;

&lt;p&gt;What this means is that if you&amp;#8217;re keeping an instance around and calling a wrapped method multiple times, it&amp;#8217;s very easy to get better performance from super-and-extend than &lt;code&gt;alias_method_chain&lt;/code&gt;, but if you&amp;#8217;re instantiating a lot of single-use instances, results will be in &lt;code&gt;alias_method_chain&lt;/code&gt;&amp;#8217;s favor. Obviously we&amp;#8217;re talking tiny performance differences stacking up in either case.&lt;/p&gt;

&lt;h3 id='further_reading'&gt;Further Reading&lt;/h3&gt;

&lt;p&gt;The vagaries of extend are a common topic of conversation; you may find the following interesting reading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jay Fields&amp;#8217; &lt;a href='http://blog.jayfields.com/2006/05/ruby-extend-and-include.html'&gt;basic overview of extend and include&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;A thread of ruby-talk &lt;a href='http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/183508'&gt;about reversing extend&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: See my follow-up to this article, &lt;a href='/2009/01/07/more-on-super-and-extend.html'&gt;More on super-and-extend&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Revisiting Python</title>
   <link href="http://codefluency.com/2008/12/26/revisiting-python.html"/>
   <updated>2008-12-26T00:00:00-08:00</updated>
   <id>http://codefluency.com/2008/12/26/revisiting-python</id>
   <content type="html">&lt;p&gt;I used to be an avid Pythonista. I poured over Python books, read huge swathes of Python code (including the source of &lt;a href='http://twistedmatrix.com'&gt;Twisted&lt;/a&gt;, which, as its name might imply, I think of as quite a personal accomplishment), and soaked up as much material as I could find. I had survived the relative chaos of Perl, and was relieved to find a more orderly, seemingly sane language to work with. I &lt;em&gt;dove in&lt;/em&gt;, and I loved it.&lt;/p&gt;

&lt;p&gt;I learned a huge amount during those years; Python was my first OOP language, and cemented what has become my obsession with dynamic, &amp;#8220;lightweight&amp;#8221; languages. I&amp;#8217;ve never studied CS formally (having opted for languages and linguistics instead) so Python&amp;#8217;s more draconian rules and academic bent helped temper my more artistic tendencies and pushed me far enough into the land of algorithms, data structures, and big O notation so not to be seen as a complete dilettante by later CS nerd colleagues.&lt;/p&gt;

&lt;p&gt;One day, I stumbled across a lone copy of Programming Ruby by chance at at bookstore (back when you &lt;em&gt;just didn&amp;#8217;t find&lt;/em&gt; Ruby books). At the time, I thought of Ruby as merely &amp;#8220;a Japanese Perl,&amp;#8221; so I only picked it up on a whim â€” but only a few chapters in, I was completely hooked.&lt;/p&gt;

&lt;p&gt;Although I continued to use Python (and PHP) professionally for the next couple of years, and very successfully â€” I spent my spare time on Ruby, and became very active in the community. In 2004 I fully switched, and became a professional Ruby developer.&lt;/p&gt;

&lt;p&gt;I haven&amp;#8217;t looked back.&lt;/p&gt;

&lt;h3 id='okay_looking_back'&gt;Okay, looking back&lt;/h3&gt;

&lt;p&gt;Recently I&amp;#8217;ve had the need to do a proof-of-concept across multiple &amp;#8220;production quality&amp;#8221; OO languages, so it seemed only natural to dig back into Python a bit.&lt;/p&gt;

&lt;p&gt;I discovered a language that had matured significantly with a smart community â€” that now included some &amp;#8220;younger&amp;#8221; blood and a fair bit of excitement.&lt;/p&gt;

&lt;p&gt;So, some specifics, maybe?&lt;/p&gt;

&lt;p&gt;First of all, let me add a disclaimer.&lt;/p&gt;

&lt;p&gt;As I&amp;#8217;ve stated, I haven&amp;#8217;t touched the language in years, and I&amp;#8217;m many a code kata from anywhere near full competency, let alone best-practices. The following may be completely unadulterated bullshit, and since it&amp;#8217;s largely based on Python 2.6 vs 3.0, may be a bit outdated as well. I heartily welcome comments from people who care deeply about Python and can point out better ways to approach things, or simple flaws in my judgment.&lt;/p&gt;

&lt;h3 id='random_feelings'&gt;Random feelings&lt;/h3&gt;

&lt;p&gt;So here you go, the bad in with the good.&lt;/p&gt;

&lt;p&gt;Python feels clean. I &lt;em&gt;know&lt;/em&gt; I&amp;#8217;m writing something for a computer, and I seem to focus on the implementation vs the API first when coding Python. This is kind of satisfying. I&amp;#8217;m not sure if this is good or bad.&lt;/p&gt;

&lt;p&gt;I can&amp;#8217;t help but love packages. Although they can be a horrific, academic mess (ie, Java), in many cases a file-based approach removes a lot of complexity. The Ruby community adheres to a lot of different ephemeral &amp;#8220;standards&amp;#8221; on how to split code between files, and it can be exhausting worrying about itâ€” as a perfectionist I&amp;#8217;m a constant fiddler, and worrying about how to split up a module is simply too trivial to be productive.&lt;/p&gt;

&lt;p&gt;I love list comprehensions. Python has them, Ruby doesn&amp;#8217;t. This still burns me. I blame Haskell for getting me addicted.&lt;/p&gt;

&lt;p&gt;People tend to focus on little details like whitespace sensitivity when they complain about Python. &lt;em&gt;Especially&lt;/em&gt; Rubyists â€” we tend to look on strict, seemingly &amp;#8220;arbitrary&amp;#8221; rules with a jaundiced eye â€” but this is a red herring in my opinion. A good developer is going to indent correctly and consistently anyway. If you don&amp;#8217;t have a standard way of indenting your codeâ€” or if, God forfend, you use &lt;em&gt;tabs&lt;/em&gt;â€” someone should shake the crap out of you.&lt;/p&gt;

&lt;p&gt;Butâ€¦ I&amp;#8217;m sorry, I love my end keyword. Lose it, and if you have to re-indent code manually it&amp;#8217;s a serious pain in the ass. The fluttering, anchor-less statements of Python rely on a single colon to indicate an upcoming indentation, and that&amp;#8217;s not enough for my poor eyes (I like a nice sturdy end to indicate the end of an indentation). It &lt;em&gt;is&lt;/em&gt; a bit nice to lose an extra line every time, but I&amp;#8217;ll happily refer to it as the Clarity Tax. Obviously this is a personal preference.&lt;/p&gt;

&lt;p&gt;I love my blocks; the stunted lambda Python supports seems a pittance. I &lt;em&gt;do&lt;/em&gt; think the new with keyword is an interesting approach towards &amp;#8220;cleanup blocks&amp;#8221; (eg, File.open), though they feel a bit like hidden magic and a bit hackish to implement. I know, I know, a Rubyist complaining about magic!&lt;/p&gt;

&lt;p&gt;Stating what I think about explicit returns would be too explicit for this blog.&lt;/p&gt;

&lt;p&gt;Python doesn&amp;#8217;t feel &amp;#8220;fluent&amp;#8221; to meâ€” in terms of flow, it&amp;#8217;s the stuttering Tarzan of programming languagesâ€” staccato phrases, prolific underscores, colons and parenthesis galore. Granted, this is a matter of taste (and I happily code in Erlang, which is far worse), and it &lt;em&gt;is&lt;/em&gt; a &lt;em&gt;programming&lt;/em&gt; language, but I would consider Python far more functional (in the utility sense) than elegant.&lt;/p&gt;

&lt;p&gt;Multiple inheritance is still more of a pain than it&amp;#8217;s worth, super() is pretty lame, and the fact self still needs to be a parameter in method definitions makes me scratch my head in befuddlement.&lt;/p&gt;

&lt;p&gt;Python threads are far better than Ruby 1.8 threads, plain and simple. They&amp;#8217;re strict (you ask them &lt;em&gt;politely&lt;/em&gt; to exit, &lt;em&gt;on their own time&lt;/em&gt;) and competent.&lt;/p&gt;

&lt;p&gt;setuptools is kind of cool, and eggs are also neat; Rubygems seems simpler and more cohesive, however.&lt;/p&gt;

&lt;p&gt;Frankly, properties and generators are still a bit missing in my education; they&amp;#8217;re not features that &amp;#8220;pop out&amp;#8221; or seem to be explained in clear terms. This is probably my failing, and may have prevented me from seeing Python in a clear light in some cases.&lt;/p&gt;

&lt;p&gt;The Python executable being a REPL is just plain awesome. I still don&amp;#8217;t know why IRB is separate from the Ruby executable (and don&amp;#8217;t even &lt;em&gt;try&lt;/em&gt; to read it, it&amp;#8217;s a shark attack). My good friend David Black, even older Ruby salt than I, &lt;a href='http://twitter.com/david_a_black/status/1069675147'&gt;commiserated on this recently&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, I think that&amp;#8217;s enough for now. I&amp;#8217;ve also been playing with Django a fair bit, so I may post something on it soon.&lt;/p&gt;

&lt;h4 id='updates'&gt;Updates&lt;/h4&gt;

&lt;p&gt;I&amp;#8217;ve removed my previous statement on Pythonistas not finding closures &lt;em&gt;useful&lt;/em&gt;, as it was confusing and seemed to indicate a lack of support in the language rather than discussions I&amp;#8217;ve had with Python developers on their utility in day-to-day development. I&amp;#8217;m aware Ruby developers complaining about missing language feature X in Python is probably as annoying as Python developers complaining about VM speed in Ruby, and based on just as outdated information. Python&amp;#8217;s &amp;#8220;lack of closures&amp;#8221; is a common straw man, and I apologize for the confusion.&lt;/p&gt;

&lt;p&gt;There seems to be a lot of contention on the tabs vs spaces comment. It&amp;#8217;s a personal view, largely based on code portability (including copy and paste to a browser) and modern editors. Lots of people on either side of this issue; feel free to debate amongst yourselves.&lt;/p&gt;

&lt;p&gt;I wasn&amp;#8217;t overstating the fact Ruby developers complain about Python&amp;#8217;s importance of whitespace. It&amp;#8217;s often one of the first criticisms leveled against the language (and as I indicate above, a fairly petty one), and is easy to find on the web &lt;a href='http://www.google.com/search?q=python+vs+ruby+whitespace'&gt;via google&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To add something else that I think is &lt;em&gt;awesome&lt;/em&gt; about Python: docstrings. In comparison, Ruby&amp;#8217;s tools-only approach (ie ri for retrieval and rdoc for generation) is pretty weak. It&amp;#8217;s amazingly handy to access documentation via the console; wouldn&amp;#8217;t it be neat if we could do something like the following in Ruby? It would make building new documentation tools (not to mention casual investigation) &lt;em&gt;so&lt;/em&gt; much easier.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;puts some_object.documentation # or `doc` or `__doc__`, etc

# For methods
puts some_object.method(:method_name).documentation&lt;/code&gt;&lt;/pre&gt;

&lt;blockquote&gt;
&lt;p&gt;A note for commenters: whenever possible, please include code or references. I&amp;#8217;m quite happy to own up to and add an update here if I&amp;#8217;m wrong on a point, but I&amp;#8217;d like references available for readers, especially if it&amp;#8217;s a common misconception.&lt;/p&gt;
&lt;/blockquote&gt;</content>
 </entry>
 
 <entry>
   <title>Front Row to History</title>
   <link href="http://codefluency.com/2008/11/09/front-row-to-history.html"/>
   <updated>2008-11-09T00:00:00-08:00</updated>
   <id>http://codefluency.com/2008/11/09/front-row-to-history</id>
   <content type="html">&lt;p&gt;I had to tell this story several dozen times at RubyConf, so I thought I&amp;#8217;d wrap it up for posterity.&lt;/p&gt;

&lt;p&gt;It all started with an email. The campaign was running a contest entitled &amp;#8220;Front Row to History,&amp;#8221; and would select 5 first-time and 5 repeat donators to attend the rally in Chicago&amp;#8211; what would later become a massive victory celebration.&lt;/p&gt;

&lt;p&gt;I had donated to the campaign before and had, like many of you, become more and more fervent in my support of Obama as election day approached. I&amp;#8217;m an independent voter, but my support was won after researching policies and watching the tone of the campaigns as they progressed.&lt;/p&gt;

&lt;p&gt;So, I did a bit of early voting with my wallet. Again.&lt;/p&gt;

&lt;h3 id='the_barack_blog_calleth'&gt;The Barack blog calleth&lt;/h3&gt;

&lt;p&gt;Halloween night was fantastic. I spent the evening with my wife, Melissa, and sons Braedyn and Jamis (Peter Pan and Captain Hook, respectively) in the Hyde Park neighborhood in Austin, guests of my generous boss, Steve Sanderson, and his lovely family. We had a blast; with well over a thousand kids and blocked- off roads, this was the place to be.&lt;/p&gt;

&lt;p&gt;Then, unexpectedly, the &lt;a href='http://barackobama.com/blog'&gt;Barack Obama blog&lt;/a&gt; called, wanting an interview. They had read the little blurb I had added on the donation form as a cathartic gesture, detailing my support in light of the fact I was an Arabic Linguist in the USAF for 6 years, before 9/11 and through the first couple years of the war. As they explained it, they were just looking for material for a blog entry. I expected a cross-section of donors would be detailed on the blog, and that in essence I would just be a part of a campaign funding post-mortem, or something equally mundane.&lt;/p&gt;

&lt;p&gt;But something about the interview struck me: it was deep. It seemed like more than the material for a pedestrian blurb and picture. Did they really have the time to invest so much energy in a long list of interviews, mere days before the election?&lt;/p&gt;

&lt;p&gt;I joked with my wife that maybe they needed to prep press decks ahead of time for &amp;#8220;Front Row to History,&amp;#8221; since they&amp;#8217;d want to announce the winners as late as possible, but they&amp;#8217;d need to gather the material for the release as quietly as possible. We laughed; me a little more uneasily.&lt;/p&gt;

&lt;p&gt;But stuff like this doesn&amp;#8217;t happen to people like us, right?&lt;/p&gt;

&lt;h3 id='the_narrowly_avoided_heartattack'&gt;The narrowly avoided heart-attack&lt;/h3&gt;

&lt;p&gt;Around noon on the 3rd I was sitting at work, furiously trying to track down a bug in a piece of software I was writing when I received a call from the friendly Obama blogger. My side of the conversation probably went something like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Oh, hi Molly, how are you doing today? Great, great. Doing very wellâ€¦ umm.. what? WHAT? ARE YOU SERIOUS? REALLY? Yeah, I think I can do that. No, really. Yeah. &lt;strong&gt;takes breath&lt;/strong&gt; Okay, I can&amp;#8217;t believe this, this is insane! Okay, I&amp;#8217;ll wait for the call from travelâ€¦&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I went home early. I&amp;#8217;ll get to that software bug eventually.&lt;/p&gt;

&lt;h3 id='off_i_go'&gt;Off I go&lt;/h3&gt;

&lt;p&gt;The next day, off I flew to Chicago, taking my friend &lt;a href='http://damonc.com'&gt;Damon&lt;/a&gt; (who was probably even more surprised, considering he was visiting family in Tulsa, and didn&amp;#8217;t see this coming &lt;em&gt;at all&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;More on the election night party itself soon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: I didn&amp;#8217;t get a chance to post about the election night party in any decent amount of time, so I&amp;#8217;ll leave it to your imagination. Suffice it to say, it was surreal to stand just a couple dozen yards away from now-President Obama as he gave his victory speech.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Boston.rb Slides</title>
   <link href="http://codefluency.com/2008/09/09/boston-slides.html"/>
   <updated>2008-09-09T00:00:00-07:00</updated>
   <id>http://codefluency.com/2008/09/09/boston-slides</id>
   <content type="html">&lt;p&gt;The &lt;a href='http://www.scribd.com/doc/5707264/New-in-Ruby-1-9'&gt;material for the talk&lt;/a&gt; is fairly similar to the Lone Star 1.9 talk I did a few days prior, but re-tooled for a smaller group.&lt;/p&gt;

&lt;p&gt;Thanks to my employer, &lt;a href='http://www.fiveruns.com'&gt;FiveRuns&lt;/a&gt;, for bankrolling the trip, and to the guys out at &lt;a href='http://thoughtbot.com'&gt;Thoughtbot&lt;/a&gt; and the Boston.rb group for their hospitality.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Arrow Lambdas, a Ruby 1.9 Vignette</title>
   <link href="http://codefluency.com/2008/08/17/arrow-lambdas-a-ruby-1-9-vignette.html"/>
   <updated>2008-08-17T00:00:00-07:00</updated>
   <id>http://codefluency.com/2008/08/17/arrow-lambdas-a-ruby-1-9-vignette</id>
   <content type="html">&lt;p&gt;Proc, the object-y twin of the syntax-level block, is the subject of a controversial change in Ruby 1.9: the addition of a new literal.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s here to stay. Let&amp;#8217;s play a bit, shall we?&lt;/p&gt;

&lt;p&gt;While we still have &lt;code&gt;Kernel#lambda&lt;/code&gt;, in Ruby 1.9 the parser now accepts a literal that looks like the following (to support some great new features such as default arguments and associated blocks):&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='c1'&gt;# the basic form&lt;/span&gt;
&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;x&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='c1'&gt;# with an argument&lt;/span&gt;
&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;x&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;x&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='c1'&gt;# (without parenthesis, too)&lt;/span&gt;
&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;y&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;x&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;y&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='c1'&gt;# multiple arguments&lt;/span&gt;
&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;y&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;x&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;y&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='c1'&gt;# default arguments&lt;/span&gt;
&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;y&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='n'&gt;z&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;x&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;y&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;z&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;call&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='c1'&gt;# take a block&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These are being called &lt;em&gt;arrow&lt;/em&gt; (or &lt;em&gt;pointy&lt;/em&gt;) lambdas. It&amp;#8217;s just a Proc literal.&lt;/p&gt;

&lt;p&gt;Although many people dislike this new syntax, it&amp;#8217;s come to grow on me. Having lambdas at the syntax level strikes me as a good &lt;em&gt;functional&lt;/em&gt; feature, and functional programming is a hard drug to come off of. I &lt;em&gt;do&lt;/em&gt; wish a slightly different format had been used â€” Erlang makes me want the arguments first, and Haskell makes me want a Î»-like backslash (&lt;a href='http://pragdave.blogs.pragprog.com/pragdave/2008/05/new-lambda-synt.html'&gt;as it does Dave Thomas&lt;/a&gt;) â€” but I can live with it.&lt;/p&gt;

&lt;h3 id='calling_them'&gt;Calling them&lt;/h3&gt;

&lt;p&gt;You can call lambdas using a bit of new syntax, too.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='n'&gt;times&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;y&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;x&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;y&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='n'&gt;times&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This outputs:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='mi'&gt;6&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Make sure you use &lt;em&gt;a dot before the opening parenthesis&lt;/em&gt;. If you forget it, you&amp;#8217;ll get a NameError when Ruby looks around for a &lt;em&gt;method&lt;/em&gt; by that name:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='n'&gt;times&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;# BAD!&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It raises:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;NoMethodError: undefined method `times&amp;#39; for main:Object&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I remember this shortend call feature under the moniker &lt;em&gt;dot call&lt;/em&gt; (which is reminiscent of regular expression &lt;code&gt;//s&lt;/code&gt; &lt;em&gt;dotall&lt;/em&gt;, so it works for me, text- processing nerd that I am).&lt;/p&gt;

&lt;h3 id='with_a_block_no_less'&gt;With a block, no less&lt;/h3&gt;

&lt;p&gt;Let&amp;#8217;s try defining a lambda that accepts an associated block when called, since we can these days:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='n'&gt;say_hello&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;n&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='nb'&gt;name&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;n&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;times&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='nb'&gt;puts&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Hello, %s&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;%&lt;/span&gt; &lt;span class='nb'&gt;name&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here we assign a lambda to the variable &lt;code&gt;say_hello&lt;/code&gt; that takes two arguments; the first a number of times to say something, and the second a block to call to retrieve a name (which will be converted to a lambda with &amp;amp; and assigned to the name block variable).&lt;/p&gt;

&lt;p&gt;Now let&amp;#8217;s invoke it:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='n'&gt;say_hello&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; 
  &lt;span class='s2'&gt;&amp;quot;Bruce&amp;quot;&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This outputs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Hello, Bruce
Hello, Bruce
Hello, Bruce&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, here we call the lambda, sending it 4 as the first argument (which is assigned to n), and a block (which is converted and assigned to name). The say&lt;em&gt;hello lambda does its work, invoking the name lambda (with no arguments) in turn.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Note we can&amp;#8217;t just use yield in the &lt;code&gt;say_hello&lt;/code&gt; lambda to call name; yield in this context would make Ruby look for a block passed to the &lt;em&gt;enclosing scope&lt;/em&gt; (ie, the method where &lt;code&gt;say_hello&lt;/code&gt; is being defined), and that&amp;#8217;s not what we want.&lt;/p&gt;

&lt;h3 id='it_can_get_really_ugly'&gt;It can get really ugly&lt;/h3&gt;

&lt;p&gt;These new lambda literals can be a bit odd in some syntactic contexts. Here&amp;#8217;s one.&lt;/p&gt;

&lt;h4 id='as_hash_values_in_oldstyle_hash_literals'&gt;As hash values (in old-style hash literals)&lt;/h4&gt;

&lt;p&gt;Not that this would generally be done anyhow, but &lt;em&gt;boy&lt;/em&gt; are the double arrows here ugly:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='n'&gt;strategies&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;mult&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;y&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;x&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;y&lt;/span&gt; &lt;span class='p'&gt;}}&lt;/span&gt;
&lt;span class='nb'&gt;p&lt;/span&gt; &lt;span class='n'&gt;strategies&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;mult&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Outputs:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='mi'&gt;6&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s even worse without parenthesis (it&amp;#8217;s a good idea to use parenthesis in any but the most trivial arrow lambda):&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;mult&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;y&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;x&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;y&lt;/span&gt; &lt;span class='p'&gt;}}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s a &lt;em&gt;bit&lt;/em&gt; better using the new hash syntax (using a Symbol for a key this time):&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;mult&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;x&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;y&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;x&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;y&lt;/span&gt;&lt;span class='p'&gt;}}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id='strung_out_or_wrung_out'&gt;Strung out or wrung out&lt;/h4&gt;

&lt;p&gt;The parser&amp;#8217;s pretty good at figuring out what the boundaries of these new lambdas are, and with new possibilities like default arguments, mandatory arguments &lt;em&gt;after&lt;/em&gt; default arguments, not to mention block arguments, things can get pretty long and &lt;em&gt;nasty&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The following is a completely legal &lt;em&gt;single&lt;/em&gt; lambda being immediately invoked:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;b&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;c&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='n'&gt;d&lt;/span&gt; &lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;b&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;c&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='nb'&gt;p&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='nb'&gt;p&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='mi'&gt;4&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Yeah, I know this lambda is useless. But even if it was &lt;em&gt;useful&lt;/em&gt; it&amp;#8217;d be too ugly to foist on another human being.&lt;/p&gt;

&lt;p&gt;Ruby is not Perl. Say it with me.&lt;/p&gt;

&lt;h3 id='who_are_we_who_will_we_be'&gt;Who are we? Who will we be?&lt;/h3&gt;

&lt;p&gt;Issues like the addition of a new literal really get people riled up (well, as riled up as nerdy backseat language designers get, I guess). This is a language many of us became interested in because of its elegance (perceived or otherwise; it really doesn&amp;#8217;t matter), and I think it&amp;#8217;s only natural that we try to avoid adding to the language at such a basic level as syntax.&lt;/p&gt;

&lt;p&gt;Lambdas are such a basic building block of Ruby, however, that I think a real, flexible literal has been long overdue, and I&amp;#8217;m very happy it&amp;#8217;s here, especially since it&amp;#8217;s in a form I don&amp;#8217;t consider completely off-putting.&lt;/p&gt;

&lt;p&gt;Hopefully the community will self-regulate a little on convention and continue to consider elegance, not obfuscation, as the defining characteristic of a kickass Rubyist. That&amp;#8217;s all any of us can ask for.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>ViewGem, a Little Script</title>
   <link href="http://codefluency.com/2008/08/10/viewgem-a-little-script.html"/>
   <updated>2008-08-10T00:00:00-07:00</updated>
   <id>http://codefluency.com/2008/08/10/viewgem-a-little-script</id>
   <content type="html">&lt;p&gt;What do you do when you need figure out what&amp;#8217;s going on inside a gem, or just get a feel for its API?&lt;/p&gt;

&lt;p&gt;I don&amp;#8217;t use generated documentation to help me solve problems â€” often the library&amp;#8217;s author and I disagree about what&amp;#8217;s important to mention, and/or the documentation is fairly non-existent. Hey, I can&amp;#8217;t whineâ€¦ this stuff is &lt;em&gt;free&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;While I don&amp;#8217;t necessarily agree with my esteemed colleague &lt;a href='http://therealadam.com'&gt;Adam Keys&lt;/a&gt; on his hypothesis that comments are a &lt;em&gt;bad smell&lt;/em&gt;, I can definitely state that many &lt;em&gt;smell bad&lt;/em&gt;. The fact they get generated into a prettier format also doesn&amp;#8217;t help muchâ€¦ and well, we all know how often User&amp;#8217;s Manuals and the like get updated.&lt;/p&gt;

&lt;p&gt;Just get me to the code already!&lt;/p&gt;

&lt;h3 id='heres_a_little_script'&gt;Here&amp;#8217;s a little script&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Update 2008-12-23&lt;/strong&gt;: Just use the &lt;a href='http://github.com/lmarlow/gemedit/tree/master'&gt;gemedit gem&lt;/a&gt; :-)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails BootUp, Austin TX</title>
   <link href="http://codefluency.com/2008/08/06/rails-bootup-austin-tx.html"/>
   <updated>2008-08-06T00:00:00-07:00</updated>
   <id>http://codefluency.com/2008/08/06/rails-bootup-austin-tx</id>
   <content type="html">&lt;p&gt;&lt;img src='/assets/rails_bootup_logo.png' alt='' /&gt; A couple of months ago when &lt;a href='http://damonc.com'&gt;Damon Clinkscales&lt;/a&gt; asked if I&amp;#8217;d participate in a local training session for new Rails developers, I jumped at the opportunity. I really enjoyed my time as a speaker for the Rails Edge conferences, and, regardless of how stressful it is, there&amp;#8217;s few things as satisfying as watching someone &lt;em&gt;get&lt;/em&gt; Ruby and Rails right in front of your eyes.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://railsbootup.eventbrite.com/'&gt;Rails BootUp&lt;/a&gt; was born, and this last Saturday Damon, Edward, Mike, Rob, myself, and a class of 11 spent the day at Datran Media&amp;#8217;s offices talking about Ruby and Rails. It was funâ€¦ and there was some mighty fine catering, courtesy of Damon&amp;#8217;s excellent taste in local restaurants.&lt;/p&gt;

&lt;h3 id='why_we_did_it'&gt;Why we did it&lt;/h3&gt;

&lt;p&gt;So, backing up a bitâ€¦ why teach a small Rails course here in Austin?&lt;/p&gt;

&lt;p&gt;To put it plain and simple, it was to help build up the local Ruby community. While Austin is a pretty fair sized IT corridor, our Ruby and Rails groups are still in the fledgling stage; there seem to be a large number of local developers (many of them working with Java) that seem poised on the fence, interested in Ruby but without the skills or understanding they feel necessary to take the leap.&lt;/p&gt;

&lt;p&gt;This course, from my perspective, was designed in part to introduce a new group of developers to the languageâ€” and to test the waters to see if a demand for Ruby training exists in the local area. As fast as the event sold out, I think we have our answer.&lt;/p&gt;

&lt;p&gt;We also donated over $400 to &lt;a href='http://www.austinchildrenshelter.org'&gt;Austin Children&amp;#8217;s Shelter&lt;/a&gt;, which isn&amp;#8217;t half- bad!&lt;/p&gt;

&lt;h3 id='it_went_pretty_well'&gt;It went pretty well&lt;/h3&gt;

&lt;p&gt;I think we had a solid progression of lessons throughout the day; from Rob&amp;#8217;s thorough introduction to the Ruby language itself all the way to Damon&amp;#8217;s talk on Capistrano (where attendees actually deployed their own code to separate Dreamhost configurations).&lt;/p&gt;

&lt;p&gt;My talk on ActionPackâ€” explaining how requests become responses and how views are structuredâ€” seemed to go off well, though this is definitely a &lt;em&gt;set&lt;/em&gt; of topics that should be broken out to several focused talks in later manifestations of the Rails BootUp. As with any training courseâ€” especially one being done for the very first timeâ€” there is plenty of room for improvement in future events.&lt;/p&gt;

&lt;h3 id='salutations'&gt;Salutations&lt;/h3&gt;

&lt;p&gt;We sure did meet a great group of inquisitive, bright developers. Welcome, and &lt;a href='http://austinonrails.org'&gt;keep in touch&lt;/a&gt;!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>RTeX 2.0 Released</title>
   <link href="http://codefluency.com/2008/05/20/rtex-2-0-released.html"/>
   <updated>2008-05-20T00:00:00-07:00</updated>
   <id>http://codefluency.com/2008/05/20/rtex-2-0-released</id>
   <content type="html">&lt;p&gt;I&amp;#8217;m happy to finally release &lt;a href='http://rtex.rubyforge.org'&gt;RTeX v2.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;RTeX is a Ruby library for generating PDFs via the &lt;a href='http://www.latex-project.org/'&gt;LaTeX typesetting system&lt;/a&gt;, and can be used as a &lt;a href='http://rtex.rubyforge.org/manual/executable.html'&gt;standalone executable&lt;/a&gt; or &lt;a href='http://rtex.rubyforge.org/manual/rails.html'&gt;Rails plugin&lt;/a&gt; for &lt;code&gt;pdf.rtex&lt;/code&gt; files. If you need to generate complex (and well- typeset) documents dynamically, this might be the ticket.&lt;/p&gt;

&lt;p&gt;This updated version of RTeX offers a number of improvements over previous versions, and has been a long time in making. For more details on the library, &lt;a href='http://rtex.rubyforge.org/'&gt;start here&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>RTeX on Lighthouse</title>
   <link href="http://codefluency.com/2008/05/17/rtex-on-lighthouse.html"/>
   <updated>2008-05-17T00:00:00-07:00</updated>
   <id>http://codefluency.com/2008/05/17/rtex-on-lighthouse</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve just opened up a Lighthouse project for &lt;a href='http://rtex.rubyforge.org'&gt;RTeX&lt;/a&gt; &lt;a href='http://codefluency.lighthouseapp.com/projects/11492-rtex'&gt;here&lt;/a&gt;. This fills out the RTeX family of pages to be:&lt;/p&gt;

&lt;p&gt;* &lt;a href='http://rtex.rubyforge.org'&gt;Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;* &lt;a href='http://github.com/bruce/rtex'&gt;Development&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;* &lt;a href='http://codefluency.lighthouseapp.com/projects/11492-rtex'&gt;Issue tracking&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>RTex Webby Filter</title>
   <link href="http://codefluency.com/2008/04/29/rtex-webby-filter.html"/>
   <updated>2008-04-29T00:00:00-07:00</updated>
   <id>http://codefluency.com/2008/04/29/rtex-webby-filter</id>
   <content type="html">&lt;p&gt;Good news today. &lt;a href='http://webby.rubyforge.org'&gt;Webby&lt;/a&gt;, my favorite little&lt;/p&gt;

&lt;p&gt;static website generator that could, is now being &lt;a href='http://github.com/TwP/webby'&gt;developed on GitHub&lt;/a&gt;. This will make contributing to the project easier for those of a git persuasion, and hopefully take a bit of pressure off Tim&amp;#8217;s shoulders in the long-term.&lt;/p&gt;

&lt;p&gt;I really enjoy playing with Webby, and my recent work with &lt;a href='http://rtex.rubyforge.org'&gt;RTeX&lt;/a&gt; has tweaked my interest in integrating PDF generation. Here&amp;#8217;s a walkthrough on how to add a quick filter to do just that.&lt;/p&gt;

&lt;h3 id='installing_the_goods'&gt;Installing the Goods&lt;/h3&gt;

&lt;p&gt;First of all, some prerequisites:&lt;/p&gt;

&lt;p&gt;1. Get &lt;a href='http://webby.rubyforge.org/manual/#h1'&gt;started&lt;/a&gt; on Webby, and create a project.&lt;/p&gt;

&lt;p&gt;2. Install &lt;a href='http://rtex.rubyforge.org/manual/install.html'&gt;RTeX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3. Brush up on your LaTeX (see the &lt;a href='http://rtex.rubyforge.org/faq/#latex'&gt;RTeX FAQ&lt;/a&gt; for a pointer on resources).&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;ve done all this, you&amp;#8217;re readyâ€¦ if you haven&amp;#8217;t, you&amp;#8217;re just skimming to see if this is interesting and/or simple, and that&amp;#8217;s okay, too.&lt;/p&gt;

&lt;h3 id='creating_a_document'&gt;Creating a Document&lt;/h3&gt;

&lt;p&gt;Let&amp;#8217;s create a file in your Webby &lt;code&gt;content/&lt;/code&gt; directory called &lt;code&gt;example.tex&lt;/code&gt; and put the following in it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  ---
  extension: pdf
  created_at: 2008-04-29 08:12:58.135564 -05:00
  layout: false
  filter: rtex
  ---
  \documentclass[12pt]{article}
  \begin{document}
  \title{A simple RTeX-generated PDF}
  \author{You \\ your-address@your-site.com}
  \maketitle
  \newpage
  See, it&amp;#39;s simple\ldots
  \end{document}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Okay, LaTeX content aside (it can be a bit much to take in if you&amp;#8217;re not used to it), this is a simple document.&lt;/p&gt;

&lt;p&gt;The first portion of the file (the part that looks &lt;em&gt;suspiciously&lt;/em&gt; like a YAML document) is the metadata. The first thing you should notice is the rtex filter we&amp;#8217;re assigning, which we&amp;#8217;ll work on shortly.&lt;/p&gt;

&lt;p&gt;We also set some other bits; the extension so that the generated document is named correctly (ie, &lt;code&gt;example.pdf&lt;/code&gt;), and layout, which we unset (you could use a nice, reusable LaTeX layout, but let&amp;#8217;s skip that for this example).&lt;/p&gt;

&lt;h3 id='a_simple_filter'&gt;A Simple Filter&lt;/h3&gt;

&lt;p&gt;Creating the filter for Webby is easy; it&amp;#8217;s just the bit of glue that sticks RTeX and Webby together.&lt;/p&gt;

&lt;p&gt;In your Webby project&amp;#8217;s &lt;code&gt;lib/&lt;/code&gt; directory (create it if needed), add a file. You can call it whatever you like, but let&amp;#8217;s use &lt;code&gt;rtex_filter.rb&lt;/code&gt; for now.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s the contents of the file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require &amp;#39;rtex&amp;#39;
Webby::Filters.register :rtex do |input, cursor|
  RTeX::Document.new(input).to_pdf
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Not exactly rocket science, is it?&lt;/p&gt;

&lt;h3 id='the_results'&gt;The Results&lt;/h3&gt;

&lt;p&gt;Now, regenerate your site. I commonly keep this running, as you can read about in the Webby documentation:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  rake autobuild&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should find example.pdf in the corresponding location under output/. Just link it from your normal Webby pages.&lt;/p&gt;

&lt;p&gt;With very few changes to the filter (eg, looking for additional processing options in a page&amp;#8217;s metadata), arbitrarily complex documents can be created directly from Webby.&lt;/p&gt;

&lt;p&gt;Not bad for a &amp;#8220;runt with a special knack for transforming text&amp;#8221; and a gem that&amp;#8217;s a poor man&amp;#8217;s binding.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>RTeX 2 Preview 1 Released</title>
   <link href="http://codefluency.com/2008/04/28/rtex-2-preview-1-released.html"/>
   <updated>2008-04-28T00:00:00-07:00</updated>
   <id>http://codefluency.com/2008/04/28/rtex-2-preview-1-released</id>
   <content type="html">&lt;p&gt;I&amp;#8217;m happy to release RTeX 2 Preview 1 (v1.99.0), now available as a gem from RubyForge. RTeX can be used as a plugin with Rails 2.0.1+.&lt;/p&gt;

&lt;h3 id='history'&gt;History&lt;/h3&gt;

&lt;p&gt;In 2006 I released a Rails plugin, &lt;code&gt;Rtex&lt;/code&gt;, used to generate PDFs via the LaTeX typesetting system. It became a popular choice for people looking for a more advanced alternative to PDF::Writer, especially for larger documents.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.halfgaar.net'&gt;Wiebe Cazemier&lt;/a&gt; joined the project in 2007, helping to improve the plugin and fielding patches and bug reports.&lt;/p&gt;

&lt;h3 id='rtex_2'&gt;RTeX 2&lt;/h3&gt;

&lt;p&gt;RTeX 2 isn&amp;#8217;t just a Rails plugin; it&amp;#8217;s &lt;a href='http://rtex.rubyforge.org/download'&gt;distributed as a gem&lt;/a&gt; and includes a &lt;a href='http://rtex.rubyforge.org/manual/executable.html'&gt;standalone executable&lt;/a&gt; that can be used to process documents outside a Rails process (for delayed processing or use in some other type of application) through a series of custom filters (eg, Textile).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For more detailsâ€¦&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;* &lt;a href='http://rtex.rubyforge.org'&gt;Documentation&lt;/a&gt; and &lt;a href='http://rtex.rubyforge.org/manual'&gt;Manual&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;* &lt;a href='http://rubyforge.org/projects/rtex'&gt;RubyForge&lt;/a&gt; for gem distribution and &lt;a href='http://github.com/bruce/rtex'&gt;GitHub&lt;/a&gt; for development.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>RubyLearning Interview</title>
   <link href="http://codefluency.com/2008/04/18/ruby-learning-interview.html"/>
   <updated>2008-04-18T00:00:00-07:00</updated>
   <id>http://codefluency.com/2008/04/18/ruby-learning-interview</id>
   <content type="html">&lt;p&gt;Satish Talim of &lt;a href='http://rubylearning.com'&gt;RubyLearning.com&lt;/a&gt; just posted &lt;a href='http://rubylearning.com/blog/2008/04/18/ruby-interview-bruce-williams-'&gt;my responses&lt;/a&gt; to several questions he posed on Ruby as a language and my tips on mastering it.&lt;/p&gt;

&lt;p&gt;It was a fun interview, and around a topic I really enjoy speaking about; Thanks Satish!&lt;/p&gt;

&lt;p&gt;of-fiveruns/&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Introduction to Ruby</title>
   <link href="http://codefluency.com/2008/04/14/introduction-to-ruby.html"/>
   <updated>2008-04-14T00:00:00-07:00</updated>
   <id>http://codefluency.com/2008/04/14/introduction-to-ruby</id>
   <content type="html">&lt;p&gt;&lt;a href='http://www.scribd.com/doc/13161925/Introduction-to-Ruby'&gt;Here are the slides&lt;/a&gt; for the talk I gave at the Scotland on Rails charity workshop on April 3rd â€¦ to a group of &lt;em&gt;very forgiving&lt;/em&gt; attendees who had graciously donated money only to see the first speaker arrive late and out-of- breath!&lt;/p&gt;

&lt;p&gt;As you might imagine, the content of the talk is fairly elementary &amp;#8211; but if you&amp;#8217;re looking for a brief, code-centric overview of Ruby&amp;#8217;s language features and syntax this might be the ticket.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Migrating to Ruby 1.9</title>
   <link href="http://codefluency.com/2008/04/14/migrating-to-ruby-1-9.html"/>
   <updated>2008-04-14T00:00:00-07:00</updated>
   <id>http://codefluency.com/2008/04/14/migrating-to-ruby-1-9</id>
   <content type="html">&lt;p&gt;&lt;a href='http://www.scribd.com/doc/12942398/Migrating-To-Ruby-19'&gt;Here&amp;#8217;s the slides&lt;/a&gt; for the other talk I gave at &lt;a href='http://scotlandonrails.com'&gt;Scotland on Rails&lt;/a&gt;, going over the syntax and language feature changes between Ruby 1.8 and Ruby 1.9.&lt;/p&gt;

&lt;p&gt;This is a significantly updated and expanded version of a &lt;a href='/2008/02/04/ruby-19-presentation.html'&gt;similar talk&lt;/a&gt; I gave at the Austin on Rails meeting in February.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Playing Catch-Up</title>
   <link href="http://codefluency.com/2008/04/13/playing-catch-up.html"/>
   <updated>2008-04-13T00:00:00-07:00</updated>
   <id>http://codefluency.com/2008/04/13/playing-catch-up</id>
   <content type="html">&lt;p&gt;It&amp;#8217;s been a busy month, finishing up a big release at &lt;a href='http://fiveruns.com'&gt;work&lt;/a&gt; and then escaping to hang out in the UK for a bit. Not that it&amp;#8217;s an excuse to go dark, of course, but I &lt;em&gt;have&lt;/em&gt; been preoccupied!&lt;/p&gt;

&lt;p&gt;Scotland on Rails was a really excellent conference. A smallish regional event (even the regional conferences are getting big these days), it was a largely single-track event and had a very cohesive feel. I was lucky to be able to present twice during the conference; &amp;#8220;Introduction to Ruby&amp;#8221; for the charity workshop and a &amp;#8220;Migrating to Ruby 1.9&amp;#8221; plenary session (slides for both of these to be posted soon).&lt;/p&gt;

&lt;p&gt;The conference covered a wide range of material; a good bit of pure Ruby (which always makes me happy), a suitable amount of Rails-centric sessions (it is Scotland on &lt;em&gt;Rails&lt;/em&gt;, after all), and even an Erlang talk for good measure.&lt;/p&gt;

&lt;p&gt;From an adoption standpoint, Scotland felt very US-in-late-2006 to me; a lot of individual passion and interest in the technology, a number of smaller companies actively using it, some large company/academic interest. It seems like there&amp;#8217;s a lot of opportunity for growth, given the number of smart people around. It will be interesting to see what happens in the coming year or two; I definitely plan on returning to see for myself!&lt;/p&gt;

&lt;p&gt;Thanks again to Alan, Paul, Abdel, and Graeme for all their hard work putting the conference together. This sort of thing is not a trivial undertaking!&lt;/p&gt;

&lt;p&gt;To those I met over Ruby or a pint &amp;#8211; let&amp;#8217;s keep in touch!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Scotland on Rails, April 4th-5th</title>
   <link href="http://codefluency.com/2008/02/23/register-for-scotland-on-rails.html"/>
   <updated>2008-02-23T00:00:00-08:00</updated>
   <id>http://codefluency.com/2008/02/23/register-for-scotland-on-rails</id>
   <content type="html">&lt;p&gt;I love Ruby (and Rails) conferences. I attend as many as I can each year, and I&amp;#8217;m especially excited about &lt;a href='http://scotlandonrails.com/'&gt;Scotland on Rails&lt;/a&gt; coming up in early April. Sure, part of it might be that I haven&amp;#8217;t been back to the UK since I was a teenager (and I plan to cool my heels in Edinburgh for a few extra days), but more than anything else, it&amp;#8217;s about meeting new people and reconnecting with old friends. It looks like there will be a wide range of both present at Scotland on Rails, and hopefully plenty of hacking, too!&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ll be speaking at about Ruby 1.9 at the conference, and there&amp;#8217;s a &lt;a href='http://scotlandonrails.com/speakers'&gt;great lineup&lt;/a&gt; of other talks about a wide range of subjects. If you can make it to Edinburgh April 4th-5th, &lt;a href='http://scotlandonrails.com/'&gt;register away&lt;/a&gt; â€¦ hope to see you there!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Advice for a Java Developer</title>
   <link href="http://codefluency.com/2008/02/17/advice-for-a-java-developer.html"/>
   <updated>2008-02-17T00:00:00-08:00</updated>
   <id>http://codefluency.com/2008/02/17/advice-for-a-java-developer</id>
   <content type="html">&lt;p&gt;Over the last two years or so there&amp;#8217;s definitely been an influx of people from Java, and that seems to be accelerating. Two of the developers I work with, in fact (&lt;a href='http://buddingrubyist.com'&gt;Brian&lt;/a&gt; and &lt;a href='http://mikeperham.com'&gt;Mike&lt;/a&gt;), are &lt;span&gt;somewhat&lt;/span&gt; recent converts from Java; you&amp;#8217;re definitely not alone.&lt;/p&gt;

&lt;p&gt;With as much Java experience as you have, you probably don&amp;#8217;t need a lot of hand-holding; but there are some concepts in Ruby might be somewhat foreign to you (depending on the rest of your background) &amp;#8211; specifically concepts like block closures and the level of dynamicism present in the language. If you&amp;#8217;re looking for books, I&amp;#8217;d recommend you familiarize yourself with:&lt;/p&gt;

&lt;p&gt;* &lt;a href='http://www.amazon.com/Programming-Ruby-Pragmatic-Programmers-'&gt;Programming Ruby&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;* &lt;a href='http://www.amazon.com/Ruby-Way-Second-Addison-Wesley-'&gt;The Ruby Way&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;* &lt;a href='http://www.amazon.com/Cookbook-Cookbooks-OReilly-Lucas-'&gt;The Ruby Cookbook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think it&amp;#8217;s important you get a firm grounding in the language &lt;em&gt;before&lt;/em&gt; the framework, but here are some Rails (framework-level) books:&lt;/p&gt;

&lt;p&gt;* &lt;a href='http://www.amazon.com/Agile-Web-Development-Rails-'&gt;Agile Web Development with Rails&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;* &lt;a href='http://www.amazon.com/Rails-Way-Addison-Wesley-Professional-'&gt;The Rails Way&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;* &lt;a href='http://www.amazon.com/Rails-Recipes-Pragmatic-Programmers-'&gt;Rails Recipes&lt;/a&gt; (I like this better than &amp;#8220;Rails Cookbook&amp;#8221;); an up-to- date &amp;#8220;Advanced Rails Recipes&amp;#8221; is coming out soon.&lt;/p&gt;

&lt;p&gt;* &lt;a href='http://www.amazon.com/Ruby-Rails-Techniques-'&gt;Ruby for Rails&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure you&amp;#8217;re spending time:&lt;/p&gt;

&lt;p&gt;* Reading code that highlights &amp;#8220;best practices&amp;#8221; (The Ruby Cookbook and Rails Recipes books above illustrate some examples); obviously like any community there are differences on opinion on what constitutes good, idiomatic Ruby, but I can give you some recommendations on specific projects&lt;/p&gt;

&lt;p&gt;* Spending some time with Ruby developers (&lt;a href='http://austinonrails.org'&gt;Austin on Rails&lt;/a&gt; is certainly a good place to start if you&amp;#8217;re in the Austin, TX area); collaborate on an actual project if you can, but there&amp;#8217;s value in just chatting, as well&lt;/p&gt;

&lt;p&gt;* Following what&amp;#8217;s going on in the Ruby community; there are a number of websites, mailing lists, and IRC channels that can help&lt;/p&gt;

&lt;p&gt;I consider these steps far more important than a full bookshelf.&lt;/p&gt;

&lt;p&gt;Second/dp/0974514055&lt;/p&gt;

&lt;p&gt;Professional/dp/0672328844/ref=pd&lt;em&gt;sim&lt;/em&gt;b&lt;em&gt;img&lt;/em&gt;4&lt;/p&gt;

&lt;p&gt;Carlson/dp/0596523696/ref=pd&lt;em&gt;sim&lt;/em&gt;b&lt;em&gt;img&lt;/em&gt;2&lt;/p&gt;

&lt;p&gt;2nd/dp/0977616630/ref=pd&lt;em&gt;bbs&lt;/em&gt;sr&lt;em&gt;1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1202238870&amp;amp;sr=1-1&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Ruby/dp/0321445619/ref=pd&lt;em&gt;bbs&lt;/em&gt;sr&lt;em&gt;2?ie=UTF8&amp;amp;s=books&amp;amp;qid=1202238899&amp;amp;sr=1-2&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Fowler/dp/0977616606/ref=sr&lt;em&gt;1&lt;/em&gt;4?ie=UTF8&amp;amp;s=books&amp;amp;qid=1202238946&amp;amp;sr=1-4&lt;/p&gt;

&lt;p&gt;Developers/dp/1932394699/ref=pd&lt;em&gt;bbs&lt;/em&gt;sr&lt;em&gt;1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1202239113&amp;amp;sr=1-1&lt;/em&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The Statesman on Rails</title>
   <link href="http://codefluency.com/2008/01/28/statesman-on-rails.html"/>
   <updated>2008-01-28T00:00:00-08:00</updated>
   <id>http://codefluency.com/2008/01/28/statesman-on-rails</id>
   <content type="html">&lt;p&gt;At the January meeting of &lt;a href='http://austinonrails.org'&gt;Austin on Rails&lt;/a&gt;, we had a couple visitors from the Austin American-Statesman newspaper (which everyone around here just calls &amp;#8220;The Statesman&amp;#8221;), covering Rails&amp;#8217; mindshare and market penetration in the city for an &lt;a href='http://www.statesman.com/business/content/business/stories/technology/'&gt;article published today&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The first thing you&amp;#8217;ll probably notice, looking at the page, is the &lt;em&gt;huge&lt;/em&gt; Rails logo; you can even &lt;span&gt;enlarge it&lt;/span&gt;, if you&amp;#8217;d like. Beyond that, there&amp;#8217;s a fairly even-handed article to read, and even a couple pictures (thankfully, the one with me hunched over my MBP hastily cobbling together the last few slides on my presentation has disappeared). If you&amp;#8217;re interested in Ruby/Rails from either a development or a business standpoint, it&amp;#8217;s probably worth a read.&lt;/p&gt;

&lt;p&gt;Crazy how this little language grew up.&lt;/p&gt;

&lt;h4 id='austin_on_rails'&gt;Austin on Rails&lt;/h4&gt;

&lt;p&gt;A lot of credit needs to go to &lt;a href='http://damonclinkscales.com/'&gt;Damon Clinkscales&lt;/a&gt; and the others who were around when the group first started. There&amp;#8217;s a lot of value in actual, face- to-face, cross-company technical and social interaction for developers, and I&amp;#8217;ve been really happy to hang around with these guys this year. This type of thing makes for a tighter knit community, a better support network, and opportunities for collaboration. If you&amp;#8217;re a developer and you&amp;#8217;re not taking a couple hours out of every month (or every week, with a &lt;a href='http://cafebedouins.com/austin'&gt;Cafe Bedouin&lt;/a&gt; or &lt;a href='http://austinruby.com/'&gt;ARCTAN&lt;/a&gt; style meeting) getting to know like-minded developers in your community, you&amp;#8217;re shooting yourself in the foot, period.&lt;/p&gt;

&lt;p&gt;Anyhow, a bit of code and beer never hurt anyone. Theoretically.&lt;/p&gt;

&lt;p&gt;01/28/0128ruby.html&lt;/p&gt;

&lt;p&gt;http://www.statesman.com/business/content/business/stories/technology/01/28 /Ruby-on-Rails-logo.html&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Welcome Back, Codefluency</title>
   <link href="http://codefluency.com/2008/01/27/welcome-back-codefluency.html"/>
   <updated>2008-01-27T00:00:00-08:00</updated>
   <id>http://codefluency.com/2008/01/27/welcome-back-codefluency</id>
   <content type="html">&lt;p&gt;A couple weeks ago I moved hosts, and while doing so put up a parking page. Life interceded,&lt;/p&gt;

&lt;p&gt;and I was down a bit longer than I would have liked, but &lt;em&gt;codefluency&lt;/em&gt; is back up and running.&lt;/p&gt;

&lt;p&gt;Some temporary shortcomings at the moment are, in order of importance:&lt;/p&gt;

&lt;p&gt;1. &amp;#8211;The atom feed (which seems to be the way a good percentage of people pick this up)&amp;#8211; This should be working now; it&amp;#8217;s up &lt;a href='http://codefluency.com/feed/atom.xml'&gt;at its old location&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;2. &amp;#8211;The need to rewrite incoming links (tag articles/ on the front of those old links at the moment)&amp;#8211; This should also be working. Let me know if you run into any bad links.&lt;/p&gt;

&lt;p&gt;Notably, and possibly permanently missing are:&lt;/p&gt;

&lt;p&gt;1. Search. Most browser-based readers come here directly for a specific article, and search has been essentially unused. Google does a better job of indexing the site in any case, so if it&amp;#8217;s needed just tack site:codefluency.com onto the front of your query, and voila .&lt;/p&gt;

&lt;p&gt;2. Comments. I love an active community just as much as the next guy (likely more, in fact), but I&amp;#8217;ve always found the best type of communication of a more active (live, if possible) nature. I&amp;#8217;ve had some great comments in the past, but the signal-to-noise ratio hasn&amp;#8217;t been very compelling, even counting out spam. I&amp;#8217;ve had a much better experience with those people who send a direct email, tweet, or IM (even if it&amp;#8217;s just to say &amp;#8216;hi&amp;#8217;). If something&amp;#8217;s said that&amp;#8217;s worth an update to an article, it&amp;#8217;ll happen. I&amp;#8217;ve wrestled a bit with this, but that&amp;#8217;s my conclusion; at least for the time being.&lt;/p&gt;

&lt;p&gt;Now the obligatory comments on the current incarnation. Those of you that have known me for any length of time know how I feel about this website; it&amp;#8217;s a playground, and it changes often. I had the previous design up for well over six months, which is likely a record for me. I&amp;#8217;ll probably keep it that way.&lt;/p&gt;

&lt;p&gt;So this time, a bit darker and content-focused. I&amp;#8217;ve added a bit of vector artâ€¦ which I&amp;#8217;ve alternately heard called &lt;em&gt;Rock Star&lt;/em&gt; and &lt;em&gt;Maoist&lt;/em&gt; this time; an interesting stylistic overlap, I suppose. I&amp;#8217;d heard comments that my old artwork looked dated, especially as it related to my hair (I&amp;#8217;m growing it out for charity, so it&amp;#8217;s obviously not short and spiky anymore), so this is a bit more accurate.&lt;/p&gt;

&lt;p&gt;A quick note on the technologies used this go. I&amp;#8217;ve opted for static pages, which is pretty refreshing for a guy who&amp;#8217;s been up to his eyeballs in web frameworks, most notably Rails, for the past few years. I&amp;#8217;m using &lt;a href='http://webby.rubyforge.org'&gt;Webby&lt;/a&gt; for generation; Tim Pease is both a good friend and a wickedly smart guy, and I really like what he&amp;#8217;s put together. It&amp;#8217;s built in Ruby, of course, and reminds me of the type of generation framework I &lt;em&gt;wanted&lt;/em&gt; to write coming off of bloxsom years ago, but could never get quite right; Tim has done a much better job than I ever could. Webby comes with a rake autobuild task, which integrated with Jeremy Hinegardner&amp;#8217;s &lt;a href='http://rubyforge.org/projects/copiousfreetime/'&gt;heel&lt;/a&gt; and &lt;a href='http://rubyforge.org/projects/copiousfreetime/'&gt;launchy&lt;/a&gt; projects makes on-the-fly generation a snap. Use Webby for static pages if you want something simple and straightforward.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://git.or.cz/'&gt;Git&lt;/a&gt; and &lt;a href='http://wiki.codemongers.com/Main'&gt;Nginx&lt;/a&gt; make up the rest of the toolkit; the website is actually a master repo that gets reset on update (thanks to &lt;a href='http://reinh.com'&gt;ReinH&amp;#8217;s&lt;/a&gt; suggestion and &lt;a href='http://utsl.gen.nz/git/post-update'&gt;this script&lt;/a&gt; called in a post-update hook).&lt;/p&gt;

&lt;p&gt;So, quick and simple is the callword for this version.&lt;/p&gt;

&lt;p&gt;Okay, enough meta for now.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Taming Your Views</title>
   <link href="http://codefluency.com/2007/12/18/taming-your-views.html"/>
   <updated>2007-12-18T00:00:00-08:00</updated>
   <id>http://codefluency.com/2007/12/18/taming-your-views</id>
   <content type="html">&lt;p&gt;Here&amp;#8217;s a note I should have posted a couple weeks ago..&lt;/p&gt;

&lt;p&gt;The Taming Your Views talk I gave at the Charity Workshop for the Lone Star Ruby Conference &lt;a href='http://www.mindbites.com/lesson/265-taming-your-views-in-ruby-on-rails'&gt;is available at MindBites&lt;/a&gt; (along with the other talks filmed that night), with proceeds going to charity.&lt;/p&gt;

&lt;p&gt;MindBites has some interesting videos (and you get some free credits when you sign up), so go have a look. Many thanks to &lt;a href='http://damonclinkscales.com/'&gt;Damon Clinkscales&lt;/a&gt; for putting the workshop together and handing video QA.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>10 Minutes with Factor</title>
   <link href="http://codefluency.com/2007/12/17/10-minutes-with-factor.html"/>
   <updated>2007-12-17T00:00:00-08:00</updated>
   <id>http://codefluency.com/2007/12/17/10-minutes-with-factor</id>
   <content type="html">&lt;p&gt;Factor is a stack-oriented language, similar in that respect to Forth and Joy. I&amp;#8217;ve &lt;em&gt;played&lt;/em&gt; with both at one point or another, so when I recently ran across a reference to Factor in a recent interview with Zed Shaw, I thought I&amp;#8217;d take a look. I&amp;#8217;m always on the prowl for little esoteric languages, hoping to harvest new (or newly revised) approaches to software development.&lt;/p&gt;

&lt;p&gt;First of all, some caveats. I don&amp;#8217;t know much about Factor yet, and I&amp;#8217;ve never been successful at implementing anything worthwhile in any stack-oriented language (not that I&amp;#8217;ve tried); my strengths mainly lie along the OOP and functional fronts, and I haven&amp;#8217;t really hit the &amp;#8220;Aha!&amp;#8221; moment yet with stacks. I do, however, appreciate the syntactic simplicity and extensibility of the idea, and hope to get there soon.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s get started.&lt;/p&gt;

&lt;h4 id='installing_factor'&gt;Installing Factor&lt;/h4&gt;

&lt;p&gt;You can grab binary and source copies of Factor from the website &lt;a href='http://factorcode.org/download.fhtml'&gt;here&lt;/a&gt;. Make sure you download an image file as well if you&amp;#8217;re building from source.&lt;/p&gt;

&lt;p&gt;You can also clone the Factor repository using git, with the standard disclaimers on stability.&lt;/p&gt;

&lt;h4 id='the_gui'&gt;The GUI&lt;/h4&gt;

&lt;p&gt;As crazy little esoteric languages go, Factor comes well-dressedâ€¦ with a relatively simple, but powerful GUI for interactive hacking, debugging, and code/documentation browsing. It completely puts irb to shame, of course; though there has been some work in this direction in Ruby, it sure would be nice if something similar would come standard with the language. I&amp;#8217;m not a big fan of big IDEs that do enough work for you that you forget how to do things yourself, but give me a little hacking console any day.&lt;/p&gt;

&lt;h5 id='basic_concepts'&gt;Basic Concepts&lt;/h5&gt;

&lt;p&gt;The basic concept of stack-oriented programming centers around manipulation of one or more stacks. In Factor this manipulation is done via &lt;em&gt;words&lt;/em&gt; (that sit in &lt;em&gt;vocabularies&lt;/em&gt;), and &lt;em&gt;generally&lt;/em&gt; a single stack is used. Let&amp;#8217;s try a simple example using the &amp;#8221;+&amp;#8221; word.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1 2 + .&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The first thing you might notice is that &amp;#8217;+&amp;#8217; comes at the end. This is called Reverse Polish Notation (RPN), and though it might seem a bit weird to those of us with infix operator leanings (and backwards to PN Schemers), it makes complete sense when you&amp;#8217;re dealing with a stack.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s break the example down, bit by bit.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;1&lt;/code&gt; is recognized as a number literal. It&amp;#8217;s pushed onto the stack. Stack looks like: &lt;code&gt;1&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;code&gt;2&lt;/code&gt; is recognized as a number literal. It&amp;#8217;s pushed onto the stack. Stack looks like: &lt;code&gt;1 2&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&lt;code&gt;+&lt;/code&gt; isn&amp;#8217;t recognized as a literal; it&amp;#8217;s a word that&amp;#8217;s found and executed. It pops off two items from the stack, adds them (just pretend how &lt;em&gt;that&lt;/em&gt; happens is unimportant for the moment), and pushes the result on the stack. Stack looks like: &lt;code&gt;3&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;A single period pops off an item from the stack. Think of it as returning a value. Stack is now empty.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>Gem</title>
   <link href="http://codefluency.com/2007/12/15/gem.html"/>
   <updated>2007-12-15T00:00:00-08:00</updated>
   <id>http://codefluency.com/2007/12/15/gem</id>
   <content type="html">&lt;p&gt;Rails plugins have been a great tool to have around; just look at the amazing number of plugins that have popped up over the last couple of years; great ideas from all over the place. Plugins are so easy to put together and distribute that many people who&amp;#8217;ve never released software before&lt;/p&gt;

&lt;p&gt;They also have some pretty serious flaws. There&amp;#8217;s no built-in versioning or Rails version requirements. There&amp;#8217;s no dependency resolution. There&amp;#8217;s no real metadata or built-in search functionality.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Syntax Changes in 1.9</title>
   <link href="http://codefluency.com/2007/12/03/syntax-changes-in-1-9.html"/>
   <updated>2007-12-03T00:00:00-08:00</updated>
   <id>http://codefluency.com/2007/12/03/syntax-changes-in-1-9</id>
   <content type="html">&lt;p&gt;I think one of the more interesting conversations that&amp;#8217;s going to occur in the Ruby community once 1.9 is released is how we integrate the syntax (and behavioral) changes coming into the language in as elegant form as possible. Over time, the consensus (or at least conventional usage) will drive what we label &lt;em&gt;Rubyesque&lt;/em&gt; (that is, idiomatically &lt;em&gt;Ruby&lt;/em&gt;); what is accepted, what is absurd, what is &lt;em&gt;clean&lt;/em&gt;, what is over-engineered, and what is far more clever than it is smart. We&amp;#8217;ll be reforming the &lt;em&gt;feel&lt;/em&gt; and &lt;em&gt;taste&lt;/em&gt; of Ruby using new artistic tools.&lt;/p&gt;

&lt;p&gt;Over time, we&amp;#8217;re sure to see a lot of forms pop up and then slowly fade away (remember the days of def ClassName.method&lt;em&gt;name and :: method invocations?), we&amp;#8217;ll see casual groups form (eg, the collectionists, the mappers, the private indenters, etc), and entirely new dialects pop out of the ether (Rails, anyone?) and seed the ground with fresh ideas.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is nothing new. It&amp;#8217;s how languages grow. Regardless of how you feel about it, Ruby is no exception.&lt;/p&gt;

&lt;p&gt;Over the next few weeks I&amp;#8217;m going to be switching the focus of this blog (&lt;em&gt;wait, there was a focus?&lt;/em&gt;) to the Ruby 1.9 release, especially as it relates to the syntax changes.. since Ruby&amp;#8217;s syntax is largely what drew me to the language, and something that continues to enthrall. This is definitely the most radical release I&amp;#8217;ve seen so far (though it needs to be said that many of the changes are experimental), so I&amp;#8217;m really going to dig in.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s start with a few examples of experimental lambda and hash features currently in 1.9. I&amp;#8217;ll be showing a few examples of some variants, it&amp;#8217;s up to you to decide on the forms you like most. You might want to bone up on the &lt;a href='http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l4'&gt;changes&lt;/a&gt; first.&lt;/p&gt;

&lt;h4 id='the_strategy_hash'&gt;The Strategy Hash&lt;/h4&gt;

&lt;p&gt;Example: Assigning a hash of symbol keys and lambda values as various strategies to process a string.&lt;/p&gt;

&lt;p&gt;Flavors to choose from:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Traditional &amp;#8216;lambda&amp;#8217; (let&amp;#8217;s skip &amp;#8216;proc&amp;#8217;)&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Experimental arrow lambda, parameters outside (parenthesized)&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Experimental arrow lambda, parameters outside (bare)&lt;/p&gt;

&lt;p&gt;strategies = { :simple =&amp;gt; lambda { |item| item.capitalize } } strategies = { :simple =&amp;gt; -&amp;gt;(item) { item.capitalize } } strategies = { :simple =&amp;gt; -&amp;gt; item { item.capitalize } }&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The arrow variants look &lt;span&gt;at least&lt;/span&gt; a little less ridiculous with the special symbol-key syntax:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;strategies = { simple: lambda { |item| item.capitalize } }
strategies = { simple: -&amp;gt;(item) { item.capitalize } }
strategies = { simple: -&amp;gt; item { item.capitalize } }&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id='the_filter_list'&gt;The Filter List&lt;/h4&gt;

&lt;p&gt;Example: Now let&amp;#8217;s toss some text filtering lambdas into an Array, using the various flavors.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;filters &amp;lt;&amp;lt; lambda { |item| item.capitalize }
filters &amp;lt;&amp;lt; -&amp;gt;(item) { item.capitalize }
filters &amp;lt;&amp;lt; -&amp;gt; item { item.capitalize }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Whoa, love the opposing directions there.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s push multiple arguments now:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;filters.push lambda { |item| item.capitalize }, lambda { |item| item.reverse }
filters.push -&amp;gt;(item) { item.capitalize }, -&amp;gt;(item) { item.reverse }
filters.push -&amp;gt; item { item.capitalize }, -&amp;gt; item { item.reverse }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These filters would be fun with inject &amp;amp; the new experimental &lt;code&gt;.()&lt;/code&gt; version of &lt;code&gt;call&lt;/code&gt;/&lt;code&gt;[]&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;filters.inject(&amp;#39;hey!&amp;#39;) { |res, filter| filter.(res) }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In parting, a bit of &lt;em&gt;clever&lt;/em&gt; code (note Enumerator, Lambda syntax, single block parameter, alternate call syntax).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;3.times.inject(-&amp;gt; { -&amp;gt; { -&amp;gt; { &amp;quot;Hello, #{RUBY_VERSION} World!&amp;quot; } } }){ |_| _.() }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There&amp;#8217;s a lot more to cover, obviously, but that&amp;#8217;s enough for now.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>It's time to play with 1.9</title>
   <link href="http://codefluency.com/2007/12/02/it-s-time-to-play-with-1-9.html"/>
   <updated>2007-12-02T00:00:00-08:00</updated>
   <id>http://codefluency.com/2007/12/02/it-s-time-to-play-with-1-9</id>
   <content type="html">&lt;p&gt;With Ruby 1.9 just around the corner, it&amp;#8217;s time for you to start playing with it. While you&amp;#8217;ll want to keep any production apps you have chugging away happily on 1.8, don&amp;#8217;t shoot yourself in the foot by not keeping up.&lt;/p&gt;

&lt;p&gt;Read the CHANGELOG, so you know what to expect (or read the &lt;a href='http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9'&gt;overview at eigenclass&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Install it alongside 1.8; here&amp;#8217;s my method:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;svn co http://svn.ruby-lang.org/repos/ruby/trunk ruby1.9
cd ruby1.9
autoconf
./configure --prefix=/usr/local --program-suffix=1.9
make
sudo make install&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Try something ridiculous, just because you can:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby1.9 -e &amp;#39;-&amp;gt;(t){ puts t }.(&amp;quot;This is Ruby 1.9!&amp;quot;)&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Build something with it, post some examples (I certainly plan to), and see what other people have to say&lt;/p&gt;

&lt;p&gt;&lt;code&gt;svn up&lt;/code&gt;, rebuild, and reinstall as we approach the Christmas release&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s a lot of great features and syntax changes in this release; I expect we&amp;#8217;ll see a lot of patterns (and anti-patterns) pop up as the community plays with 1.9. This is the first release with significant syntax changes since Ruby became popular &amp;#8211; in the past the number of people using Ruby was smaller by several orders of magnitudeâ€¦ so it will be interesting to see how, or if, a general consensus can be reached.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Ruby.framework</title>
   <link href="http://codefluency.com/2007/11/03/ruby-framework.html"/>
   <updated>2007-11-03T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/11/03/ruby-framework</id>
   <content type="html">&lt;p&gt;A few articles ago I talked about re-building Ruby on Leopard (instead of using the provided Ruby.framework).&lt;/p&gt;

&lt;p&gt;A couple days ago, I switched back to the framework to play around and have been using it instead &amp;#8211; and after Laurent&amp;#8217;s talk tonight I&amp;#8217;m 100% certain it was the right decision.&lt;/p&gt;

&lt;p&gt;Absolutely amazing.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Drinks at RubyConf</title>
   <link href="http://codefluency.com/2007/10/31/drinks-at-rubyconf.html"/>
   <updated>2007-10-31T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/10/31/drinks-at-rubyconf</id>
   <content type="html">&lt;p&gt;My &lt;a href='http://fiveruns.com'&gt;employer&lt;/a&gt; and &lt;a href='http://www.blueboxgrid.com/'&gt;BlueBox Group&lt;/a&gt; are graciously holding the bar open at &lt;a href='http://www.yelp.com/biz/arpa-charlotte'&gt;Arpa&lt;/a&gt; after the RubyConf keynote. Obviously they&amp;#8217;ll cap us at some pointâ€¦ but let&amp;#8217;s make that happen, shall we?&lt;/p&gt;

&lt;p&gt;No agenda + free drinks. See the &lt;a href='http://blog.fiveruns.com/2007/10/29/rubyconf-2007-event'&gt;official announcement&lt;/a&gt; and &lt;em&gt;rÃ©servez s &amp;#8216;il-vous-plaÃ®t&lt;/em&gt; if you have a moment (so I can gauge my planned intake).&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Stackalicious</title>
   <link href="http://codefluency.com/2007/10/27/stackalicious.html"/>
   <updated>2007-10-27T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/10/27/stackalicious</id>
   <content type="html">&lt;p&gt;So, at the risk of making entirely too many posts about Leopard today, I&amp;#8217;m going to toss another out.&lt;/p&gt;

&lt;p&gt;Uses for Stacks:&lt;/p&gt;

&lt;p&gt;* Clean up messes: Within a week I can turn a nice, clean desktop into a morass of inane downloads, screenshots, and documents. A Stack of ~/Downloads makes things a lot cleaner. If I can only figure out how to get screenshots to go into a separate Stackâ€¦&lt;/p&gt;

&lt;p&gt;* Little discrete groupings: I usually have a logical grouping of files on the desktop that I want quick access to, ie TextMake Project files. Having a single Stack might be a good approach for this.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Some Leopard + Ruby Notes</title>
   <link href="http://codefluency.com/2007/10/27/some-leopard-ruby-notes.html"/>
   <updated>2007-10-27T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/10/27/some-leopard-ruby-notes</id>
   <content type="html">&lt;p&gt;Ruby developers may want to keep the following bits of information in mind when they install Leopard.&lt;/p&gt;

&lt;p&gt;1. If you replaced Tiger&amp;#8217;s horribly broken /usr/bin/ruby with your own custom build (most of you did), be aware Leopard will overwrite it (now it points to the 1.8.6 Ruby.framework in /System that comes bundled). The same issue exists for the gem and rails executable. Not a big deal; re-overwrite as you see fit (or use the framework version and reinstall some gems and libraries).&lt;/p&gt;

&lt;p&gt;2. You&amp;#8217;ll probably need to reinstall Xcode, as well (at least if you want a compiler!). Throw your Leopard disk back in, go to Optional Installs -&amp;gt; Xcode Tools and install XcodeTools.mpkg. Same process as with Tiger.&lt;/p&gt;

&lt;p&gt;3. I needed to reinstall MacPorts as well.&lt;/p&gt;

&lt;p&gt;As you might expect, YMMV. More as I run across it.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Leopard, Off the Cuff</title>
   <link href="http://codefluency.com/2007/10/26/leopard-off-the-cuff.html"/>
   <updated>2007-10-26T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/10/26/leopard-off-the-cuff</id>
   <content type="html">&lt;p&gt;So, today was Leopard release day. Showing up at work this morning and seeing a shrink-wrapped copy on my desk was a nice surprise.&lt;/p&gt;

&lt;p&gt;Some initial reactions:&lt;/p&gt;

&lt;p&gt;* It&amp;#8217;s snappier. I&amp;#8217;m sure cleaning out my 10.4 cruft helped, but it sure is faster than I expected.&lt;/p&gt;

&lt;p&gt;* Spaces is a big deal. Multiple desktops are something I really missed from my days as a Linux junkie (Virtue Desktops didn&amp;#8217;t perform well enough for my tastes)&lt;/p&gt;

&lt;p&gt;* Cleaner UI. Very happy to get rid of the clunkier brushed-metal look. The window shadowing is definitely better in this release as well.&lt;/p&gt;

&lt;p&gt;* Web Clips are sweet. I do wonder, however, how this will affect ad-driven sites who rely on people coming to view changing content (which now can be docked ad-free on Dashboard).&lt;/p&gt;

&lt;p&gt;* Cover Flow in Finder is neat, at least for some types of media (especially with video Quick Look); it&amp;#8217;s useless with text, of course. The default blue folder image is disappointingly drab.&lt;/p&gt;

&lt;p&gt;* Lots of small features to find (tabbed windows and better Google Talk support in iChats, an improved Spotlight, etc); some of these &lt;a href='http://www.tuaw.com/2006/08/08/7-apps-that-leopard-kills/'&gt;might reduce&lt;/a&gt; my &lt;span&gt;currently fanatical&lt;/span&gt; need for applications like Quicksilver and Chax.&lt;/p&gt;

&lt;p&gt;I think the thing that most excites me about Leopard is the fact new applications are sure to come out that will leverage technologies like Core Animation (and various nifty XCode improvements). The next version of TextMate, which will be Leopard-only, for instance, is something I can&amp;#8217;t wait to get my hands on.&lt;/p&gt;

&lt;p&gt;All in all, very happy with this release so far.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>KeywordSearch 1.3.1</title>
   <link href="http://codefluency.com/2007/10/09/keywordsearch-1-3-1.html"/>
   <updated>2007-10-09T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/10/09/keywordsearch-1-3-1</id>
   <content type="html">&lt;p&gt;&lt;a href='http://codefluency.rubyforge.org/keyword_search'&gt;KeywordSearch&lt;/a&gt; is a small library I wrote earlier this year to add support for GMail-style keyword/value searches via a DSL. It&amp;#8217;s a parser pet project that I tweak from time-to-time.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s an example, albeit a little hackish:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Some variables to build up
clauses = []
arguments = []
# Search a string, defining the supported keywords and building up
# the variables in the associated closures
KeywordSearch.search(&amp;#39;account has:attachment since:2006-12-03&amp;#39;) do |with|
  with.default_keyword :title # values without keywords get assigned to this
  with.keyword :title do |values|
    # keyword blocks are yielded an array of values
    clauses &amp;lt;&amp;lt; &amp;quot;title like ?&amp;quot;
    arguments &amp;lt;&amp;lt; &amp;quot;%#{values.join(&amp;#39; &amp;#39;)}%&amp;quot;
  end
  with.keyword :has do |values|
    clauses &amp;lt;&amp;lt; &amp;#39;has_attachment = true&amp;#39; if values.include?(&amp;#39;attachment&amp;#39;)
  end
  with.keyword :since do |values|
    date = Date.parse(values.first) # only support one
    clauses &amp;lt;&amp;lt; &amp;#39;created_on &amp;gt;= ?&amp;#39;
    arguments &amp;lt;&amp;lt; date.to_s
  end
end

# Do our search with clauses and arguments

conditions = [clauses.map{|c| &amp;quot;(#{c})&amp;quot;}.join(&amp;#39; AND &amp;#39;)), *arguments] # simplistic example
results = Message.find(:all, :conditions =&amp;gt; conditions)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;KeywordSearch is available from RubyForge and can be installed via:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo gem install keyword_search&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Comments, as always, are welcome.&lt;/p&gt;

&lt;h3 id='changes_in_this_release'&gt;Changes in this release:&lt;/h3&gt;

&lt;p&gt;* Conversion to a &lt;a href='http://www.cs.queensu.ca/~thurston/ragel/'&gt;Ragel&lt;/a&gt; parser as a performance tweak (not to mention less code). (I still love Dhaka, though).&lt;/p&gt;

&lt;p&gt;* More advanced parsing with better character set support&lt;/p&gt;

&lt;p&gt;* Test suite now uses &amp;#8220;test/spec&amp;#8221;: and has been added to significantly&lt;/p&gt;

&lt;p&gt;* Keywords/values are now case sensitive; downcase the input manually if you want the old behavior.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rewrite Woes (Take Two)</title>
   <link href="http://codefluency.com/2007/09/24/rewrite-woes-take-two.html"/>
   <updated>2007-09-24T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/09/24/rewrite-woes-take-two</id>
   <content type="html">&lt;p&gt;There seems to be quite a furor over Derek Siver&amp;#8217;s &lt;a href='http://www.oreillynet.com/ruby/blog/2007/09/7_reasons_i_switched_back_to_p_1.html'&gt;recent post&lt;/a&gt; on CDBaby&amp;#8217;s failed rewrite to Rails.&lt;/p&gt;

&lt;p&gt;Of course, this is fodder for the Rails anti-hype engine; which isn&amp;#8217;t a bad thing, at least when it comes down to having logical, well-reasoned, and realistic discussion about when Rails is and &lt;em&gt;isn&amp;#8217;t&lt;/em&gt; the right platform choice. I tend to think that, for the most part, Derek&amp;#8217;s points center around his own personal tastes vs strong technical reasons &amp;#8211; which is not to say they&amp;#8217;re less important; just less portable.&lt;/p&gt;

&lt;p&gt;On top of the platform choiceâ€¦ to those who are jumping on this and screaming &amp;#8220;Thinking about a rewrite to &lt;strong&gt;Rails&lt;/strong&gt;? Think again!&amp;#8221; I say &amp;#8220;Thinking about a &lt;strong&gt;rewrite&lt;/strong&gt;? Think again!&amp;#8221; &lt;a href='http://chadfowler.com'&gt;Chad&lt;/a&gt; covered &lt;em&gt;those&lt;/em&gt; issues &lt;a href='http://chadfowler.com/the-big-rewrite'&gt;back in December&lt;/a&gt; (read bottom-up), earned after we spilled our own blood and tears on a failed PHP -&amp;gt; Rails rewrite.&lt;/p&gt;

&lt;p&gt;Not to say that a rewrite &lt;em&gt;never&lt;/em&gt; makes sense; just that you&amp;#8217;d better be ready to tackle it.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Lone Star Ruby Conference Starting</title>
   <link href="http://codefluency.com/2007/09/05/lone-star-ruby-conference-starting.html"/>
   <updated>2007-09-05T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/09/05/lone-star-ruby-conference-starting</id>
   <content type="html">&lt;p&gt;So, the &lt;a href='http://lonestarrubyconf.com/'&gt;Lone Star Ruby Conference&lt;/a&gt; starts here in a couple days, with the Charity Workshop getting the ball rolling tomorrow afternoon. I&amp;#8217;ll be doing one of the 30-minute talks (talking about my old stand in, tips and tricks Rails views &amp;#8211; or at least what I can fit into half an hour), and then it&amp;#8217;s two days of near-relaxation listening to other people speak &amp;#8211; and looking for local developers to hire.&lt;/p&gt;

&lt;p&gt;A lot of great people are coming into town, so I&amp;#8217;m really looking forward to the next few days. Hope to see you there (well, here)!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Some of us are getting together to see Wayne&amp;#8217;s World at the Alamo Drafthouse&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(Lake Creek) for the special midnight showing on Friday. If you&amp;#8217;re interested (Austin has a lot to do), look &lt;a href='http://wiki.lonestarrubyconf.com/AfterHours'&gt;here&lt;/a&gt; for more info. What&amp;#8217;s the Alamo Drafthouse? Why, the best movie theater there is, of course!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Off Topic, FiveRuns is Hiring</title>
   <link href="http://codefluency.com/2007/08/29/off-topic-fiveruns-is-hiring.html"/>
   <updated>2007-08-29T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/08/29/off-topic-fiveruns-is-hiring</id>
   <content type="html">&lt;p&gt;Live near Austin, TX? Want to work at a small, Rails-focused company? Not completely put off by the idea of having to work with me on a day-to-day basis? &lt;em&gt;Really, think about that last oneâ€¦&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We&amp;#8217;re gearing up to hire several Rails developers &lt;span&gt;with varying levels of experience&lt;/span&gt; from the local area. If you&amp;#8217;re sincerely passionate about Rails, Ruby, the community that&amp;#8217;s grown up around it, and fit the bill, drop me a line (&lt;em&gt;bruce at fiveruns&lt;/em&gt;).&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Paginator 1.1.0</title>
   <link href="http://codefluency.com/2007/08/12/paginator-1-1-0.html"/>
   <updated>2007-08-12T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/08/12/paginator-1-1-0</id>
   <content type="html">&lt;p&gt;I just released an update of the &lt;a href='http://paginator.rubyforge.org/'&gt;paginator gem&lt;/a&gt;; the full range of Enumerable methods are now available on Paginator and Page instances. This was a long overdue feature &amp;#8211; like many releases, this one was for largely selfish reasons â€¦ not having inject available was really getting on my nerves.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://paginator.rubyforge.org/'&gt;Paginator&lt;/a&gt; is a simple library that can be used to add pagination to any Ruby &lt;span&gt;not just Rails&lt;/span&gt; application. The original release notice is &lt;a href='/2006/10/24/paginator-released.html'&gt;here&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Forward and Delegate, A Simple Pattern</title>
   <link href="http://codefluency.com/2007/08/11/forward-and-delegate-a-simple-pattern.html"/>
   <updated>2007-08-11T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/08/11/forward-and-delegate-a-simple-pattern</id>
   <content type="html">&lt;p&gt;Here&amp;#8217;s a simple example showing how to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Forward all missing method invocations on to some object&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Dynamically add delegation of that method to that object for future invocation.&lt;/p&gt;

&lt;p&gt;def method&lt;em&gt;missing(meth, &lt;em&gt;args, &amp;amp;block) #:nodoc: returning @object.&lt;strong&gt;send&lt;/strong&gt;(meth,&lt;/em&gt;args, &amp;amp;block) do self.class.class&lt;/em&gt;eval %{delegate :#{meth}, :to =&amp;gt; :@object} end end&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note this example uses two bits from ActiveSupport:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;returning to avoid explicitly setting a temporary variable for the return value (stylistic choice of mine)&lt;/li&gt;

&lt;li&gt;delegate to generate the delegation code (because it&amp;#8217;s dull to do it yourself)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Using Warehouse</title>
   <link href="http://codefluency.com/2007/08/09/using-warehouse.html"/>
   <updated>2007-08-09T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/08/09/using-warehouse</id>
   <content type="html">&lt;p&gt;A few weeks ago, the guys at &lt;a href='http://activereload.net'&gt;ActiveReload&lt;/a&gt; released &lt;a href='http://warehouseapp.com/'&gt;Warehouse&lt;/a&gt;, a web- based Subversion repository management and browsing tool. You may know ActiveReload for the &lt;a href='http://lighthouseapp.com/'&gt;Lighthouse&lt;/a&gt; bug tracking system, which has been out for several months, or from the fact it&amp;#8217;s a small company made up of &lt;a href='http://techno-weenie.net/'&gt;Rick Olson&lt;/a&gt; (rails-core member and prolific purveyor of plugins) and &lt;a href='http://pastie.caboo.se/'&gt;Josh Goebel&lt;/a&gt; (who generously gave us &lt;a href='http://pastie.caboo.se'&gt;Pastie&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;I love both of these tools, for several reasons. First off, they&amp;#8217;ve been built with integration in mind. They both have APIs (especially Lighthouse), and hooking them into tools like &lt;a href='http://campfirenow.com'&gt;Campfire&lt;/a&gt; is trivial (and&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>My Thanks; An Aside</title>
   <link href="http://codefluency.com/2007/08/07/my-thanks-an-aside.html"/>
   <updated>2007-08-07T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/08/07/my-thanks-an-aside</id>
   <content type="html">&lt;p&gt;I&amp;#8217;d like to offer my sincere thanks to those of you who have contacted me this week offering your condolences for the sudden and unexpected death of my youngest brother, Tristan.&lt;/p&gt;

&lt;p&gt;As you might imagine, this came as an unbelievably hard blow to my family &amp;#8211; but the outpouring of support received the last few days has helped me more than I can say (in the very least, offering a bit of human interaction).&lt;/p&gt;

&lt;p&gt;My very sincere thanks to all of you. Don&amp;#8217;t take anything for granted.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Bruce&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;PS. Now, back to the regularly scheduled &lt;span&gt;and considerably more cheery&lt;/span&gt; programâ€¦&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Finding Stale Tables</title>
   <link href="http://codefluency.com/2007/08/01/finding-stale-tables.html"/>
   <updated>2007-08-01T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/08/01/finding-stale-tables</id>
   <content type="html">&lt;p&gt;Here&amp;#8217;s a simple rake task to help you find unused db tables lying around in your application. Keep in mind it&amp;#8217;s just a guess, showing any table that doesn&amp;#8217;t constantize; if you&amp;#8217;re using habtm tables, unconventional table names, or other such things, expect to see them show up as well.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namespace :app do
  namespace :stale do
    task :tables =&amp;gt; :environment do
      tables = ActiveRecord::Base.connection.tables.reject do |table|
        table.classify.camelize.constantize rescue nil
      end - %w(schema_info)
      if tables.any?
        $stderr.puts &amp;quot;The following may be stale:&amp;quot;
        puts tables
      else
        $stderr.puts &amp;quot;No stale tables found&amp;quot;
      end
    end
  end
end&lt;/code&gt;&lt;/pre&gt;</content>
 </entry>
 
 <entry>
   <title>acts_as_texan :bruce</title>
   <link href="http://codefluency.com/2007/07/18/acts_as_texan-bruce.html"/>
   <updated>2007-07-18T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/07/18/acts_as_texan-bruce</id>
   <content type="html">&lt;p&gt;Okay, so I totally stole that from &lt;a href='http://therealadam.com/'&gt;Adam Keys&lt;/a&gt; and the crowd up at &lt;a href='http://dallasrb.stikipad.com'&gt;Dallas.rb&lt;/a&gt; &amp;#8211; but it&amp;#8217;s true â€¦ I&amp;#8217;ve just &amp;#8220;finished&amp;#8221; my move to &lt;a href='http://en.wikipedia.org/wiki/Austin,_Texas'&gt;Austin, TX&lt;/a&gt;, finally ending months of planning, hair pulling, and various other acts of torture that revolve around getting a family with two small children across several states.&lt;/p&gt;

&lt;p&gt;By &amp;#8220;finished,&amp;#8221; of course I really mean I&amp;#8217;m sitting in a hotel awaiting keys to the new house and the arrival of everything I own &amp;#8211; but you get the point. I&amp;#8217;m here, at least in body, and trying to come to grips with living in a completely new place.&lt;/p&gt;

&lt;p&gt;So, if you&amp;#8217;re around Austin, drop me a note; I&amp;#8217;m lucky in that I already know a &lt;a href='http://www.vernix.org/marcel'&gt;few&lt;/a&gt; &lt;a href='http://damonclinkscales.com/'&gt;people&lt;/a&gt;, but development is a social pursuit â€¦ so bring on the contacts :-)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Pownce, off the cuff</title>
   <link href="http://codefluency.com/2007/07/06/pownce-off-the-cuff.html"/>
   <updated>2007-07-06T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/07/06/pownce-off-the-cuff</id>
   <content type="html">&lt;p&gt;A few days ago I started to play around with &lt;a href='http://pownce.com'&gt;Pownce&lt;/a&gt;, a recent new player in the ever expanding social webapp scene, roughly similar to Twitter.&lt;/p&gt;

&lt;p&gt;I was a bit sceptical starting out, for three reasons.&lt;/p&gt;

&lt;p&gt;1. The word &amp;#8220;social&amp;#8221; can easily mean &amp;#8220;recycled crap&amp;#8221; at this point in the game&lt;/p&gt;

&lt;p&gt;2. It&amp;#8217;s hard for me to think of Kevin Rose (part of the Pownce team) without thinking of the huge volume of vapid script kiddies that hang on his every word, or the general quality of Digg comments (not directly his fault, of course)&lt;/p&gt;

&lt;p&gt;3. To be truthful, it&amp;#8217;s built on &lt;a href='http://djangoproject.com'&gt;Django&lt;/a&gt;, and as an ex-Pythonista and passionate Rubyist we know &lt;a href='http://rubyonrails.org'&gt;what framework I prefer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, on to reality and a few days laterâ€¦&lt;/p&gt;

&lt;p&gt;The featureset is pretty compelling. With finer grained dissemination controls, a first class &amp;#8220;reply&amp;#8221; feature, and the obvious benefits of having message types like Event and File, Pownce is already far less of a &amp;#8220;toy&amp;#8221; application than Twitter feels after several months of regular use. The fact Pownce offers a Flickr-like pro subscription is also nice, since it shows some forethought occurred as to monetization &amp;#8211; which will hopefully stave off some scalability issues through generous use of hardware/staffing as well as limit advertising.&lt;/p&gt;

&lt;p&gt;The design, in my opinion, is certainly better than Twitter&amp;#8217;s. Twitter&amp;#8217;s tiny hairline-bordered sidebar with the kitschy palette of friends is habitually annoying and not particularly intuitive, whereas Pownce&amp;#8217;s interface, while certainly not perfect, seems reasonably put together.&lt;/p&gt;

&lt;p&gt;Of course everything isn&amp;#8217;t rosy; I ran into a few small issues, including it inexplicably not being able to handle PNG profile images &amp;#8211; but it seems to be pretty stable for what&amp;#8217;s most certainly a newly released application. I&amp;#8217;d like to see some further development &amp;#8211; like a published and open API with integration with other services, but as a developer I understand these things take time.&lt;/p&gt;

&lt;p&gt;So, to wrap up, let&amp;#8217;s address my initial concerns:&lt;/p&gt;

&lt;p&gt;1. On social sites: although these are commonly used elements on social sites, this seems to integrate them in what feels like a very cohesive interface, and keeps things simple without making them too stupid.&lt;/p&gt;

&lt;p&gt;2. On Kevin: he&amp;#8217;s just a part of a team, and thanks to the friend controls, I can insulate myself from the aforementioned hangers-on and comment &lt;span&gt;message&lt;/span&gt; trolls.&lt;/p&gt;

&lt;p&gt;3. On Django: liking or not liking an application for the underlying framework is pretty stupid; understanding when you&amp;#8217;re the developer and when you&amp;#8217;re the user is smart, so I&amp;#8217;ll step back and see Pownce for what it is; a pretty clever use of a framework I don&amp;#8217;t prefer but can appreciate.&lt;/p&gt;

&lt;p&gt;You can find me at Twitter &lt;a href='http://twitter.com/wbruce'&gt;here&lt;/a&gt; and Pownce &lt;a href='http://pownce.com/bruce'&gt;here&lt;/a&gt;. If you&amp;#8217;d like a Pownce invitation, contact me &amp;#8211; there&amp;#8217;s a chance I have one handy.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Locking down The Move</title>
   <link href="http://codefluency.com/2007/06/21/locking-down-the-move.html"/>
   <updated>2007-06-21T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/06/21/locking-down-the-move</id>
   <content type="html">&lt;p&gt;So, after a couple months of trying to figure it out, it looks as if my move to the Austin area is finally starting to take shape.&lt;/p&gt;

&lt;p&gt;A week or so into July, we start the exciting trip southeast &amp;#8211; this time trading in the normal drive through thrill-a-minute &lt;a href='http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;q=longmont,+co+to+austin,+tx&amp;amp;sll'&gt;Kansas&lt;/a&gt; for the post- apocolypsesque terrain of &lt;a href='http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;q=from%3A+longmont,+co+to%3A+ama'&gt;West Texas&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ve secured a nice 4 bedroom house near &lt;a href='http://fiveruns.com'&gt;the office&lt;/a&gt;, several &lt;a href='http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;q=coffeeshop+near+cedar+park,+tx'&gt;coffeeshops&lt;/a&gt;, and Lake Travis, thereby meeting my laziness, caffeination, and occasional-periods-of-sunshine needs.&lt;/p&gt;

&lt;h1 id='rillotxto3asanangelotxto3aaustintxsll36776292104412689sspn'&gt;rillo,+tx+to%3A+san+angelo,+tx+to%3A+austin,+tx&amp;amp;sll=36.776292,-104.412689&amp;amp;sspn&lt;/h1&gt;

&lt;p&gt;&amp;amp;ie=UTF8&amp;amp;z=12&amp;amp;om=1&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Best Garlic Press</title>
   <link href="http://codefluency.com/2007/06/04/best-garlic-press.html"/>
   <updated>2007-06-04T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/06/04/best-garlic-press</id>
   <content type="html">&lt;p&gt;I love garlic, and so does my wife (which I suppose is lucky for both of us), and together we go through a vast amount of it every month. For the past few years I&amp;#8217;ve been hand-mincing my garlic with a chef&amp;#8217;s knife or santoku because of mixed results I&amp;#8217;ve gotten from number of garlic presses &amp;#8211; hard to clean, hard to use, not durable, etc.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m a fair hand with a knife, so mincing manually isn&amp;#8217;t a huge problem, but due to the volume of garlic I have to process (since we eat largely mediterranean meals) it got a bit tiring.&lt;/p&gt;

&lt;p&gt;Soâ€¦ I decided to give garlic presses another try, purchasing a &lt;a href='http://www.amazon.com/Rosle-USA-12782-RÃ¶sle-Garlic/dp/B000063Y8F'&gt;RÃ¶sle&lt;/a&gt;. This is by &lt;em&gt;far&lt;/em&gt; the best press I&amp;#8217;ve ever used, and I highly recommend it to fellow garlic eaters.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>folder_for, A Controller DSL</title>
   <link href="http://codefluency.com/2007/06/02/folder_for-a-controller-dsl.html"/>
   <updated>2007-06-02T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/06/02/folder_for-a-controller-dsl</id>
   <content type="html">&lt;p&gt;Over the last year or so, I&amp;#8217;ve spoken at a number of meetings and conferences (including &lt;a href='http://pragmaticstudio.com/therailsedge/'&gt;The Rails Edge&lt;/a&gt; and &lt;a href='http://railsconf.org'&gt;RailsConf&lt;/a&gt;) about view layer concerns, and on several occasions have given a folder interface example when speaking about controller domain specific languages. Since I&amp;#8217;ve received several requests, here&amp;#8217;s some information on the example.&lt;/p&gt;

&lt;p&gt;First of all, here&amp;#8217;s the source (&lt;em&gt;Sorry, this file has gone missing since this article was written&lt;/em&gt;).&lt;/p&gt;

&lt;h3 id='the_slimy_used_car_salesman_app_beta'&gt;The Slimy Used Car Salesman App (beta)&lt;/h3&gt;

&lt;p&gt;For our example, let&amp;#8217;s pretend for a moment that we&amp;#8217;re developing an application that will serve as a local listing of used cars for sale. After talking with the client, we&amp;#8217;ve determined that in makes sense that a folder- style interface to be used on a few pages, most notably when viewing the information for a specific car. Folder interfaces aren&amp;#8217;t hard, but they can be tedious &amp;#8211; so we&amp;#8217;re going to employ a DSL so we can easily create them with a minimum of hassle. We could do this purely in the view layer, but we&amp;#8217;d like the flexibility to add custom code for individual tabs in the controller, and don&amp;#8217;t want to have to remember a series of helpers that we&amp;#8217;ll need in views.&lt;/p&gt;

&lt;p&gt;Using this plugin, we can do something like the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  class CarsController &amp;lt; ActionController::Base
    # ...
    folder_for :show do
      tab &amp;quot;General Information&amp;quot; do
        @score = current_user.score_for_car(@car)
      end
      tab &amp;quot;History&amp;quot;
      tab &amp;quot;Photos&amp;quot;
    end
    # ...
  end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What we&amp;#8217;re doing here is defining a folder to be displayed for the show action, with 3 tabs. On the first tab, General Information, we&amp;#8217;d also like to calculate a score for the car, based on the currently signed-in user&amp;#8217;s preferences.&lt;/p&gt;

&lt;p&gt;So, what happens now?&lt;/p&gt;

&lt;p&gt;We have to define the content of each tab. In the past, we would have one view template to work with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  cars/
    show.html.erb&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and would have had to manually render the partial for the currently selected tab, based on a parameter, and handled setting the default tab, not to mention the mechanics of switching tabs. Perhaps, if we were exceedingly lazy, we would have just had a big, ugly if, elsif statement in our template as well, conditionally rendering content for tabs. Ick.&lt;/p&gt;

&lt;p&gt;How this works now, by convention, is that we break up our templates/partials like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  cars/
    show.html.erb
    show/
      _general_information.html.erb
      _history.html.erb
      _photos.html.erb&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and our &lt;code&gt;show.html.erb&lt;/code&gt; might look something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  &amp;lt;h1&amp;gt;&amp;lt;%= @car.title %&amp;gt;&amp;lt;/h1&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;%= @car.summary %&amp;gt;&amp;lt;/p&amp;gt;
  &amp;lt;%= folder %&amp;gt;
  &amp;lt;p&amp;gt;Some information below the folder...&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The folder helper essentially says &amp;#8220;put the folder here,&amp;#8221; and the content that&amp;#8217;s inserted consists of:&lt;/p&gt;

&lt;p&gt;* A set of easily-styleable, functional tabs (a &lt;code&gt;ul&lt;/code&gt;), with the current tab selected (through a CSS class)&lt;/p&gt;

&lt;p&gt;* The content from the appropriate tab partial inserted in a div within the folder&lt;/p&gt;

&lt;p&gt;The concerns of the folder system &amp;#8211; the fact that it involves the use of &lt;code&gt;params[:tab]&lt;/code&gt;, the first tab is the default, and links need to be generated to switch from tab to tab &amp;#8211; is not something you need to care about; these are mundane details that this level of abstraction allows you to ignore.&lt;/p&gt;

&lt;p&gt;Another thing you may have noticed is the fact that &lt;code&gt;car&lt;/code&gt; is available for use &amp;#8211; both within the tab definitions in the controller (where, in our example, we set &lt;code&gt;score&lt;/code&gt;) and in views. How is this handled? Using REST conventions (the fact we&amp;#8217;re doing this within &lt;code&gt;CarsController&lt;/code&gt;), the folder knows that there should be a Car model, and that it should set @car using &lt;code&gt;Car.find(params[:id]&lt;/code&gt;). Once again, a mundane detail that remains beneath your notice.&lt;/p&gt;

&lt;h3 id='caveat_emptor'&gt;Caveat Emptor&lt;/h3&gt;

&lt;p&gt;It&amp;#8217;s important that I point out a few details on the limitations of this plugin &amp;#8211; and very unapologetically, since it&amp;#8217;s an example and not a release.&lt;/p&gt;

&lt;p&gt;1. Cases where a record need not be queried (ie, we don&amp;#8217;t need @car), or multiple records are needed (ie, if we were setting up a folder on index) are not handled by this implementation &amp;#8211; but could easily if an options hash argument was handled by &lt;code&gt;folder_for&lt;/code&gt;. I sacrificed completeness for &lt;span&gt;some semblance of&lt;/span&gt; clarity.&lt;/p&gt;

&lt;p&gt;2. There is no support for multiple folders-per-view (though there is support for multiple folders per controller), since I think that&amp;#8217;s a fairly stupid interface decision, so adding support for it is stupid, too.&lt;/p&gt;

&lt;p&gt;3. The code may or may not work with Rails versions prior to support for .html.erb template extensions (ie, the old .rhtml days)&lt;/p&gt;

&lt;p&gt;4. There&amp;#8217;s probably a number of other limitations; feel free to extend as you see fit.&lt;/p&gt;

&lt;h3 id='in_my_defense'&gt;In My Defense&lt;/h3&gt;

&lt;p&gt;There are likely several of you reading this that are disturbed to see a &lt;em&gt;folder&lt;/em&gt; reference within a &lt;em&gt;controller&lt;/em&gt;, as this amounts to level type of MVC &amp;#8220;separation of concerns&amp;#8221; blasphemy in your very strict, very well-worn book of religious morals.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m here to tell you it&amp;#8217;s okay, and you&amp;#8217;ll recover in time.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s keep in mind here that the MVC separation of concerns, while a great rule of thumb &amp;#8211; is just that &amp;#8211; and is not an ivory tower to be left unassailed in times of dire need. At times, it makes sense to allow abstractions to cross these boundaries for the sake of reducing our own overhead, and in the cause of developing your own app-wide domain specific language &amp;#8211; something, that in my book, is the principal sign of a good Rails developer (for what it&amp;#8217;s worth).&lt;/p&gt;

&lt;h3 id='malleable_fun_or_the_moral_of_the_story'&gt;Malleable Fun (or, the Moral of the Story)&lt;/h3&gt;

&lt;p&gt;An important thing to remember when using Rails is that it sits on top of Ruby &amp;#8211; something that&amp;#8217;s so obvious that it&amp;#8217;s moronic, but nonetheless something people seem to forget.&lt;/p&gt;

&lt;p&gt;What this means is that you have this amazingly dynamic, expressive language at your fingertips, and you&amp;#8217;re free to extemporize as you see fit, creating your own mini languages in a flash.&lt;/p&gt;

&lt;p&gt;Think something sucks to do every time manually? Don&amp;#8217;t. Write code to do it, or write code to write code to do it. You&amp;#8217;re language crappiness quotient is remarkably low &amp;#8211; are you taking advantage of that, or have you fallen into old patterns of suck-it-up-and-bear-it self-pity?&lt;/p&gt;

&lt;p&gt;And that&amp;#8217;s the Public Service Announcement of the day, thank you.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Donate through Pragmatic Studio</title>
   <link href="http://codefluency.com/2007/05/18/donate-through-pragmatic-studio.html"/>
   <updated>2007-05-18T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/05/18/donate-through-pragmatic-studio</id>
   <content type="html">&lt;p&gt;This morning at the RailsConf welcome talk, &lt;a href='http://chadfowler.com'&gt;Chad&lt;/a&gt; gave an impassioned speech urging conference attendees to help &amp;#8220;change the world&amp;#8221; by donating to charity through &lt;a href='http://pragmaticstudio.com/'&gt;Pragmatic Studio&lt;/a&gt;. Pragmatic Studio, known for their excellent commercial tutorials, raised over $10k through donations by attendees of their Guidebook yesterday.&lt;/p&gt;

&lt;p&gt;This is something anyone can participate in, whether you have the opportunity to attend &lt;a href='http://railsconf.org'&gt;RailsConf&lt;/a&gt; or not. How much money can the community, as a whole, raise?&lt;/p&gt;

&lt;p&gt;Donate at http://pragmaticstudio.com/donate/&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>fast_forward 1.0.0</title>
   <link href="http://codefluency.com/2007/05/14/fast_forward-1-0-0.html"/>
   <updated>2007-05-14T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/05/14/fast_forward-1-0-0</id>
   <content type="html">&lt;p&gt;Just a note that I recently released a new gem, &lt;code&gt;fast_forward&lt;/code&gt;, which adds support for delegation of all missing methods to another object, and does a bit of dynamic method generation to reduce overhead for subsequent calls. The API looks something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  class Foo
    def some_foo_method
      &amp;quot;Hello&amp;quot;
    end
  end
  class Bar
    fast_forward_to :@foo
    def initialize
      @foo = Foo.new
    end
  end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(Note I could have used &lt;code&gt;fast_forward_to :foo&lt;/code&gt; if there was an &lt;code&gt;attr_reader&lt;/code&gt; for it)&lt;/p&gt;

&lt;p&gt;Now, if I create a Bar instance, I can call &lt;code&gt;Foo#some_foo_method&lt;/code&gt; transparently using &lt;code&gt;Bar#some_foo_method&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  bar = Bar.new
  bar.some_foo_method
  =&amp;gt; &amp;quot;Hello&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What&amp;#8217;s cool with this setup is the fact that methods are added automatically to the delegating object when they&amp;#8217;re invoked for the first time &amp;#8211; future invocations don&amp;#8217;t need to check up the object hierarchy and resort to &lt;code&gt;method_missing&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  bar = Bar.new
  bar.respond_to?(:some_foo_method)
  =&amp;gt; false
  bar.some_foo_method
  =&amp;gt; &amp;quot;Hello&amp;quot;
  bar.respond_to?(:some_foo_method)
  =&amp;gt; true&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;fast_forward&lt;/code&gt; is a small library &amp;#8211; but the concepts rolled into it have been pretty handy for me in recent projects.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>An ï£¿tv Aside</title>
   <link href="http://codefluency.com/2007/04/20/an-tv-aside.html"/>
   <updated>2007-04-20T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/04/20/an-tv-aside</id>
   <content type="html">&lt;p&gt;I love my ï£¿tv, but here&amp;#8217;s a tip: use the Photo screensaver option very carefully.&lt;/p&gt;

&lt;p&gt;Recently, when I was in Texas, I took a day trip out to the graveyard where some of my family is buried (4-5 generations back), and took a few pictures for relatives.&lt;/p&gt;

&lt;p&gt;Seeing the gravestone of your Great-Great-Great Grandfather float by (though very prettily) in the midst of a particularly rockin&amp;#8217; song &lt;em&gt;totally&lt;/em&gt; kills the mood, I promise.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Another Day, Another Language</title>
   <link href="http://codefluency.com/2007/04/20/another-day-another-language.html"/>
   <updated>2007-04-20T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/04/20/another-day-another-language</id>
   <content type="html">&lt;p&gt;The smart folks over at Pragmatic Programmers have done it yet againâ€¦ I&amp;#8217;ve bought another book from them; this time it&amp;#8217;s &lt;a href='http://pragmaticprogrammer.com/titles/jaerlang/index.html'&gt;Programming Erlang&lt;/a&gt; in the wonderful Beta Book format &amp;#8211; how wonderful is it that we developers, mostly an impatient lot to begin with, now don&amp;#8217;t even have to wait for a book to be published to start reading?.&lt;/p&gt;

&lt;p&gt;Back a few years ago (2002, it seems), I took part in the &lt;a href='http://www.pragmaticprogrammer.com/loty/'&gt;Language of the Year&lt;/a&gt; project, and it really changed my feelings about language learning. Someone that had always been interested in languages, be they natural or â€¦ unnatural, I&amp;#8217;d already been bouncing around from one programming language to another, but I had this slightly erking feeling that it was a &lt;em&gt;bad idea&lt;/em&gt; and that it made me a &lt;em&gt;bad developer&lt;/em&gt;. After all, couldn&amp;#8217;t I just &lt;em&gt;stick&lt;/em&gt; with anything? Was I destined to be a mere dilettante, completely without &amp;#8220;professional&amp;#8221; focus?&lt;/p&gt;

&lt;p&gt;After LOTY, I felt completely vindicated. Through the experience, I came to fully appreciate the reason I love to learn new languages, and how valuable allowing myself to try them out can be. It&amp;#8217;s made me a much better developer than if I had just put my head down and let Ruby fill my entire universe &amp;#8211; what a shame it would have been without Haskell, Erlang, Smalltalk, OCaml, Io, Lua, Self, et al to help me see the different approaches, new possibilities, and beautiful variations in technique that I&amp;#8217;ve been able to incorporate into my problem solving process, code, and outlook!&lt;/p&gt;

&lt;p&gt;So, it&amp;#8217;s time to revisit Erlang for a bit (along with several others I&amp;#8217;ve &lt;a href='http://vernix.org/'&gt;spoken to&lt;/a&gt; &lt;a href='http://chadfowler.com'&gt;recently&lt;/a&gt; and &lt;a href='http://pragdave.pragprog.com/pragdave/2007/04/a_first_erlang_.html'&gt;read&lt;/a&gt;), and nothing makes me more happy at this moment than finding the perfect book to help.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>iStalkr</title>
   <link href="http://codefluency.com/2007/04/02/istalkr.html"/>
   <updated>2007-04-02T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/04/02/istalkr</id>
   <content type="html">&lt;p&gt;An interesting web application that recently popped up into beta is &lt;a href='http://istalkr.com'&gt;iStalkr&lt;/a&gt;, a &amp;#8220;social feed aggregator&amp;#8221; which allows you to add your RSS feeds to your profile (ie, for me that would be this blog, twitter, flickr, last.fm, delicious, and others), and follow your friends&amp;#8217; without the need for manual intervention (since they manage their own lists). Shareable, personal aggregation, I suppose.&lt;/p&gt;

&lt;p&gt;Has anyone seen a similar concept? I think it&amp;#8217;s pretty neat.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Hotkey Plugin</title>
   <link href="http://codefluency.com/2007/03/27/hotkey-plugin-update.html"/>
   <updated>2007-03-27T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/03/27/hotkey-plugin-update</id>
   <content type="html">&lt;p&gt;Rails Plugin Name RubyForge Project&lt;/p&gt;

&lt;p&gt;hotkey&lt;/p&gt;

&lt;p&gt;&lt;a href='http://github.com/bruce/hotkey'&gt;hotkey&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rails plugin to allow javascript-based hotkey assignments to remote and client-side actions.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Badger</title>
   <link href="http://codefluency.com/2007/03/27/badger.html"/>
   <updated>2007-03-27T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/03/27/badger</id>
   <content type="html">&lt;p&gt;Current Version Gem Name Documentation&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;li&gt;0&lt;/li&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;badger&lt;/p&gt;

&lt;p&gt;&lt;a href='http://codefluency.rubyforge.org/badger/'&gt;View&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A library used to generate badge sheets for events, given a PDF template and data for the badges. Uses pdftk.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>With FiveRuns</title>
   <link href="http://codefluency.com/2007/03/27/with-fiveruns.html"/>
   <updated>2007-03-27T00:00:00-07:00</updated>
   <id>http://codefluency.com/2007/03/27/with-fiveruns</id>
   <content type="html">&lt;p&gt;This is a bit overdue, but I&amp;#8217;ve been remiss in posting the last month or so (has it been that obvious?)&lt;/p&gt;

&lt;p&gt;I just wanted to mention, off the cuff, that I recently signed with &lt;a href='http://fiveruns.com'&gt;FiveRuns&lt;/a&gt;, an enthusiastic supporter of the Rails community working in the systems management space, and based out of Austin, TX. I&amp;#8217;m lucky enough to be joined at FiveRuns by the venerable &lt;a href='http://vernix.org/marcel'&gt;Marcel Molina, Jr.&lt;/a&gt; of rails-core fame, and working with a talented, visionary group of developers (not to mention all the other smart folks making things tick at the office).&lt;/p&gt;

&lt;p&gt;So, I&amp;#8217;ve got my nose to the grindstone, as it were &amp;#8211; deep in new code, fresh APIs, a unfamiliar domain, and some really exciting work &amp;#8211; but I&amp;#8217;ll try to catch up, I promise.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Germany in September</title>
   <link href="http://codefluency.com/2007/02/24/germany-in-september...html"/>
   <updated>2007-02-24T00:00:00-08:00</updated>
   <id>http://codefluency.com/2007/02/24/germany-in-september..</id>
   <content type="html">&lt;p&gt;So, I&amp;#8217;ll definitely be attending &lt;a href='http://conferences.oreillynet.com/railseurope/'&gt;RailsConf Europe&lt;/a&gt; this year (in addition to a slew of other conferences), and I&amp;#8217;ve decided that this is the perfect opportunity to look around. I&amp;#8217;ve never been to Germany, though it&amp;#8217;s always been on my list.&lt;/p&gt;

&lt;p&gt;What makes it even better is that I&amp;#8217;ll be bringing along my wife, Melissa, for a few days away from our two &lt;span&gt;lovely, but exhausting&lt;/span&gt; sons. Melissa&amp;#8217;s father was adopted from Berlin as a child, so she&amp;#8217;s always had an interest in visiting.&lt;/p&gt;

&lt;p&gt;So, here&amp;#8217;s the part where having this site really has some advantages. Ideas.&lt;/p&gt;

&lt;p&gt;Given a few extra days (let&amp;#8217;s say a week total, conference and vacation; I can only saddle my mother-in-law with two small children for so long) and a wife that deserves a quiet, romantic vacation, where would you go? I&amp;#8217;ve, of course, heard S. Germany (and &lt;em&gt;Romantische Straße&lt;/em&gt;), but is there somewhere specific that really pops out in your mind? A few nights in a small village, some area that &lt;em&gt;just must&lt;/em&gt; be seen?&lt;/p&gt;

&lt;p&gt;Travel by train preferred, but renting a car is an option. Suggestions by real, live Germans (!!!) a bonus.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Gem List</title>
   <link href="http://codefluency.com/2007/02/20/gem-list.html"/>
   <updated>2007-02-20T00:00:00-08:00</updated>
   <id>http://codefluency.com/2007/02/20/gem-list</id>
   <content type="html">&lt;p&gt;Since &lt;a href='http://clarkware.com/cgi/blosxom/2007/02/10#GemSurvey'&gt;Mike&lt;/a&gt; and &lt;a href='http://chadfowler.com/2007/2/11/show-us-your-gems'&gt;Chad&lt;/a&gt; have already posted theirs, here&amp;#8217;s my &lt;code&gt;gem list&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;actionmailer (1.3.1, 1.2.5, 1.2.3, 1.2.1, 1.0.1)
actionpack (1.13.1, 1.12.5, 1.12.3, 1.12.1, 1.9.1)
actionwebservice (1.2.1, 1.1.6, 1.1.4, 1.1.2, 0.8.1)
activerecord (1.15.1, 1.14.4, 1.14.3, 1.14.2, 1.11.1)
activesupport (1.4.0, 1.3.1, 1.1.1)
audioscrobbler (0.0.1)
badger (1.0.0)
barcode (0.2)
BlueCloth (1.0.0)
builder (2.0.0)
capistrano (1.2.0, 1.1.0)
capistrano-ext (1.1.0, 1.0.1)
cgi_multipart_eof_fix (2.0.2)
cocoa_dialog (0.0.2)
color-tools (1.3.0)
cooloptions (1.1.0)
daemons (1.0.4, 1.0.2, 0.4.4)
dhaka (0.0.6, 0.0.5)
diff-lcs (1.1.2)
fastercsv (1.0.0)
fastthread (0.6.2)
fcgi (0.8.7, 0.8.6.1)
gem_plugin (0.2.2, 0.2.1)
greenbar (1.0.1, 0.2.1)
gruff (0.2.8, 0.2.4, 0.1.2)
hoe (1.1.6, 1.1.2)
hpricot (0.4)
instiki (0.10.2)
json (0.4.2)
keybox (1.0.0)
keyword_search (1.0.2)
libxml-ruby (0.3.8)
madeleine (0.7.3, 0.7.1)
mailfactory (1.2.3)
memcache-client (1.2.0, 1.0.3)
mime-types (1.15)
mongrel (1.0.1, 0.3.13.4, 0.3.13.3, 0.3.12.4)
mongrel_cluster (0.2.1, 0.2.0)
mysql (2.7)
needle (1.3.0)
net-sftp (1.1.0)
net-ssh (1.0.10, 1.0.9, 1.0.8)
open4 (0.9.1)
paginator (1.0.8, 1.0.7, 1.0.5, 1.0.0)
pdf-writer (1.1.3)
peggy (0.1.0)
piston (1.2.0, 1.1.1)
radiant (0.5.2)
radius (0.5.1)
rails (1.2.1, 1.1.6, 1.1.4, 1.1.2, 0.13.1)
rails_gem_plugin_shim (1.0.0)
rake (0.7.1)
rcov (0.7.0.1)
RedCloth (3.0.4, 3.0.3)
rmagick (1.14.1, 1.11.1, 1.10.1)
rspec (0.6.4, 0.5.13)
rubyforge (0.3.2, 0.3.0)
rubygems-update (0.9.0)
rubyosa (0.1.0)
rubyzip (0.9.1, 0.5.8)
ruport (0.6.1)
scruffy (0.2.2)
sources (0.0.1)
spacesuit (1.2.0)
syntax (1.0.0)
tattle (1.0.3, 1.0.2, 1.0.0)
termios (0.9.4)
Text (1.1.0)
transaction-simple (1.3.0)
twfy (1.0.0)
twitter (0.0.2)
tzinfo (0.3.2, 0.3.1)
xhtmldiff (1.0.0)
ZenTest (3.4.1, 3.2.0)&lt;/code&gt;&lt;/pre&gt;</content>
 </entry>
 
 <entry>
   <title>After Rails Edge Reston</title>
   <link href="http://codefluency.com/2007/01/29/after-rails-edge-reston.html"/>
   <updated>2007-01-29T00:00:00-08:00</updated>
   <id>http://codefluency.com/2007/01/29/after-rails-edge-reston</id>
   <content type="html">&lt;p&gt;Well, one more &lt;a href='http://therailsedge.com'&gt;Rails Edge conference&lt;/a&gt; came to a close yesterday. This was an especially fun conference, with a lot of great people and some really interesting new material by my fellow speakers. The feedback has been excellent, really hammering home what&amp;#8217;s been becoming more and more obvious &amp;#8211; this conference format &lt;em&gt;really works&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So, my thanks to those of you who made the conference such a success &amp;#8211; the attendees!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;After my presentation on Building UI Frameworks, I received a large amount&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;of interest in releasing one of my examples, the folder DSL, as a plugin. I&amp;#8217;ll announce it here in a few days &amp;#8211; after I have a chance to package it appropriately.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Ch-Ch-Ch-Chia!</title>
   <link href="http://codefluency.com/2007/01/17/ch-ch-ch-chia.html"/>
   <updated>2007-01-17T00:00:00-08:00</updated>
   <id>http://codefluency.com/2007/01/17/ch-ch-ch-chia</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve never had long hair. I grew up in a family where haircuts where performed on a nearly flawless bi-weekly schedule, and my service in the Air Force really put the nail in the coffin &amp;#8211; even the &lt;em&gt;thought&lt;/em&gt; of having hair over my ears and down my neck makes me a little crazy, not to mention a bit itchy.&lt;/p&gt;

&lt;p&gt;Regardless, as of today &lt;strong&gt;I am resolved to grow my hair to a minimum length of at least 10 inches&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m not doing this because I&amp;#8217;ve mastered electric guitar and am about to live out my dream of headlining an 80&amp;#8217;s hair band, or because I&amp;#8217;ve given up the trappings of animal enslavement, become a vegan, and plan to live out the rest of my life in a state of blissfully natural, unwashed hippiedom &amp;#8211; in fact, I&amp;#8217;ll continue to shower regularly and enjoy a good steak.&lt;/p&gt;

&lt;p&gt;Rather, I&amp;#8217;ve decided that I&amp;#8217;m going to support a charity called Locks of Love. &lt;a href='http://www.locksoflove.org/'&gt;Locks of Love&lt;/a&gt; is a non-profit organization dedicated to providing financially disadvantaged children suffering from hair loss with hair prosthetics. Common causes of hair loss in children include chemotherapy (read: cancer) along with conditions like &lt;a href='http://en.wikipedia.org/wiki/Alopecia_areata'&gt;alopecia&lt;/a&gt;, an autoimmune disorder.&lt;/p&gt;

&lt;p&gt;Over the last year I&amp;#8217;ve been frequently impressed with the determination of &lt;a href='http://chadfowler.com'&gt;Chad Fowler&lt;/a&gt;, a good friend of mine, to support Locks of Love. If you&amp;#8217;ve had the opportunity to see Chad at conferences, talks, or training sessions recently, you&amp;#8217;ll probably have noticed his hair has been steadily gaining length. He&amp;#8217;s serious about doing this, and it&amp;#8217;s been hard not to be inspired by that kind of selflessness.&lt;/p&gt;

&lt;p&gt;I think this charity is something that&amp;#8217;s really worthwhile to support&amp;#8211;it&amp;#8217;s an opportunity to make a difference in a way a simple financial donation can&amp;#8217;t. I really encourage you to look at Locks of Love, and charities like it, and do what you can.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ll be making regular posts, probably monthly, on my progress. I&amp;#8217;m really curious as to how it will turn out, from both a psychological and aesthetic standpoint. Will I lose my mind? Will my &lt;em&gt;extremely&lt;/em&gt; thick, wavy hair doom me to some horrible caucasian afro? Stay tuned. Regular updates, including &lt;em&gt;hair raising&lt;/em&gt; photos to come over the next several months.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>KeywordSearch Released</title>
   <link href="http://codefluency.com/2007/01/09/keywordsearch-released.html"/>
   <updated>2007-01-09T00:00:00-08:00</updated>
   <id>http://codefluency.com/2007/01/09/keywordsearch-released</id>
   <content type="html">&lt;h3 id='in_the_wild'&gt;In the wild&lt;/h3&gt;

&lt;p&gt;Along with archival and a good UI, the thing that really strikes me about gmail&amp;#8211;what makes it really useful&amp;#8211;is the search feature. Obviously we expect good search capabilities in anything Google puts out, but the keyword-based searching is extra handy. I find myself doing things like this pretty often:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  presentation &amp;quot;rails edge&amp;quot; from:chad after:2006/08/16&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This searches for emails in exactly as it reads; it will return emails from &lt;em&gt;chad&lt;/em&gt; containing the words &lt;em&gt;presentation&lt;/em&gt; and &lt;em&gt;rails edge&lt;/em&gt; that were sent after the &lt;em&gt;16th of August, 2006&lt;/em&gt;. Niftyâ€¦ and quick.&lt;/p&gt;

&lt;p&gt;Google has developed a list of keywords, and in some cases, expected values for those keywords, that are translated into an advanced query. This is an interesting alternative to a large and unwieldy advanced search form.&lt;/p&gt;

&lt;p&gt;Over the last couple of weeks I&amp;#8217;ve become increasingly interested in adding a similar flexible, easy-to-extend search feature to a Rails application that I&amp;#8217;m developing. I&amp;#8217;ve wanted to play around with &lt;a href='http://dhaka.rubyforge.org/'&gt;Dhaka&lt;/a&gt; since it came out, and this presented the perfect opportunity.&lt;/p&gt;

&lt;h3 id='how_it_works'&gt;How it works&lt;/h3&gt;

&lt;p&gt;The library is generic&amp;#8211;it&amp;#8217;s not Rails-specific by any means&amp;#8211; so you could use it for any Ruby project, but for the purposes of this example, let&amp;#8217;s go ahead and put together a controller example.&lt;/p&gt;

&lt;p&gt;As you might imagine, installation is as easy as:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo gem install keyword_search -y&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now let&amp;#8217;s require it. In Rails, this means putting the following in your environment.rb:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require &amp;#39;keyword_search&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For the example, let&amp;#8217;s duplicate he concept of searching for messages, in messages&lt;em&gt;controller.rb. Let&amp;#8217;s work inside an index action (or search, if you prefer), starting out by defining a couple variables we&amp;#8217;ll use to accumulate the conditions we&amp;#8217;ll need to use in the call to Message.find. There&amp;#8217;s better ways to do this (one of which is on my list to release), but for now lets just use a few arrays:&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;clauses = []
arguments = []
includes = []&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The entry point for the library is KeywordSearch.search, which takes a string to parse and a block. Let&amp;#8217;s go ahead and parse params&lt;span&gt;:q&lt;/span&gt;, in Googlesque fashion:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;KeywordSearch.search(params[:q]) do |with|&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The method yields an new instance of KeywordSearch::Definition, which is just a handy container to define the keywords we want to allow. In our example, we&amp;#8217;re calling the block variable it gets assigned to withâ€¦ just because it will sound nice later.&lt;/p&gt;

&lt;p&gt;First, we should handle the &amp;#8220;keywordless&amp;#8221; terms that are just floating around&amp;#8211; these belong to the default keyword, which we can set with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  with.default_keyword :text&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Lets add a handler for the text keyword, too. In production, you&amp;#8217;d probably want to use something like Ferret, or at least fulltext searches, but for this simple example let&amp;#8217;s just use SQL like. Keyword handlers are always passed an array of values&amp;#8211;keywords might want to allow more than one value, like the text keyword does:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  with.keyword :text do |values|
    # Check subject and body for each, allowing any match (OR)
    clauses &amp;lt;&amp;lt; [&amp;quot;(subject like ? or body like ?)&amp;quot;] * values.size).join(&amp;#39; OR &amp;#39;)
    # Add 2 of each value to the arguments, fitted out with &amp;lt;tt&amp;gt;like&amp;lt;/tt&amp;gt; globs
    arguments += values.map{|val| [&amp;quot;%#{val}%&amp;quot;] * 2 }.flatten
  end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Keyword handlers use the &lt;a href='/2006/5/18/closures-an-italian-sonnet.html'&gt;magic&lt;/a&gt; of &lt;a href='http://en.wikipedia.org/wiki/Closure_(computer_science'&gt;closures&lt;/a&gt;) to give you the flexibility to do whatever you&amp;#8217;d like with any variable in scope&amp;#8211;in our case, we add a clause and two arguments for each value that&amp;#8217;s encountered.&lt;/p&gt;

&lt;p&gt;Now let&amp;#8217;s deal with from, which is a bit tricker, from a query standpoint, requiring a join. We&amp;#8217;ll allow multiple possible values here too:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;with.keyword :from do |values|
  includes &amp;lt;&amp;lt; :author unless includes.include?(:author) # just a good habit
  # Assuming the author is a User
  clauses &amp;lt;&amp;lt; ([&amp;#39;users.name like ?&amp;#39;] * values.size).join(&amp;#39; OR &amp;#39;)
  # Glob for &amp;lt;tt&amp;gt;like&amp;lt;/tt&amp;gt; comparison
  arguments += values.map{|value| &amp;quot;%#value%&amp;quot; }
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let&amp;#8217;s only support one since value, though:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;with.keyword :since do |values|
  date = Date.parse(values.first) # Skipped exception handling
  clauses &amp;lt;&amp;lt; &amp;#39;created_on &amp;gt;= ?&amp;#39;
  arguments &amp;lt;&amp;lt; date
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now that we&amp;#8217;re done with keywords, let&amp;#8217;s just close up the KeywordSearch.search block:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;â€¦ and put everything together for the call to Message.find, building the conditions array as Rails expects:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;conditions = [clauses.map{|c| &amp;quot;(#{c})&amp;quot;}.join(&amp;#39; AND &amp;#39;), *arguments]
@messages = Message.find(:all, :conditions=&amp;gt;conditions, :include=&amp;gt;includes)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Of course, you can always &lt;a href='/2006/10/24/paginator-released.html'&gt;paginate&lt;/a&gt; the results&amp;#8211;or do anything else you&amp;#8217;d like with them.&lt;/p&gt;

&lt;h3 id='a_time_and_a_place'&gt;A time and a place&lt;/h3&gt;

&lt;p&gt;It might be worth noting that Google, in the &lt;a href='http://gmail.google.com/support/bin/answer.py?answer=7190&amp;amp;topic=41'&gt;documentation&lt;/a&gt; for the GMail search feature, calls it &amp;#8220;Advanced Search.&amp;#8221; This feature truly is more &lt;em&gt;advanced&lt;/em&gt; than an unwieldy, but in-your-face search form, requiring some effort and memorization from your users. For that reason, this approach might not be the best fit for many applications.&lt;/p&gt;

&lt;p&gt;Although the keyword method does take an optional description argument, at the moment generating documentation for the supported keywords isn&amp;#8217;t really built into the API, so use in in-house applications is a more likely scenario.&lt;/p&gt;

&lt;p&gt;As to the stability and/or usefulness of the library for its intended purpose at the momentâ€¦ it&amp;#8217;s an initial release&lt;/p&gt;

&lt;h3 id='from_here'&gt;From here&lt;/h3&gt;

&lt;p&gt;There are a number of things that still need to be worked on in the library.&lt;/p&gt;

&lt;p&gt;* For the moment, the character set it allows in searches is extremely restricted (alphanumeric and a few extra characters)&lt;/p&gt;

&lt;p&gt;* Better parser error handling/reporting is needed&lt;/p&gt;

&lt;p&gt;* Dynamic documentation for keywords is desired&lt;/p&gt;

&lt;p&gt;* Support for grouping and negation (v2.0)&lt;/p&gt;

&lt;p&gt;You can read the API docs &lt;a href='http://codefluency.rubyforge.org/keyword_search'&gt;here&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The Rails Edge Part Deux</title>
   <link href="http://codefluency.com/2006/12/30/the-rails-edge-part-deux.html"/>
   <updated>2006-12-30T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/12/30/the-rails-edge-part-deux</id>
   <content type="html">&lt;p&gt;So, the second Rails Edge conference is quickly approaching; I&amp;#8217;ll be flying to the East Coast here in a few weeks, where I&amp;#8217;ll be lucky enough to speak alongside some &lt;a href='http://pragmaticstudio.com/therailsedge/speakers.html'&gt;really smart people&lt;/a&gt; (again) about something I find a &lt;em&gt;lot&lt;/em&gt; of fun&amp;#8211; Rails. I will, of course, be talking about Rails Views, and there&amp;#8217;s a lot of other interesting things planned.&lt;/p&gt;

&lt;p&gt;This one&amp;#8217;s in Reston, VA, January 25-27. If you don&amp;#8217;t know how &lt;a href='http://pragmaticstudio.com/therailsedge/'&gt;The Rails Edge&lt;/a&gt; works, the most compelling fact to know about is its format. Casual. Collaborative. Fun. The last conference, here in Denver, was a blast, and the next one, we think, will be even better.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m looking forward to seeing you there!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Construction in Dubai</title>
   <link href="http://codefluency.com/2006/12/30/construction-in-dubai.html"/>
   <updated>2006-12-30T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/12/30/construction-in-dubai</id>
   <content type="html">&lt;p&gt;This is a bit out of my normal topic area, but I really do love &lt;a href='http://dubai.isnuts.googlepages.com.nyud.net:8080/'&gt;this article&lt;/a&gt; on the planned and ongoing construction in &lt;a href='http://en.wikipedia.org/wiki/Dubai'&gt;Dubai&lt;/a&gt; in the United Arab Emirates.&lt;/p&gt;

&lt;p&gt;If you love seeing insane building projects, this is the article for you. I grew up in Las Vegas, so I&amp;#8217;m used to constant construction and a tourism- focused economy, but this really takes the cake.&lt;/p&gt;

&lt;p&gt;What sadly mars the city&amp;#8217;s reputation through all this, however, is the treatment of low-wage workers from India, Pakistan, and other countries. Unfortunately the Gulf states in general have a bit of a bad reputation when it comes to poor, expatriate workers; in fact, when I was studying Arabic in school, I heard quite a bit from Egyptian friends about how the elite citizen minority in the Gulf treat migrant Egyptian workers.&lt;/p&gt;

&lt;p&gt;What is it with money and bad behavior?&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>That nifty question mark</title>
   <link href="http://codefluency.com/2006/12/16/that-nifty-question-mark.html"/>
   <updated>2006-12-16T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/12/16/that-nifty-question-mark</id>
   <content type="html">&lt;p&gt;Here&amp;#8217;s a pattern you see a lot of in Ruby:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  foo.bar if foo.respond_to?(:bar)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I do this kind of thing frequently, as I&amp;#8217;m a big fan of &lt;a href='http://wiki.rubygarden.org/Ruby/page/show/DuckTyping'&gt;ducktyping&lt;/a&gt; over checking an object&amp;#8217;s class explicitly. I&amp;#8217;m not concerned with the &lt;em&gt;class&lt;/em&gt; of an object as long as it does what I&amp;#8217;m asking.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://iolanguage.com'&gt;Io&lt;/a&gt; has a nice and simple way of doing this, built into the language:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  foo ?bar&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If foo has &lt;em&gt;slot&lt;/em&gt; bar (ie, in Rubyland it &lt;em&gt;responds to&lt;/em&gt; bar), send the bar message to foo.&lt;/p&gt;

&lt;p&gt;Simple trick: you can essentially bootstrap Ruby to do the same thing (note I use the word try in this example, which may have too much baggage for some of you):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Object
  def try(meth, *args, &amp;amp;block)
    __send__(meth, *args, &amp;amp;block) if respond_to? meth
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then you can do &lt;code&gt;foo.try :bar&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If the object doesn&amp;#8217;t respond to the method, nil is returned, as in Io.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Migrate already!</title>
   <link href="http://codefluency.com/2006/12/14/migrate-already.html"/>
   <updated>2006-12-14T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/12/14/migrate-already</id>
   <content type="html">&lt;p&gt;For some reason, people seem to have an issue with &lt;a href='http://www.rubyonrails.org/api/classes/ActiveRecord/Migration.html'&gt;migrations&lt;/a&gt; â€¦ they get them confused with &lt;em&gt;schemas&lt;/em&gt;. Allow me to explain.&lt;/p&gt;

&lt;p&gt;A lot of people seem to sit on changes they want to make models, &lt;em&gt;collecting&lt;/em&gt; changes for &amp;#8220;one big migration.&amp;#8221; As if it were of utmost important that the migration &lt;em&gt;be complete&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Migrations are meant to encapsulate a &lt;em&gt;single&lt;/em&gt; set of modifications to your database schema. If you discover suddenly that that your table doesn&amp;#8217;t have columns &lt;em&gt;x&lt;/em&gt;, &lt;em&gt;y&lt;/em&gt;, and &lt;em&gt;z&lt;/em&gt;, and you need them for a model, make a migration for it. Don&amp;#8217;t hold out on the off chance that you&amp;#8217;ll come up with more changes in 10 minutes. Taking care of business, and take care of it now.&lt;/p&gt;

&lt;p&gt;Let me give you a few reasons why you shouldn&amp;#8217;t be afraid of &lt;em&gt;just migrating already&lt;/em&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Smaller migrations mean there&amp;#8217;s less of a chance of making an error in the middle. Migrations that fail in the middle are a &lt;em&gt;whole&lt;/em&gt; lot of fun to fix, right?&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Smaller migrations make writing self.downs easier; less looking back and forth (if you&amp;#8217;re not using a handy feature of your editor/IDE to write them for you)&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Naming smaller migrations is easier&amp;#8211; there&amp;#8217;s less change in the migration you need to describe&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;More migration numbers mean you can roll back with finer granularity if you need to&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Faster changes == Agility. If you don&amp;#8217;t care about agility, you &lt;em&gt;just might&lt;/em&gt; be using the wrong framework.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;There&amp;#8217;s no reason not to (unless you&amp;#8217;re afraid of &lt;em&gt;another file&lt;/em&gt;&amp;#8211; eeek!)&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;&amp;#8220;Speed&amp;#8221; concerns are poppycock. At over &lt;em&gt;500&lt;/em&gt; migrations on my mega app, running db:migrate chugs along handily.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;A migration number is not sacrosanct. Ruby can count forwards and backwards faster than you can, and, surprisingly, &lt;em&gt;absolutely no&lt;/em&gt; puppies or kittens die if you have more migrations.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And there you have it.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Introducing Badger</title>
   <link href="http://codefluency.com/2006/12/08/introducing-badger.html"/>
   <updated>2006-12-08T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/12/08/introducing-badger</id>
   <content type="html">&lt;p&gt;Badges are an expected, even necessary hassle for conference organizers; they identify who&amp;#8217;s allowed in the door, help people start conversations, and end up as souveniers once the conference is finished. The problem with badges, though, is that they can be a real pain to put together.&lt;/p&gt;

&lt;p&gt;Design-wise, each badge at a conference is essentially the same&amp;#8211; but the fact each badge has different information, getting them printed (and looking good afterwards) can be a challenge. Paying a print shop to fill-in the badges can be prohibitively expensive, if they offer the service at all (and having the badges printed is pricey enough). Trying to print over a blank sheet of badges with names, etc, is error prone and, in most cases, the badges come off obviously homemade. Using programs like Publisher isn&amp;#8217;t hard to do, but feels heavy, ends up being less nimble if you need to make changes or fix mistakes, and, depending on your OS, may or may not be an option.&lt;/p&gt;

&lt;p&gt;For RubyConf 2006, I wrote a small script called Badger which we used to generate the conference badges. It&amp;#8217;s a lightweight solution that relies on the use of a PDF form template (which I have a pretty good amount of experience creating), a YAML data source (something any Rubyist can tackle), and an Open Source tool called &lt;a href='http://accesspdf.com/pdftk'&gt;PDF Toolkit&lt;/a&gt; to handle the form filling. It ended up being the right tool for the job; the results are professional, it&amp;#8217;s agile (in terms of data changes), easy to automate, and lacking any stringent design limitations (big plus there).&lt;/p&gt;

&lt;p&gt;I recently refactored the tool into a RubyGem, and I&amp;#8217;m happy to announce its initial release. Check out the &lt;a href='http://codefluency.rubyforge.org/badger'&gt;documentation&lt;/a&gt;, and see the &lt;a href='http://rubyforge.org/frs/download.php/15418/badger_sample-1.0.0.tar.gz'&gt;sample project tarball&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can install the gem, as you might expect, with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo gem install badger&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You&amp;#8217;ll need to be able to create PDF forms (probably with the full version of Adobe Acrobat), and have &lt;a href='http://accesspdf.com/pdftk'&gt;PDF Toolkit&lt;/a&gt; installed.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Adding Date and Time Formats</title>
   <link href="http://codefluency.com/2006/12/05/adding-date-and-time-formats.html"/>
   <updated>2006-12-05T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/12/05/adding-date-and-time-formats</id>
   <content type="html">&lt;p&gt;This is nothing new, but, having seen enough Rails developers using custom helpers to do the same thing, I thought it might warrant a quick tip.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re entering dates/times in your fixtures, you&amp;#8217;re probably familiar with this trick:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  ---
  item1:
    id: 1
    name: foo
    created_at: &amp;lt;%= 3.days.ago.to_s(:db) %&amp;gt;&lt;/code&gt;&lt;/pre&gt;</content>
 </entry>
 
 <entry>
   <title>Memoizing nil and false</title>
   <link href="http://codefluency.com/2006/12/03/memoizing-nil-and-false.html"/>
   <updated>2006-12-03T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/12/03/memoizing-nil-and-false</id>
   <content type="html">&lt;p&gt;Here&amp;#8217;s a common technique:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def foo
  @foo ||= compute_foo
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For those that don&amp;#8217;t know, this is an example of &lt;em&gt;memoization&lt;/em&gt;; we only compute&lt;em&gt;foo if @foo hasn&amp;#8217;t been assigned a value.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Well, that&amp;#8217;s not &lt;em&gt;strictly&lt;/em&gt; true. Let&amp;#8217;s say that &lt;code&gt;compute_foo&lt;/code&gt; returns nil or false, completely acceptable values for @foo. Let&amp;#8217;s also say that compute&lt;em&gt;foo take 2.3 minutes, chugs 150MB of RAM while running, and hits the network like a room full of Rails programmers at a conference (just for kicks&amp;#8211; I have no idea what &lt;code&gt;compute_foo&lt;/code&gt; does, but it&amp;#8217;s resource intensive, obviously).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Using this traditional memoization technique, if &lt;code&gt;compute_foo&lt;/code&gt; returns nil, we&amp;#8217;ll be calling &lt;code&gt;compute_foo&lt;/code&gt; unnecessarily every successive time we call foo. Oops.&lt;/p&gt;

&lt;p&gt;Ruby&amp;#8217;s pretty dynamic, so let&amp;#8217;s make use of it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def foo
  @foo = `compute_foo` unless `instance_variables`.include?(&amp;#39;@foo&amp;#39;)
  @foo
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let&amp;#8217;s add Rails-style &amp;#8220;expirable&amp;#8221; memoization, too:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def foo(force_reload=false)
  unless `force_reload` || !instance_variables.include?(&amp;#39;@foo&amp;#39;)
    @foo = compute_foo
  end
  @foo
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And there you have it.&lt;/p&gt;

&lt;p&gt;Keep in mind what I&amp;#8217;m talking about is definitely an edge case; in most situations, &lt;code&gt;compute_foo&lt;/code&gt; won&amp;#8217;t return nil or false, so this won&amp;#8217;t come up. Also, if you find expirable memoization to be tedious to do by hand (like any sane person &lt;em&gt;does&lt;/em&gt;), take a look at Marcel&amp;#8217;s &lt;a href='http://rubyforge.org/viewvc/s3/trunk/lib/aws/s3/extensions.rb?root=amazon&amp;amp;view=markup'&gt;memoize in aws/s3&lt;/a&gt; for a nifty approach.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>RubyGem-based Rails Plugins</title>
   <link href="http://codefluency.com/2006/11/29/rubygem-based-rails-plugins.html"/>
   <updated>2006-11-29T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/11/29/rubygem-based-rails-plugins</id>
   <content type="html">&lt;p&gt;One thing about Rails that&amp;#8217;s a bit annoying to those of us who have been using Ruby for a long time is the lack of support for RubyGem-based plugins.&lt;/p&gt;

&lt;p&gt;You have to take into account the kind of torture conversations like this were, for years upon years, and the kind of psychological damage it did to all of us:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What&amp;#8217;s Ruby&amp;#8217;s CPAN?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;Anything like CPAN for Ruby?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;What&amp;#8217;s the package/library manager for Ruby?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;Ruby sucks! Where&amp;#8217;s CPAN?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every time someone new ran into Ruby (often from Perl, especially in the beginning), it would inevitably come up&amp;#8211; and someone would respond (out of ignorance or some type of masochistic delight), and it would ping-pong back and forth for a few days. It was the Ruby mailing list equivalent of &lt;a href='http://www.imdb.com/title/tt0107048/'&gt;Groundhog Day&lt;/a&gt; â€¦ but less fun. It was painfully repetitive, annoyingly pertinent, and frankly, a bit embarassing (how long it went on, at least). Thankfully, a group of great developers put together RubyGems out of the blue, and it caught on (beating back a bully or two in the process). RubyGems is a complete success&amp;#8211; that&amp;#8217;s obvious from the tremendous download stats&amp;#8211; and the fact we don&amp;#8217;t have those annoying &lt;em&gt;CPAN&lt;/em&gt; conversations anymore.&lt;/p&gt;

&lt;p&gt;Don&amp;#8217;t get me wrong.. script/plugin install is great; it&amp;#8217;s been wonderful. It&amp;#8217;s fast, it&amp;#8217;s easy, and it&amp;#8217;s a large part of why Rails development is so compelling&amp;#8211; the community is &lt;em&gt;involved&lt;/em&gt; â€¦ plus, it just works. But let&amp;#8217;s keep in mind that the Rails community is growing out of controlâ€¦ plugins are becoming more widespread and advanced, and as such an important aspect of Rails, dependency resolution and versioning needs to become a serious concern if we want to keep plugins quick, fun, and easy to get working. The good news is we don&amp;#8217;t need to reinvent the wheel, RubyGems is easily up to the task.&lt;/p&gt;

&lt;p&gt;Truth be told, people have been talking about gem plugins from the beginning, and there have been certain in-roads (as with generators)&amp;#8211; but it hasn&amp;#8217;t been easily built into Rails itself.&lt;/p&gt;

&lt;p&gt;Tonight I submitted &lt;a href='http://dev.rubyonrails.org/ticket/6726'&gt;a patch&lt;/a&gt; to do just that. It&amp;#8217;s a bit naive, and likely broken in a few placesâ€¦ but hopefully it will spark some serious conversation, some good work, and someone smarter and more savvy than I will take up the torch and do something useful with it.&lt;/p&gt;

&lt;p&gt;The idea is simple; install gems and use the &lt;span&gt;existing&lt;/span&gt; plugin configuration to select what plugins you&amp;#8217;d like to load (including version requirements) for each application. It&amp;#8217;s backwards compatible; you can still use normal plugins if you&amp;#8217;d like&amp;#8211; but the gem plugins are structured the same way, have the same capabilities, and come with all the inherent benefits of RubyGems intact.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views,</title>
   <link href="http://codefluency.com/2006/11/21/rails-views-the-other-dom_id.html"/>
   <updated>2006-11-21T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/11/21/rails-views-the-other-dom_id</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve noticed recently, looking through my traffic, that a good number of people still come around looking for my &lt;code&gt;dom_id&lt;/code&gt; &lt;a href='/2006/7/2/rails-views-bulletproofing-dom_id.html'&gt;articles&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I think it&amp;#8217;s worth mentioning that you shouldn&amp;#8217;t be using my &lt;code&gt;dom_id&lt;/code&gt; code anymore- if you&amp;#8217;re running a up-to-date version of Rails (maybe only edge?) you&amp;#8217;ll want to use the &lt;code&gt;simply_helpful&lt;/code&gt; plugin instead; I do.&lt;/p&gt;

&lt;p&gt;It wraps the DOM ID related stuff with lots of RESTful goodness, so use it.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>TFWY 1.0.0 Released</title>
   <link href="http://codefluency.com/2006/11/21/tfwy-1-0-0-released.html"/>
   <updated>2006-11-21T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/11/21/tfwy-1-0-0-released</id>
   <content type="html">&lt;p&gt;I&amp;#8217;m proud to announce (along with my co-author, Martin Owen) the v1.0.0 release of the Ruby bindings to the &lt;a href='http://theyworkforyou.com'&gt;TheyWorkForYou&lt;/a&gt; &lt;a href='http://theyworkforyou.com/api'&gt;API&lt;/a&gt;. TheyWorkForYou is a &amp;#8220;non-partisan, volunteer-run website which aims to make it easy for people to keep tabs on their elected and unelected representatives in Parliament.&amp;#8221;&lt;/p&gt;

&lt;p&gt;The Ruby bindings currently support all of the services offered by v1.0.0 of the API, and makes accessing the data very, very easy to do.&lt;/p&gt;

&lt;h2 id='simple_examples'&gt;Simple Examples&lt;/h2&gt;

&lt;p&gt;Get a clientâ€¦&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  require &amp;#39;twfy&amp;#39;
  client = Twfy::Client.new&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then call services on it directlyâ€¦&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  puts client.constituency(:postcode=&amp;gt;&amp;#39;IP6 9PN&amp;#39;).name
  # =&amp;gt; Central Suffolk &amp;amp; North Ipswich
  mp = client.mp(:postcode=&amp;gt;&amp;#39;IP6 9PN&amp;#39;)
  puts mp.full_name
  # =&amp;gt; Michael Lord
  # Get a *lot* of info about this MP
  info = client.mp_info(:id=&amp;gt;mp.person_id)
  # Get a sorted list of all the parties in the House of Lords
  client.lords.map{|l| l.party}.uniq.sort
  # =&amp;gt; [&amp;quot;Bishop&amp;quot;, &amp;quot;Conservative&amp;quot;, &amp;quot;Crossbench&amp;quot;, &amp;quot;DUP&amp;quot;, &amp;quot;Green&amp;quot;, &amp;quot;Labour&amp;quot;, &amp;quot;Liberal Democrat&amp;quot;, &amp;quot;Other&amp;quot;]
  # Get number of debates in the House of Commons mentioning &amp;#39;Iraq&amp;#39;
  number = client.debates(:type=&amp;gt;&amp;#39;commons&amp;#39;,:search=&amp;gt;&amp;#39;Iraq&amp;#39;).info[&amp;#39;total_results&amp;#39;]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or, make use of the &amp;#8220;daisy chaining&amp;#8221; available for services&amp;#8211; the correct arguments are passed around for you (plus you get the benefit of some in- memory caching).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  # Get the MP for the last constituency (if you sort them alphabetically)
  mp = client.constituencies.sort_by{|c| c.name }.last.mp
  
  # get the geometry information for that constituency (coming from the MP)
  geometry = mp.constituency.geometry
  
  # An overkill example showing caching (no services are called here, since
  # the results have already been cached from above)
  mp = mp.constituency.mp.constituency.geometry.constituency.mp
  
  # These return equivalent results (Note how much easier the first is)
  info1 = mp.info # this is cached for subsequent calls
  info2 = client.mp_info(:id=&amp;gt;mp.person_id)
  
  # Get pages of debates mentioning &amp;#39;medicine&amp;#39;
  debates1 = mp.debates(:search=&amp;gt;&amp;#39;medicine&amp;#39;)
  debates2 = mp.debates(:search=&amp;gt;&amp;#39;medicine&amp;#39;, :page=&amp;gt;2)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;See http://www.theyworkforyou.com/api/docs for the original TheyWorkForYou API documentation. The Ruby bindings has RDoc up at http://twfy.rubyforge.org. The project is still in its beginning stages, and feedback is &lt;span&gt;and always will be&lt;/span&gt; welcome.&lt;/p&gt;

&lt;h2 id='get_it'&gt;Get it&lt;/h2&gt;

&lt;p&gt;As with any gemâ€¦&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo gem install twfy&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='why_i_did_this'&gt;Why I did this&lt;/h2&gt;

&lt;p&gt;It might be worth mentioning that I live in Colorado&amp;#8211; a fair ways distant from London, or from anywhere else in the UK, for that matter. So why did I do this?&lt;/p&gt;

&lt;p&gt;Sometimes I get bored, and that boredom eventually drives me to search for crazy, off the wall things to do. TheyWorkForYou is just one of the rare &lt;em&gt;useful&lt;/em&gt; projects I&amp;#8217;ve run across, and I couldn&amp;#8217;t resist tossing some Ruby goodness at it.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>My Rails Edge Wrap-up</title>
   <link href="http://codefluency.com/2006/11/21/my-rails-edge-wrap-up.html"/>
   <updated>2006-11-21T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/11/21/my-rails-edge-wrap-up</id>
   <content type="html">&lt;p&gt;So, over the last few days I had the opportunity to be a speaker for &lt;a href='http://therailsedge.com'&gt;The Rails Edge&lt;/a&gt; held in Denver, CO (incidently, just down the road a bit). The Rails Edge is a unique series of Rails-related conferences held by &lt;a href='http://pragmaticstudio.com/'&gt;The Pragmatic Studio&lt;/a&gt; that will be held regionally across the US. What makes them unique is their format&amp;#8211; open, friendly, and focused on up-to-date Rails information. The way I wish all conferences were.&lt;/p&gt;

&lt;p&gt;I &lt;em&gt;really&lt;/em&gt; enjoyed the conference, and definitely get the impression that the attendees did, too. This wasn&amp;#8217;t a conference where the speakers only popped out to speak, keeping themselves isolated the rest of the time. If there&amp;#8217;s anything the speakers have in common, it&amp;#8217;s a very sincere love of Rails, teaching, and learning from each other (and the attendees)&amp;#8211; and I think that was pretty obvious. In terms of atmosphere, it was definitely one of the best conferences I&amp;#8217;ve been to (and in terms of material, I think it was pretty damn top-notch&amp;#8211; but I&amp;#8217;m a bit biased).&lt;/p&gt;

&lt;p&gt;So, if you&amp;#8217;re interested in Rails&amp;#8211; what it can do and where it&amp;#8217;s going&amp;#8211; and have a passion for learning, I urge you to take a look at this conference series. The &lt;a href='http://pragmaticstudio.com/therailsedge/speakers.html'&gt;speakers&lt;/a&gt; have a lot to say, the format is built around collaboration and learning from each other, and we&amp;#8217;re conveniently travelling the country to make it available to everyone.&lt;/p&gt;

&lt;p&gt;The next one is in Reston, VA, in Januaryâ€¦ see you there?&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The Rails Edge starting</title>
   <link href="http://codefluency.com/2006/11/15/the-rails-edge-starting.html"/>
   <updated>2006-11-15T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/11/15/the-rails-edge-starting</id>
   <content type="html">&lt;p&gt;So, tomorrow &lt;a href='http://www.therailsedge.com'&gt;The Rails Edge&lt;/a&gt; starts up.&lt;/p&gt;

&lt;p&gt;As I get ready to hop into my car and drive the scant 30 minutes it will take to reach the venue (I&amp;#8217;m lucky&amp;#8211; this one is right in my neighborhood), I can&amp;#8217;t help but be excited. I love conferences. They&amp;#8217;re exhausting, but you can&amp;#8217;t beat the experience of being at a location with so many people with the same passion for development.&lt;/p&gt;

&lt;p&gt;RubyConf &lt;span&gt;and RailsConf, this year&lt;/span&gt; always give me a huge boost of morale, seeing the new and interesting things that people have been working on. With the unique format of this conference (it feels more collaborative and &amp;#8220;friendly&amp;#8221; than most) I can&amp;#8217;t wait to see the kind of discussion and ideas that will come out of it.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>TextMate goes spooky</title>
   <link href="http://codefluency.com/2006/10/31/textmate-goes-spooky.html"/>
   <updated>2006-10-31T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/10/31/textmate-goes-spooky</id>
   <content type="html">&lt;p&gt;Definitely the biggest surprise from today&amp;#8217;s &lt;a href='http://macromates.com'&gt;TextMate&lt;/a&gt; update was the new, spooky, and&amp;#8211; I&amp;#8217;m guessing&amp;#8211;temporary&amp;#8211; change of icons. I&amp;#8217;ve gotten used to Google&amp;#8217;s holiday theming, but this is probably the first time I&amp;#8217;ve had a desktop app get festive on me.&lt;/p&gt;

&lt;p&gt;Pretty neat, I think. I wonder what they have in store for Christmas.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rtex moved to RubyForge</title>
   <link href="http://codefluency.com/2006/10/29/rtex-moved-to-rubyforge.html"/>
   <updated>2006-10-29T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/10/29/rtex-moved-to-rubyforge</id>
   <content type="html">&lt;p&gt;The Rtex Plugin (LaTeX view engine for Rails) has moved to it&amp;#8217;s own &lt;a href='http://rtex.rubyforge.org'&gt;RubyForge project&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The subversion repository is now at svn://rubyforge.org/var/svn/rtex/trunk. I&amp;#8217;m be making some non-backwards-compatible modifications to the way the plugin is configured during the next few days, but the current stable release will always be available at tt&amp;gt;svn://rubyforge.org/var/svn/rtex/tags/legacy.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Ruby Central Redesign</title>
   <link href="http://codefluency.com/2006/10/25/ruby-central-redesign.html"/>
   <updated>2006-10-25T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/10/25/ruby-central-redesign</id>
   <content type="html">&lt;p&gt;Recently, I&amp;#8217;ve been working with the directors at &lt;a href='http://rubycentral.org'&gt;Ruby Central&lt;/a&gt; on a new design for their website, now running on top of &lt;a href='http://radiantcms.org/'&gt;Radiant&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At RubyConf, the new design was released. It&amp;#8217;s a simple, clean design sporting their new logo (also by yours truly).&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Onward Hoe!</title>
   <link href="http://codefluency.com/2006/10/24/onward-hoe.html"/>
   <updated>2006-10-24T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/10/24/onward-hoe</id>
   <content type="html">&lt;p&gt;This is just a quick followup to latest release notice.&lt;/p&gt;

&lt;p&gt;I used &lt;a href='http://rubyforge.org/frs/shownotes.php?group_id=1513&amp;amp;release_id=7521'&gt;Hoe&lt;/a&gt; to release the &lt;a href='http://paginator.rubyforge.org'&gt;paginator&lt;/a&gt; filesâ€¦ and I have to say that&amp;#8217;s the easiest, least painful release I&amp;#8217;ve ever done. As Ryan said at the conference, it makes it easy enough to release more often, and that is spectacular!&lt;/p&gt;

&lt;p&gt;As a self-described Rake nerd, I find Hoe to be truly compelling from a technical standpoint&amp;#8211; but its possible effect on the community is even more exciting. Quicker, smaller releases are better for everyone, and with the addition of sow to the library, getting up and running is easier than ever.&lt;/p&gt;

&lt;p&gt;My thanks to Ryan Davis and Ara Howard (not to mention the bevy of other contributers) for making something like this available to the community.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Paginator Released</title>
   <link href="http://codefluency.com/2006/10/24/paginator-released.html"/>
   <updated>2006-10-24T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/10/24/paginator-released</id>
   <content type="html">&lt;p&gt;Writing paginators sucks, and it&amp;#8217;s something that we get stuck with doing from time to time. Deceptively simple, they can be pretty tedious to write&amp;#8211; and they&amp;#8217;re definitely not the type of code that makes you go, &amp;#8220;Wow, that&amp;#8217;s just cool!&amp;#8221; I mean, comeonâ€¦ this isn&amp;#8217;t rocket science, it&amp;#8217;s just boring.&lt;/p&gt;

&lt;p&gt;The problem with most paginators (ie, the paginator in Rails) is that they&amp;#8217;re tightly coupled with what they&amp;#8217;re paginating&amp;#8211; so it&amp;#8217;s difficult to just rip them out and use the code elsewhere. On top of that, many times they&amp;#8217;re too rigid (hard to change pages) or make it difficult to query for metadata (is this the last page?).&lt;/p&gt;

&lt;p&gt;For a while now I&amp;#8217;ve been using a &amp;#8220;custom&amp;#8221; paginator in my Rails projects; a small library I wrote so that I would have more control over changing pages and seeing metadata. From the beginning this paginator was written to be framework agnostic&amp;#8211; something I can just rip out and use elsewhere (ie, a CLI, etc)&amp;#8211; for one simple reason. I &lt;em&gt;never&lt;/em&gt; want to have to write another paginator again.&lt;/p&gt;

&lt;p&gt;Today I released the &lt;em&gt;paginator 1.0.0,&lt;/em&gt; available as a gem. Here&amp;#8217;s a quick example:&lt;/p&gt;

&lt;h2 id='rails'&gt;Rails&lt;/h2&gt;

&lt;h3 id='in_your_controller'&gt;In your controller&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;  PER_PAGE = 20
  @pager = Paginator.new(Foo.count, PER_PAGE) do |offset, per_page|
    Foo.find(:all, :limit =&amp;gt; per_page, :offset =&amp;gt; offset)
  end
  @page = @pager.page(params[:page])&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='in_your_view'&gt;In your view&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;  &amp;lt;% @page.each do |foo| &amp;gt;
    &amp;lt;# Show something for each item &amp;gt;
  &amp;lt;% end %&amp;gt;
  &amp;lt;%= @page.number %&amp;gt;
  &amp;lt;%= link_to(&amp;quot;Prev&amp;quot;, foos_url(:page =&amp;gt; @page.prev.number)) if @page.prev? %&amp;gt;
  &amp;lt;%= link_to(&amp;quot;Next&amp;quot;, foos_url(:page =&amp;gt; @page.next.number)) if @page.next? %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='elsewhere'&gt;Elsewhere&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;bunch_o_data = (1..60).to_a
PER_PAGE = 10
pager = Paginator.new(bunch_o_data.size, PER_PAGE) do |offset, per_page|
  bunch_o_data[offset,per_page]
end
pager.each do |page|
  puts &amp;quot;Page ##{page.number}&amp;quot;
  page.each do |item|
    puts item
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It&amp;#8217;s pretty simple stuff. You instantiate a Paginator object, telling it how many records there are and how many you&amp;#8217;d like per page. You also pass a block that will be used to return the records for a page, given the record offset (and the number of records per page&amp;#8211; which you just passed into the constructor&amp;#8211; as a convenience).&lt;/p&gt;

&lt;p&gt;To get it, it&amp;#8217;s simple:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo gem install paginator&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The full docs are &lt;a href='http//paginator.rubyforge.org'&gt;here&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The theme goes official</title>
   <link href="http://codefluency.com/2006/10/24/the-theme-goes-official.html"/>
   <updated>2006-10-24T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/10/24/the-theme-goes-official</id>
   <content type="html">&lt;p&gt;I&amp;#8217;m happy to announce that my &lt;a href='http://rubyforge.org'&gt;RubyForge&lt;/a&gt; theme, after flying &lt;a href='/2006/10/6/rubyforge-theme.html'&gt;under the radar&lt;/a&gt; for some time now, has been adopted as the official, default theme. Many thanks to &lt;a href='http://rubycentral.org'&gt;RubyCentral&lt;/a&gt; and the RubyForge team for their support during the design.&lt;/p&gt;

&lt;p&gt;If you run into any problems with the theme, please contact me so that I can address them.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rake Shame</title>
   <link href="http://codefluency.com/2006/10/23/rake-shame.html"/>
   <updated>2006-10-23T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/10/23/rake-shame</id>
   <content type="html">&lt;p&gt;If you&amp;#8217;ve ever been working on a Rails application (or any application, for that matter) and found yourself &lt;span&gt;stupidly&lt;/span&gt; slipping in your testing, I have just the tool for you.&lt;/p&gt;

&lt;p&gt;Using rake and &lt;a href='http://rubyosa.rubyforge.org/'&gt;rubyosa&lt;/a&gt;, you can now automatically post your Code to Test Ratio as your iChat status message&amp;#8211; meaning you can now use shame and self- humiliation to keep you motivated.&lt;/p&gt;

&lt;p&gt;First, take a look at &lt;a href='http://clarkware.com/cgi/blosxom/2006/10/23#RubyOSA'&gt;Mike Clark&amp;#8217;s&lt;/a&gt; instructions for setting up &lt;a href='http://rubyosa.rubyforge.org/'&gt;rubyosa&lt;/a&gt;. After you&amp;#8217;ve set up rubyosa, add &lt;code&gt;shame.rake&lt;/code&gt; to your lib/tasks directory, which contains:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require &amp;#39;rbosa&amp;#39;
require &amp;#39;code_statistics&amp;#39;
task :shame do
  stats = CodeStatistics.new(*STATS_DIRECTORIES)
  code  = stats.send :calculate_code
  tests = stats.send :calculate_tests
  ichat = OSA.app(&amp;#39;ichat&amp;#39;)
  msg = &amp;quot;Code To Test Ratio: 1:#{sprintf(&amp;quot;%.1f&amp;quot;, tests.to_f/code)}&amp;quot;
  ichat.status_message = msg
  $stderr.puts %|iChat status set to: #{msg.inspect}|
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Type rake shame and let the mocking (and motivation) begin!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Simple Complexity</title>
   <link href="http://codefluency.com/2006/10/19/simple-complexity.html"/>
   <updated>2006-10-19T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/10/19/simple-complexity</id>
   <content type="html">&lt;p&gt;Rails is simple&amp;#8211; or complex&amp;#8211; depending on how you look at it. There&amp;#8217;s a lot of complexity under the covers that makes creating applications simple. This simplicity can be a bit misleading; surely something everyone says is easy to use can&amp;#8217;t solve complex problems or cater to rich domains, right?&lt;/p&gt;

&lt;p&gt;While it&amp;#8217;s true that Rails can&amp;#8217;t simplify the problems and concerns that exist in a rich domain, it can make them easier to deal with. The fact you have a good, sturdy walking stick doesn&amp;#8217;t make the mountain any shorter, it just makes it less exhausting.&lt;/p&gt;

&lt;p&gt;Although you can still find plenty of naysayers out there complaining that Rails is unsuitable for the enterprise, and that anything based on a &amp;#8220;scripting&amp;#8221; language is just a hacked-together solution (thank you, very much), those of us who &lt;em&gt;are&lt;/em&gt; writing huge web applications know better.&lt;/p&gt;

&lt;p&gt;Take a look at the curious imaeg to the rightâ€¦ what is it? A drapery that I have, for some crazy reason, deemed interesting enough to dress up with a drop shadow and post?&lt;/p&gt;

&lt;p&gt;No, it&amp;#8217;s a &lt;em&gt;very&lt;/em&gt; small detail of my application&amp;#8217;s model diagram, showing models (ovals) and associations (lines). By &amp;#8220;small&amp;#8221; I mean&amp;#8211; at most&amp;#8211; 1/50th. Wer&amp;#8217;re talking over 250 models with over 1,100 separate associations. And I just shiver at the thought of doing this in PHP, CF, JSP, or ASP (okay, &lt;em&gt;vomit&lt;/em&gt; in the case of ASP).&lt;/p&gt;

&lt;p&gt;IThis ain&amp;#8217;t no /t(&lt;span&gt;oa&lt;/span&gt;)d\1\s&lt;em&gt;list/, folks.&lt;/em&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views,</title>
   <link href="http://codefluency.com/2006/10/19/rails-views-rails-right-here...html"/>
   <updated>2006-10-19T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/10/19/rails-views-rails-right-here..</id>
   <content type="html">&lt;p&gt;I thought one or two of you might be in the market for a nice, full-time Rails job, and wouldn&amp;#8217;t mind moving out to beautiful Broomfield, CO to do it. On the downside, you&amp;#8217;d be working with me ;-)&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s the blurb:&lt;/p&gt;

&lt;p&gt;&lt;a href='http://naviance.com'&gt;Naviance&lt;/a&gt; is a small, well-established software company catering to the education domain. We’re currently seeking another full-time Rails developer to work at &lt;a href='http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;q=520+Zang+St,+Broomfield,+CO&amp;amp;ie=UTF8&amp;amp;om=1&amp;amp;z=13&amp;amp;ll=39.927773,-105.130405&amp;amp;spn=0.078062,0.233631'&gt;our Broomfield, CO office&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re interested and would like more information, contact me.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>RubyForge Theme</title>
   <link href="http://codefluency.com/2006/10/06/rubyforge-theme.html"/>
   <updated>2006-10-06T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/10/06/rubyforge-theme</id>
   <content type="html">&lt;p&gt;&lt;a href='http://tomcopeland.blogs.com'&gt;Tom Copeland&lt;/a&gt; recently &lt;a href='http://tomcopeland.blogs.com/juniordeveloper/2006/09/popular_rubyfor.html'&gt;brought to light&lt;/a&gt; the existence of my &lt;a href='http://rubyforge.org'&gt;RubyForge&lt;/a&gt; theme. It&amp;#8217;s been around for awhile, but not something we really announced (just a mention on the &lt;a href='http://rubyforge.org/credits/'&gt;credits&lt;/a&gt; page).&lt;/p&gt;

&lt;p&gt;I was pleasantly surprised by the number of people who&amp;#8217;ve elected to use the theme. If you&amp;#8217;re in the market for a change of pace, please try out the theme. Your feedback (as always), is welcome.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The Problem with Solutions</title>
   <link href="http://codefluency.com/2006/10/05/the-problem-with-solutions.html"/>
   <updated>2006-10-05T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/10/05/the-problem-with-solutions</id>
   <content type="html">&lt;p&gt;If there&amp;#8217;s anything that there&amp;#8217;s a lot of these days, it&amp;#8217;s Javascript.&lt;/p&gt;

&lt;p&gt;Seriously, take a look around. It&amp;#8217;s everywhere. We&amp;#8217;re not talking about the dumb marquee scripts and other &amp;#8220;toys&amp;#8221; that constituted the Dark Age of Javascript, either&amp;#8211; it&amp;#8217;s been the Rennaissance of Javascript for a while now&amp;#8211; with Web 2.0, smart people are putting spectacular things together with Javascript every day.&lt;/p&gt;

&lt;p&gt;&amp;#8220;Web 2.0&amp;#8221; has largely been about Javascript and our growing acceptance (and respect) for this much-maligned language, and as more people seriously started looking into the language, major libraries emerged to make life easier. Libraries like &lt;a href='http://prototype.conio.net'&gt;Prototype&lt;/a&gt; provide a layer of abstraction to protect us from browser irregularities, give us ways to handle data structures more naturally, and include &amp;#8220;remote&amp;#8221; request toolkits (ie, Ajax.Request and friends) that have quickly become the Web 2.0 standard.&lt;/p&gt;

&lt;p&gt;This movement towards the use of foundational libraries has created its own niche market, the small compact scripts touting their &lt;em&gt;lack&lt;/em&gt; of a requirement for these libraries, since they&amp;#8217;re &amp;#8220;too big.&amp;#8221;&lt;/p&gt;

&lt;p&gt;The problem with these little frugal scripts is that if you &lt;em&gt;are&lt;/em&gt; using Prototype (or whatever library you prefer), the following things are probably true:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;They&amp;#8217;re longer than their Prototype-based equivalents would be&amp;#8211; being &lt;em&gt;less&lt;/em&gt; frugal in your case ($$ is obviously shorter than document.getElementById, and that&amp;#8217;s just one function call, iterations are worse)&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;They&amp;#8217;re more brittle, since they rely on different, sometimes spotty, ways of watching for browser irregularities (meaning more redundant code, too)&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;They provide wildly different APIs. Use of Prototype, etc, encourages the building of similar APIs (ie, MyLibrary.myFunction() vs someRandomFunction())&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Their authors completely ignore the fact that caching exists and, in many cases, is good enough for most cases&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I&amp;#8217;m not saying that authors need to provide &amp;#8220;Prototype&amp;#8221; and &amp;#8220;Lite&amp;#8221; version of scripts they provide (this is free code, after all)&amp;#8211; but if you&amp;#8217;re using Prototype and you are looking at a non-Prototype-based script, you need to be aware of these issues. If you&amp;#8217;re uncomfortable with the tradeoffs, have the chops, and the license permits, why not modify the script to sit on top of Prototype, rather than beside it?&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Hopscotch</title>
   <link href="http://codefluency.com/2006/10/03/hopscotch.html"/>
   <updated>2006-10-03T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/10/03/hopscotch</id>
   <content type="html">&lt;p&gt;Moved servers and changed stuff around a bit, so things might be hectic for a day or two. I&amp;#8217;ll get the feeds working from the old URLs here shortly.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;d put animated construction banners up just to be nostalgic, but I don&amp;#8217;t feel that lame today.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Getting to know Io</title>
   <link href="http://codefluency.com/2006/10/03/getting-to-know-io.html"/>
   <updated>2006-10-03T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/10/03/getting-to-know-io</id>
   <content type="html">&lt;p&gt;Those of you who know me well know that I&amp;#8217;m a fan of languages. You could say this is one of my defining characteristics&amp;#8211; right next to my addiction to caffeinated beverages&lt;/p&gt;

&lt;p&gt;Provided a language meets a small set of criteria (cross platform, free) and has some unique characteristic(s) that catch my attention, I&amp;#8217;ll give it a look. To do otherwise would just be narrow-minded (which is the same thing as being self-destructive, as a developer).&lt;/p&gt;

&lt;p&gt;&lt;a href='http://iolanguage.com'&gt;Io&lt;/a&gt; is just such a language. I&amp;#8217;ve run into it a few times over the last few years, and as I&amp;#8217;ve noticed an increase in interest in this fairly young language (especially by fellow Rubyists), I thought I&amp;#8217;d show it some attention.&lt;/p&gt;

&lt;p&gt;In this article I&amp;#8217;m just going to discuss the very basic concepts of prototypes&lt;/p&gt;

&lt;h4 id='classless_is_classy'&gt;Classless is Classy&lt;/h4&gt;

&lt;p&gt;Io can be a bit of a shock for those that haven&amp;#8217;t played with other prototype languages like &lt;a href='http://research.sun.com/self/language.html'&gt;Self&lt;/a&gt;; we&amp;#8217;re talking about a classless OO language here. Objects are just that&amp;#8211; objects. The idea that there are special &amp;#8220;blueprints&amp;#8221; to an object simply doesn&amp;#8217;t exist as a first-class concept.&lt;/p&gt;

&lt;p&gt;Is this a class?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Car := Object clone&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;No, Car here is just an object, and so is Object. We can treat this incarnation as a class (cloning more objects from it), or we can just add data and logic to it for immediate use. For this example, let&amp;#8217;s show how it can be used as a class, since we&amp;#8217;ll want to have a whole autobahn of cars.&lt;/p&gt;

&lt;h4 id='slots_are_just_that'&gt;Slots are just that&lt;/h4&gt;

&lt;p&gt;, Objects have &amp;#8220;slots,&amp;#8221; which, essentially, are the list of messages that it responds to. &amp;#8220;Car&amp;#8221; in this example, is a slot in the Lobby object, the object our program is running inside. We could have written it Lobby Car := Object clone, instead.&lt;/p&gt;

&lt;p&gt;Now let&amp;#8217;s add a few slots to Car. These simple ones are somewhat analogous to &lt;code&gt;attr_accessor&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Car newSlot(&amp;quot;make&amp;quot;)
Car newSlot(&amp;quot;model&amp;quot;)
Car newSlot(&amp;quot;mpg&amp;quot;)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which just create blank slots for &amp;#8220;make&amp;#8221; and &amp;#8220;model.&amp;#8221; We can also assign slots directly. Let&amp;#8217;s pretend all cars come with a full 16 gallon tank of gas, and there&amp;#8217;s nothing on the odometer.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Car fuel := 16
Car milesDriven := 0&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A slot is just a slot, and can also hold a method. Let&amp;#8217;s make this baby roll. The syntax might seem odd at first, but you&amp;#8217;ll pick it up.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Car drive := method(miles,
  fuelToUse := miles / mpg
  if(fuelToUse &amp;gt; fuel,
    &amp;quot;Fill &amp;#39;er up first&amp;quot; println
    false
  ,
    milesDriven = milesDriven + miles
    fuel = fuel - fuelToUse
    &amp;quot;Miles Driven: #{milesDriven}, Fuel: #{fuel}&amp;quot; interpolate println
    true
  )
)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Something worth mentioning is the fact that the name Io, while short and sweet&amp;#8211; and a name I particulary like&amp;#8211; can make google searches for material pretty tricky. I recommend io language as a search term instead of the more false positive-prone io.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>A Child is Born (again)</title>
   <link href="http://codefluency.com/2006/09/13/a-child-is-born-again.html"/>
   <updated>2006-09-13T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/09/13/a-child-is-born-again</id>
   <content type="html">&lt;p&gt;My second child (and son), Jamis Peter Williams, was born at 8:46pm MST yesterday, the 11th of September.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;re tired, and excited, and happy&amp;#8211; and tired. I&amp;#8217;ll get back to the grindstone soon, but I&amp;#8217;m taking a short break for now.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Hotkey Plugin</title>
   <link href="http://codefluency.com/2006/08/22/hotkey-plugin.html"/>
   <updated>2006-08-22T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/08/22/hotkey-plugin</id>
   <content type="html">&lt;p&gt;Recently I needed to add hotkeys to our application for quick navigation. The result of this work is the Hotkey plugin, which I&amp;#8217;m releasing today.&lt;/p&gt;

&lt;p&gt;The Hotkey plugin consists of a Javascript file and three helpers that use it. You can add a hotkey using Javascript directly using the Hotkey.add() function in your application.js, or you can use the helpers in your templates. Here&amp;#8217;s a few examples of helper usage:&lt;/p&gt;

&lt;p&gt;Calling an action remotely:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;%= hotkey_to_remote :d, :url =&amp;gt; {:controller=&amp;gt;&amp;#39;some_controller&amp;#39;} %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Changing browser location:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;%= hotkey_to :h, :controller =&amp;gt; &amp;#39;home&amp;#39; %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Calling an arbitrary function:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;%= hotkey_to_function :p, &amp;quot;showPreferencesPanel();&amp;quot; %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here we&amp;#8217;ve defined three hotkeys; d, h, and p. Pressing a modifier key (which modifier key depends on the browser/platform you&amp;#8217;re using) and the letter activates the associated function.&lt;/p&gt;

&lt;p&gt;The plugin is very easy to use, and suits our needs. Hopefully it will help out a few others.&lt;/p&gt;

&lt;p&gt;Take a look at the README after installation for additional setup information.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update 2008&lt;/em&gt; I avoid &amp;#8220;obtrusive&amp;#8221; javascript whenever possible, so I don&amp;#8217;t recommend this approach any longer.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views,  Upgrade to 1.1.6!</title>
   <link href="http://codefluency.com/2006/08/09/rails-views-upgrade-to-1-1-6.html"/>
   <updated>2006-08-09T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/08/09/rails-views-upgrade-to-1-1-6</id>
   <content type="html">&lt;p&gt;A quick aside, since it&amp;#8217;s important:&lt;/p&gt;

&lt;p&gt;In case you haven&amp;#8217;t already heard the &lt;a href='http://weblog.rubyonrails.org/2006/8/9/rails-1-1-5-mandatory-security-'&gt;news&lt;/a&gt;, &lt;strong&gt;make sure you upgrade to 1.1.5 1.1.6 immediately&lt;/strong&gt; due to a security issue in previous versions of Rails.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re running Edge Rails, you&amp;#8217;re okay.&lt;/p&gt;

&lt;p&gt;patch-and-other-tidbits&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views,  Rails Edge</title>
   <link href="http://codefluency.com/2006/08/08/rails-views-rails-edge.html"/>
   <updated>2006-08-08T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/08/08/rails-views-rails-edge</id>
   <content type="html">&lt;p&gt;Recently I accepted an invitation to be a speaker at &lt;a href='http://pragmaticstudio.com/therailsedge/'&gt;The Rails Edge&lt;/a&gt;, a series of unique Rails-related conferences brought to you by the folks at &lt;a href='http://pragmaticstudio.com/'&gt;The Pragmatic Studio&lt;/a&gt;. It&amp;#8217;s an honor to be included alongside some of the smartest Rubyists/Railers out there.&lt;/p&gt;

&lt;p&gt;My focus, as you might imagine, will be the development of Rails views&amp;#8211; building small frameworks to minimize the chaos &lt;span&gt;inherent in the view layer of any framework&lt;/span&gt;. I&amp;#8217;ll go beyond the scope of the Rails Views series you&amp;#8217;ve been reading here, delving into the implementation of the frameworks I&amp;#8217;ve put together, and talking a bit more about my personal approach to developing views.&lt;/p&gt;

&lt;p&gt;The first Rails Edge event is in Denver, November 14-16. I hope to see you there!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Buzzwords and Pitchforks</title>
   <link href="http://codefluency.com/2006/07/17/buzzwords-and-pitchforks.html"/>
   <updated>2006-07-17T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/07/17/buzzwords-and-pitchforks</id>
   <content type="html">&lt;p&gt;A large portion of my life has been dedicated to the study of language. I studied and worked professionally with Arabic for a number of years, and have picked up little bits and pieces of various other languages as I&amp;#8217;ve played around with them. I&amp;#8217;m learning Hindi now, though more slowly than I&amp;#8217;d like (anyone giving away free Hindi lessons near Boulder, CO?), and I&amp;#8217;ll probably continue to tinker with languages until my dying day.&lt;/p&gt;

&lt;p&gt;One of the funnier things about language is the way it changes over time&amp;#8211; and in different circumstances. English is a good example of this; it&amp;#8217;s changed so much in the past thousand or so years, and is such an amalgam of &lt;em&gt;other&lt;/em&gt; languages, that it barely resembles the language it once was.&lt;/p&gt;

&lt;p&gt;The changes can come pretty fast, too&amp;#8211; especially in the IT industry. Our vocabulary is a constantly shifting landscape, brought on by various technologies coming to the forefront and slowly fading away&amp;#8211; a landscape punctuated by buzzwords and the IT community&amp;#8217;s reaction to them.&lt;/p&gt;

&lt;p&gt;Buzzwords, we think, are like marketing slogans. Those of us that consider ourselves really &lt;em&gt;hardcore developers&lt;/em&gt; think of them as some type of business scourge&amp;#8211; the worst kind of proprietary technology marketing, little word- sized billboards advertising techniques and materials of no value whatsoever, attached to projects at a whim to garner attention.&lt;/p&gt;

&lt;p&gt;Buzzwords are so hated, in fact, we have &lt;em&gt;Anti-Buzzword Buzzwords&lt;/em&gt;. Mocking phrases like &amp;#8220;Buzzword Compliant&amp;#8221; to describe a group or project, a label of irrelevancy. We sneer, or pointedly ignore, anything tainted with buzzwords, considering them beneath our dignity.&lt;/p&gt;

&lt;p&gt;The Rails community has been under attack since its inception for &lt;em&gt;buzzword compliance&lt;/em&gt;, especially since Prototype (and RJS) cause the dreaded &amp;#8220;AJAX&amp;#8221; word to be uttered pretty regularly by &lt;span&gt;what we&amp;#8217;re now calling&lt;/span&gt; Railers.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s the thing. I think sometimes a buzzword is just a common word for something&amp;#8211; a word that everyone immediately understands when it is said. It&amp;#8217;s counter-productive to describe something by anything other than the most common, understandable term&amp;#8211; and for that reason I support using &amp;#8220;AJAX,&amp;#8221; to describe that particular set of technologies that XmlHTTPRequest is a part of.&lt;/p&gt;

&lt;p&gt;But watch out next time you mention &amp;#8220;AJAX&amp;#8221; on the streets; there are literally droves of XmlHTTPRequest language purists out there with torches, pitchforks, and stacks of prosaic blog entries&amp;#8211; they could very well drive you crazy with their incessant whining.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views,  Preprocessing Parameters</title>
   <link href="http://codefluency.com/2006/07/14/rails-views-preprocessing-parameters.html"/>
   <updated>2006-07-14T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/07/14/rails-views-preprocessing-parameters</id>
   <content type="html">&lt;p&gt;I&amp;#8217;m a long-time lover of the simplicity of YAML, especially the underused &lt;a href='http://yaml4r.sourceforge.net/doc/class/yaml_add_domain_type_method.htm'&gt;domain type&lt;/a&gt; functionality. There&amp;#8217;s just something about taking some chunk of text and saying &amp;#8220;turn this into an X using the following process&amp;#8221; and having it take care of things for me that&amp;#8217;s just &lt;em&gt;cool&lt;/em&gt;. Recently, I&amp;#8217;ve put together something similar, but less structured, for params hashes, that I&amp;#8217;m releasing as a plugin called param types.&lt;/p&gt;

&lt;p&gt;Using param types is simple. First we define the different types we want to support, and how to convert values to them. Here&amp;#8217;s an example for supporting multiple formats of incoming date parameters (I put this in environment.rb, but you can do it elsewhere):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  ActionController::Base.add_param_type &amp;#39;date&amp;#39; do |value|
    case value
    when String
      Date.parse(value)
    when Hash
      Date.new(Integer(value[&amp;#39;year&amp;#39;]), Integer(value[&amp;#39;month&amp;#39;]), Integer(value[&amp;#39;day&amp;#39;]))
    end
  end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here we&amp;#8217;re registering a new param type &amp;#8216;date&amp;#8217;, and giving it a block to convert values. The block will be yielded the raw value of any incoming parameter matching the type you&amp;#8217;ve defined, and the value returned by the block will be the new value of the parameter.&lt;/p&gt;

&lt;p&gt;How do we say, on the view side, that a parameter (ie, form element) should be considered a particular type? A naming convention, of course.&lt;/p&gt;

&lt;p&gt;Param types are defined by the use of parenthesis. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  &amp;lt;%= text_field_tag &amp;#39;birthday(date)&amp;#39; %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This defines a parameter, &amp;#8216;birthday&amp;#8217;, with the param type &amp;#8216;date&amp;#8217;. Since we&amp;#8217;ve defined a &amp;#8216;date&amp;#8217; param type, we&amp;#8217;ll end up with &lt;code&gt;params[:birthday]&lt;/code&gt; (converted to a Date by our block) rather than a plain &lt;code&gt;params[&amp;quot;birthday(date)&amp;quot;]&lt;/code&gt; String.&lt;/p&gt;

&lt;p&gt;It works with nesting, too.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  &amp;lt;%= text_field_tag &amp;#39;student[birthday(date)]&amp;#39; %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this case, you&amp;#8217;d end up with params&lt;span&gt;:student&lt;/span&gt;, as you might expect.&lt;/p&gt;

&lt;p&gt;The &amp;#8216;date&amp;#8217; example above could also handle a Hash of date components, like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  &amp;lt;%= text_field_tag &amp;#39;birthday(date)[day]&amp;#39; %&amp;gt;
  &amp;lt;%= text_field_tag &amp;#39;birthday(date)[month]&amp;#39; %&amp;gt;
  &amp;lt;%= text_field_tag &amp;#39;birthday(date)[year]&amp;#39; %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;â€¦ or as selects, of course&amp;#8211; and it will put the date together (as params&lt;span&gt;:birthday&lt;/span&gt;) for you.&lt;/p&gt;

&lt;p&gt;This is really just the tip of the iceberg&amp;#8211; since params are converted depth- first, you can use the results of deeper conversions in shallower ones&amp;#8211; making the building of really complex types possible.&lt;/p&gt;

&lt;p&gt;If this sounds interesting, feel free to look at the &lt;a href='http://svn.codefluency.com/rails/plugins/param_types/README'&gt;README&lt;/a&gt; and install the plugin:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  ruby script/plugin source http://svn.codefluency.com/rails/plugins/
  ruby script/plugin install param_types&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you may know, I&amp;#8217;m a big fan of &lt;code&gt;form_for&lt;/code&gt; and &lt;code&gt;FormBuilder&lt;/code&gt;. I&amp;#8217;ll be going over how to integrate &lt;code&gt;param_types&lt;/code&gt; with them soon, so stay tuned.&lt;/p&gt;

&lt;p&gt;One of the trickiest things to deal with when developing complex interfaces in Rails is how to pass along objects as parameters.&lt;/p&gt;

&lt;p&gt;This is easy when you&amp;#8217;re dealing with simple bits of data&amp;#8211; values in params are strings, and with some PHP-like magic with brackets, we get arrays and hashes of them. This is all part of built-in actionpack functionality. Integers (Fixnums) are easy, since parsing them on the action side is as simple as &lt;code&gt;to_i&lt;/code&gt; (or, for the savvy, &lt;code&gt;Integer()&lt;/code&gt;)&amp;#8211; and a lot of the time we&amp;#8217;re using them in conjunction with ActiveRecord::Base#find anyway.&lt;/p&gt;

&lt;p&gt;So how do we handle more complex cases? How do we pass along more complex objects?&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s start with dates. Sure, sure, Rails has &lt;code&gt;date_select&lt;/code&gt;, &lt;code&gt;select_date&lt;/code&gt;, etc, and they have their own bit of special-case magic that handles date conversions. But let&amp;#8217;s be serious here&amp;#8211; does anyone &lt;em&gt;love&lt;/em&gt; the interface that these provide? Not that we should complain, mind you&amp;#8211; they&amp;#8217;re free and in a lot of cases they&amp;#8217;re all we needâ€¦ but for a consumer app, the sad fact is that a lot of us end up rolling our own date/time widgets (ie, with AJAX calendars). Then we go about manually parsing dates out of params using before&lt;em&gt;filters or even calls to private methods directly from actions.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This manual parsing is no fun, folks&amp;#8211; and it&amp;#8217;s not limited to dates. There&amp;#8217;s a lot of cases where data coming in from requests needs to be munged for one purpose or another, and having to keep track, on the action side, of what needs to be converted is tedious&amp;#8211; and, in my opinion, somewhat inappropriate for the action side of the relationship. I want the actions to &lt;em&gt;do&lt;/em&gt; stuff, not to be manually told to convert/parse the parameters that tell it what to do, &lt;em&gt;then&lt;/em&gt; do stuff.&lt;/p&gt;

&lt;p&gt;Can we make this more transparent?&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Safari and the Stray Comma</title>
   <link href="http://codefluency.com/2006/07/10/safari-and-the-stray-comma.html"/>
   <updated>2006-07-10T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/07/10/safari-and-the-stray-comma</id>
   <content type="html">&lt;p&gt;Here&amp;#8217;s a little tidbit. Safari doesn&amp;#8217;t like stray commas in Javascript (Firefox just ignores them, and IE is too busy choking on everything else to notice). Here&amp;#8217;s an example of an offense:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;new Effect.Highlight(&amp;#39;foo&amp;#39;, {duration:0.5,startcolor:&amp;#39;#ff99ff&amp;#39;,});&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;See that extra trailing comma? Safari completely &lt;em&gt;hates&lt;/em&gt; it. No neat highlight for you&amp;#8211; sloppy coders are punished severely in Safari-land.&lt;/p&gt;

&lt;p&gt;A few months back, I added a test to catch these. It goes something like this (it&amp;#8217;s weak, I know, but it works):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  def test_no_stray_commas_for_safari
    Dir[File::join(RAILS_ROOT,&amp;#39;public/javascripts&amp;#39;,&amp;#39;*.js&amp;#39;)].each do |filename|
      found = File::read(filename) =~ /([^\r\n]*),\s*[\]\})]/sm
      assert_nil (found, &amp;quot;Found possible stray comma in #{File::basename filename} at char index #{found} near:\n--START JAVASCRIPT--\n#{$1}\n--END JAVASCRIPT--&amp;quot; )
    end
  end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;â€¦ and, what do you know, today it saves the day.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views,  Getting In Context</title>
   <link href="http://codefluency.com/2006/07/02/rails-views-getting-in-context.html"/>
   <updated>2006-07-02T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/07/02/rails-views-getting-in-context</id>
   <content type="html">&lt;p&gt;In the view, you need to set the &lt;em&gt;context parameter. If you&amp;#8217;re using &lt;code&gt;link_to_remote&lt;/code&gt;, just set it manually. If you&amp;#8217;re using a form, you can use the &lt;code&gt;context_tag&lt;/code&gt; helper. Here&amp;#8217;s examples of both in action:&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  &amp;lt;%= link_to_remote &amp;quot;Complete&amp;quot;, :url =&amp;gt; {:controller =&amp;gt; &amp;#39;items&amp;#39;, :action =&amp;gt; &amp;#39;update&amp;#39;, :id =&amp;gt; item, :params =&amp;gt;{:complete=&amp;gt;true,:_context =&amp;gt; &amp;quot;Workflow One&amp;quot;}} %&amp;gt;

&amp;lt;% remote_form_for :item, item, :url =&amp;gt; {:controller =&amp;gt; &amp;#39;items&amp;#39;, :action =&amp;gt; &amp;#39;update&amp;#39;, :id =&amp;gt; item} do |f| %&amp;gt;
  &amp;lt;%= context_tag &amp;quot;Workflow Two&amp;quot; %&amp;gt;
  &amp;lt;%= check_box_tag :complete, true %&amp;gt;
  &amp;lt;!-- Other Stuff Here --&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Both of these hit one action, update. In it, we can use &lt;code&gt;in_context&lt;/code&gt; to wrap our separate renders (mixing with respond&lt;em&gt;to).&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def update
  # Update stuff here
  respond_to do |format|
    format.html
    format.js do
      render :update do |page|
        # Stuff at this point happens regardless of context
        in_context do |context|
          context.nil? do
            # This happens if no context is passed
          end
          context.workflow_one do
            # For the link
          end
          context.workflow_two do
            # For the form
          end
        end
      end
    end
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If this looks like something that might help out, feel free to get it at &lt;a href='http://svn.codefluency.com/rails/plugins/context'&gt;http://svn.codefluency.com/rails/plugins/context&lt;/a&gt;. I&amp;#8217;ll put it up on the Plugins page for installation via script/plugin install once the page editing is working again (it&amp;#8217;s giving me a 500 error at the moment).&lt;/p&gt;

&lt;p&gt;As usual, you can drop me a line if you have questions, suggestions, or comments.&lt;/p&gt;

&lt;p&gt;So, here&amp;#8217;s the problem. Let&amp;#8217;s say that, in our application, we have different types of users that need to be able to do the &lt;em&gt;same thing&lt;/em&gt; from &lt;em&gt;different places&lt;/em&gt;. Their workflows are different&amp;#8211; maybe one manages a list of items that need to be completed (they sit on that page, all day long, doing just that), and another visits each item&amp;#8217;s page separately (in the process of managing more of the item&amp;#8217;s information) and may complete items individually from that interface.&lt;/p&gt;

&lt;p&gt;We need to support both ways of completing items&amp;#8211; or maybe even more, and we want completion to occur via AJAX. Support for multiple workflows is a natural feature of complex products; the messy truth is that, sometimes, there&amp;#8217;s no &lt;em&gt;One Interface to Rule Them All&lt;/em&gt;. The land of picky users with long- established workflows, sadly, is not a minimalist Utopia.&lt;/p&gt;

&lt;p&gt;Of course, if all our workflows are hitting the same controller action, the action needs to be aware of the context&amp;#8211; different javascript may need to be returned for each workflow (we might reload a div in one case, and remove the item from a list in another, for example). We &lt;em&gt;could&lt;/em&gt; just have a different action to support each interface&amp;#8211; but that&amp;#8217;s a bad kludge I won&amp;#8217;t even address. I support the single-action, selective-render approach for the same reason I use &lt;code&gt;respond_to&lt;/code&gt; instead of having separate actions for HTML and JS requests&amp;#8211; sure, it might be verbose, but at least it&amp;#8217;s DRY.&lt;/p&gt;

&lt;p&gt;So, how do we let our action know the context from which it&amp;#8217;s being called? There&amp;#8217;s really not a clean option, since relying on referer is a bad idea (not to mention not enough information), but one approach&amp;#8211; the one I use&amp;#8211; is to pass along a parameter in requests, and have the action check for it, rendering the correct response. Since this can be a bit tedious (not to mention ugly) in practice, I&amp;#8217;ve put together a little plugin called &lt;em&gt;context&lt;/em&gt; to help out. Here&amp;#8217;s how to use it.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views, Bulletproofing dom_id</title>
   <link href="http://codefluency.com/2006/07/02/rails-views-bulletproofing-dom_id.html"/>
   <updated>2006-07-02T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/07/02/rails-views-bulletproofing-dom_id</id>
   <content type="html">&lt;p&gt;In my eternal quest to stave off DOM ID collision, I recently had to make a few small changes to the original &lt;span&gt;dom&lt;em&gt;id]&lt;a href='/2006/05/30/rails-views-active-record-dom-ids.html'&gt;1&lt;/a&gt; script from the indomitable Jamis Buck.&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recently, I needed two forms on the same page for two models from the same single-table inheritance table (though that&amp;#8217;s not part of the issue), and I wanted to use the same prefix for both. Since the vanilla &lt;code&gt;dom_id&lt;/code&gt; scheme removes the class name when a prefix is defined, collision would occur. My modifications ensure the class name is always included&amp;#8211; after all, I don&amp;#8217;t care how long the DOM ID is&amp;#8211; part of the beauty is I don&amp;#8217;t even have to know what&amp;#8217;s being generated.&lt;/li&gt;

&lt;li&gt;I removed the :bare prefix option, as I never use it (though some of you may).&lt;/li&gt;

&lt;li&gt;I replaced dashes with underscores. I prefer dashes, myself (for CSS classes, too), but due to the reported issues with dasherized ids and scriptaculous drag-and-drop (a feature I use very, very rarely), I&amp;#8217;m reluctantly letting them go.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some examples:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; person = Person.find(:first)
&amp;gt;&amp;gt; person.dom_id
=&amp;gt; &amp;quot;student_1&amp;quot; # Note: The first person is a Student
&amp;gt;&amp;gt; person.`dom_id` &amp;#39;some_prefix&amp;#39;
=&amp;gt; &amp;quot;some_prefix_student_1&amp;quot;
&amp;gt;&amp;gt; Person.new.dom_id
=&amp;gt; &amp;quot;person_new&amp;quot;
&amp;gt;&amp;gt; Person.new.`dom_id` &amp;#39;some_prefix&amp;#39;
=&amp;gt; &amp;quot;some_prefix_person_new&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Keep in mind that, since my original posting, a few people have released slightly-modified &lt;em&gt;plugin&lt;/em&gt; versions of &lt;code&gt;dom_id&lt;/code&gt; (most notably &lt;a href='http://topfunky.net/svn/plugins/dom_id/'&gt;Geoffrey Grosenbach&lt;/a&gt;). They might already meet your needs.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>RailsConf Facebook</title>
   <link href="http://codefluency.com/2006/06/20/railsconf-facebook.html"/>
   <updated>2006-06-20T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/06/20/railsconf-facebook</id>
   <content type="html">&lt;p&gt;The facebook for RailsConf 2006 is &lt;a href='http://facebook.railsconf.org/'&gt;up and running&lt;/a&gt;&amp;#8211; if you&amp;#8217;re going to the conference, don&amp;#8217;t forget to post!&lt;/p&gt;

&lt;p&gt;Many thanks to &lt;a href='http://techno-weenie.net/'&gt;Rick Olson&lt;/a&gt; who created the facebook app; I just themed it for the conference.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views, Spring Cleaning</title>
   <link href="http://codefluency.com/2006/06/19/rails-views-spring-cleaning.html"/>
   <updated>2006-06-19T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/06/19/rails-views-spring-cleaning</id>
   <content type="html">&lt;p&gt;The way I do this is with a Rake task. Rake and Rails go so well together, and we already have a boatload of custom Rake tasks in our app, so it was an easy decision.&lt;/p&gt;

&lt;p&gt;Basically, what I wanted was a quick way to see what helpers and actions weren&amp;#8217;t being used. Just a simple list that I could use to help me find things that we &lt;em&gt;probably&lt;/em&gt; didn&amp;#8217;t need anymore.&lt;/p&gt;

&lt;p&gt;So here it is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep in mind this is &lt;em&gt;NIX only (since that&amp;#8217;s all I care about, currently), and is in no way comprehensive. Someone could easily make this pure-Ruby, safer, or simply more intelligent.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre&gt;&lt;code&gt;namespace :stale do
  task :helpers do
    stale_for_glob &amp;#39;app/helpers/*_helper.rb&amp;#39;
  end
  task :actions do
    stale_for_glob &amp;#39;app/controllers/*_controller.rb&amp;#39;
  end

  def stale_for_glob(glob)
    Dir[glob].each do |filename|
      File.open(filename) do |file|
        file.each do |line|
         if line =~ /^\s*def\s+([[:alnum:]_]+)/
           meth = $1
           if `grep -R &amp;#39;#{meth}&amp;#39; app vendor/plugins | grep -v svn`.strip.split(&amp;quot;\n&amp;quot;).size &amp;lt;= 1
             $stderr.puts &amp;quot;#{filename} : #{meth}&amp;quot;
           end
         end
        end
      end
    end
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What does this do? Well, it looks though the helper (or controller) files, and tries to find helpers (or actions) that are only &lt;em&gt;defined&lt;/em&gt; and not &lt;em&gt;used&lt;/em&gt;. Granted, it&amp;#8217;s not flawless. If you have helpers or actions that have the same name and are defined in different files (&lt;em&gt;not&lt;/em&gt; an edge case), there&amp;#8217;ll be false negatives. You&amp;#8217;ll also need to run it several times as you remove items, since one helper may only be called from another that you&amp;#8217;ve removed. Don&amp;#8217;t just rip out all the helpers (or actions) that show up in the results, either. Maybe they&amp;#8217;re just not being used yet (and maybe they&amp;#8217;re the hard work of your fellow developers, too).&lt;/p&gt;

&lt;p&gt;Don&amp;#8217;t forget to remove the test cases for anything you remove, too.&lt;/p&gt;

&lt;p&gt;The point here is to dredge up old helpers and actions that, when you see them, will cause a lightbulb to go off over you head. Maybe you&amp;#8217;ll exclaim, &amp;#8220;Ah, I remember that piece of crap&amp;#8211; I thought I got rid of that a month ago!&amp;#8221;&lt;/p&gt;

&lt;p&gt;Now really get rid of it. Shorter code is happier code.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re developing a large Rails application, chances are you&amp;#8217;re going to end up creating a lot of extra helpers and actions that fall into disuse&amp;#8211; helpers are generally tightly coupled with views and often exist due to design decisions that end up changing over time, and actions can just as easily become obsolete.&lt;/p&gt;

&lt;p&gt;This is a natural side-effect of long-term development. But you need to get rid of all that clutter; it affects your test statistics, it means more code to shuffle through to find things you &lt;em&gt;are&lt;/em&gt; using&amp;#8211; and it&amp;#8217;s just plain ugly to keep around.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views, Rails Recipes Selections</title>
   <link href="http://codefluency.com/2006/06/16/rails-views-rails-recipes-selections.html"/>
   <updated>2006-06-16T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/06/16/rails-views-rails-recipes-selections</id>
   <content type="html">&lt;p&gt;These are in no particular order, and certainly aren&amp;#8217;t the only recipes that I&amp;#8217;d recommend&amp;#8211; just the ones that immediately jump out at me as I flick through my copy.&lt;/p&gt;

&lt;h3 id='recipe_52_making_your_own_rails_plugins'&gt;Recipe 52: Making Your Own Rails Plugins&lt;/h3&gt;

&lt;p&gt;Plugins aren&amp;#8217;t just for monkey patches and portable &amp;#8220;drop in&amp;#8221; functionality. You can toss views into plugins as well to make your app even more modular&amp;#8211; or provide a common interface across different applications. This recipe gives you a kick start on putting together your first plugin. Plugins, people, are a mandatory skill.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: I usually create a &lt;code&gt;files/&lt;/code&gt; subdirectory inside plugins, throw my views in there, and use my good friend, &lt;code&gt;render :file&lt;/code&gt; with a relative path to take care of business.&lt;/p&gt;

&lt;h3 id='recipe_44_write_tests_for_your_helpers'&gt;Recipe 44: Write Tests for your Helpers&lt;/h3&gt;

&lt;p&gt;Now helpers can have all the stable goodness that TDD can help make possible; this recipe helps you set-up a test environment for testing these little beastiesâ€¦ something that, sadly, isn&amp;#8217;t as cut-and-dry as we&amp;#8217;d like.&lt;/p&gt;

&lt;h3 id='recipe_12_creating_a_custom_form_builder'&gt;Recipe 12: Creating a Custom Form Builder&lt;/h3&gt;

&lt;p&gt;This is really neat stuff. As I&amp;#8217;ve mentioned before, &lt;code&gt;form_for&lt;/code&gt; is the wave of the future, and FormBuilder is along for the ride. In this recipe Chad goes over how to build form builders, and highlights how useful they can be.&lt;/p&gt;

&lt;p&gt;We use a little form builder, &lt;code&gt;form_table&lt;/code&gt;, extensively in our application at work&amp;#8211; both in and out of &lt;code&gt;form_for&lt;/code&gt;. I can&amp;#8217;t even guess at the amount of time it&amp;#8217;s saved us&amp;#8211; but it&amp;#8217;s a lot!&lt;/p&gt;

&lt;h3 id='recipe_61_adding_support_for_localization'&gt;Recipe 61: Adding Support for Localization&lt;/h3&gt;

&lt;p&gt;If you&amp;#8217;re creating an interface that will have to support multiple languages, the &lt;a href='http://www.globalize-rails.org/wiki/'&gt;Globalize Plugin&lt;/a&gt; just fits the bill. In this recipe, the &lt;em&gt;extremely eloquent, good-looking&lt;/em&gt; author gives a brief overview of how to use this pivotal plugin.&lt;/p&gt;

&lt;p&gt;Okay, I admit it&amp;#8211; &lt;em&gt;I&lt;/em&gt; wrote this one. It&amp;#8217;s still really good, I promise.&lt;/p&gt;

&lt;h3 id='recipe_6_update_multiple_requests_with_one_ajax_request'&gt;Recipe 6: Update Multiple Requests with One Ajax Request&lt;/h3&gt;

&lt;p&gt;This recipe introduces you to the idea of using RJS is your responses; if you&amp;#8217;re still using :update on your link&lt;em&gt;to&lt;/em&gt;remotes (or other such tomfoolery) you&amp;#8217;ll want to give this a look.&lt;/p&gt;

&lt;h3 id='recipe_39_write_code_that_writes_code'&gt;Recipe 39: Write Code that Writes Code&lt;/h3&gt;

&lt;p&gt;In my opinion, this is one of the best recipes in the book, introducing important metaprogramming tools like &lt;code&gt;define_method&lt;/code&gt;. Metaprogramming is the staple of the truly advanced Rails programmer&amp;#8211; who is, framework knowledge aside, also an advanced Ruby programmer.&lt;/p&gt;

&lt;p&gt;If you take the knowledge you pick up in this recipe, and apply it liberally across controllers, models, and helpers (in and out of plugins), can&amp;#8217;t your application really become a language?&lt;/p&gt;

&lt;h2 id='so'&gt;So..&lt;/h2&gt;

&lt;p&gt;If you know what&amp;#8217;s good for you (and your skills), &lt;a href='http://pragmaticprogrammer.com/titles/fr_rr/'&gt;buy this book&lt;/a&gt;. If you&amp;#8217;re a sucker for instant gratification, pick up a PDF copy, too (it&amp;#8217;s great for searching).&lt;/p&gt;

&lt;p&gt;Today my copy of &lt;a href='http://pragmaticprogrammer.com/titles/fr_rr/'&gt;Rails Recipes&lt;/a&gt; arrived, fresh from the press. Things have been pretty busy for &lt;a href='http://blogs.pragprog.com/cgi-bin/pragdave.cgi'&gt;Dave Thomas&lt;/a&gt; these last few days, getting the preorders &lt;a href='http://blogs.pragprog.com/cgi-bin/pragdave.cgi/Random/ShippingRecipes.html'&gt;out the door&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re the type of developer that puts the &amp;#8216;V&amp;#8217; in &amp;#8216;MVC&amp;#8217; and are looking for a little direction, some examples of best practices, or just some really good ideas to help make you a better Rails developer, I&amp;#8217;d recommend you add this book to your library.&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s a few recipes from the book I especially think you should check out if you&amp;#8217;re into views, and here they areâ€¦&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views,  Avoiding AJAX Faux Pas</title>
   <link href="http://codefluency.com/2006/06/10/rails-views-avoiding-ajax-faux-pas.html"/>
   <updated>2006-06-10T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/06/10/rails-views-avoiding-ajax-faux-pas</id>
   <content type="html">&lt;p&gt;When developing applications that make use of AJAX, I try to remember one simple rule.&lt;/p&gt;

&lt;p&gt;1. &lt;strong&gt;Don&amp;#8217;t leave the user hanging&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s nothing more annoying to a user than &lt;em&gt;not knowing what&amp;#8217;s going on&lt;/em&gt;. If you don&amp;#8217;t keep the user informed, your application will seem &lt;em&gt;less&lt;/em&gt;, rather than &lt;em&gt;more&lt;/em&gt;, comfortable than a traditional web interface. After all, when a browser is changing locations it at least has the common decency to show that something is happening&amp;#8211; and a new page is displayed when it&amp;#8217;s done.&lt;/p&gt;

&lt;p&gt;If your users are confused and have no idea what&amp;#8217;s going on&amp;#8211; if they&amp;#8217;re not even sure your application is working&amp;#8211; have you really taken a step forward by using AJAXâ€¦ or are you just scratching a technical itch and doing your users a disservice in the process? This is about user happiness, not cool technologies.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s some basic ground rules for interacting with users during remote actions.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;You will always indicate when a remote action is occurring&lt;/strong&gt;. Show a progress indicator; spinners are common these days, but use whatever makes sense. And don&amp;#8217;t be fooled into thinking the action occurs so fast no indicator is needed&amp;#8211; it may seem nearly instantaneous on your development server (with just &lt;em&gt;you&lt;/em&gt; accessing it), but who knows what the future will hold?&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;You will always stop the progress indicator when the action is complete&lt;/strong&gt;. An ever-spinning progress indicator is pretty, but probably pretty confusing, too.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;If the action results in success, you will always show the result&lt;/strong&gt;. Reload a div, insert an element, maybe do some fancy scriptaculous &amp;#8220;Hey, look at me&amp;#8221; effects. The point here is to do &lt;em&gt;something.&lt;/em&gt; The user did something, and they want something in return.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;If the action results in failure, you will always notify the user&lt;/strong&gt;. The only thing more frustrating than not knowing that something is going on is not knowing it failed&amp;#8211; or how to fix it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, those are the rules. How do we meet them without too much fuss?&lt;/p&gt;

&lt;p&gt;First of all, let&amp;#8217;s build a little helper method to help show and hide our progress indicators (setting the :loading and :complete options). A simple implementation might look something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def showing_progress(opts={})
  opts.merge :loading  =&amp;gt; update_page{|p| p[:progress].show },
             :complete =&amp;gt; update_page{|p| p[:progress].hide }
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And, using it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;%= link_to_remote &amp;quot;Do Something Remotely&amp;quot;, showing_progress(:url=&amp;gt;some_url) %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, that leaves indicating success and failure&amp;#8211; and here&amp;#8217;s one approach. I&amp;#8217;m not a big fan of using the :success and :failure callbacks on the link/form. I think it&amp;#8217;s messier and less flexible to handle these events on the client-side than it is for the action, generating an appropriate RJS response for either outcome.&lt;/p&gt;

&lt;p&gt;So, it all comes down to rendering the result of our remote action. If there&amp;#8217;s been errors, we need to report them in a standard way&amp;#8211; but if everything is okay, we need to have the flexibility to update the page in whatever manner makes sense for that action.&lt;/p&gt;

&lt;p&gt;A good way to do this is to wrap render :update to handle both cases. Here&amp;#8217;s an example with some pretty simplistic error reporting. This can be used from any controller action (put it in application.rb).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  def reporting_errors_on(*objs)
    valid = objs.all?{|o| o.valid?}
    render :update do |page|
      if valid
        yield page
      else
        flash[:error] = objs.map{|o| o.errors.full_messages}.flatten.join(&amp;quot;\n&amp;quot;)
        page.alert flash[:error]
      end
    end
  end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, if any of the ActiveRecord objects passed into the method are invalid, the errors are reported. Otherwise, a javascript generator object is yielded to the block, and we can use it however we&amp;#8217;d like. (Note: The errors are also stored in flash, though that&amp;#8217;s primarily for functional testing purposes)&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s an example of how to use it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def add_item
  item = Item.create(params[:item])
  reporting_errors_on item do |page|
    # Success; only happens if no errors are present
    page[:items].reload
    page[item.dom_id].visual_effect :highlight
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Obviously, these aren&amp;#8217;t the only ways to handle indicating progress and notifying the user of errors. These are also fairly simplistic examples; you might want to show text with your progress indicator, for instance, or show which fields are invalid instead of just popping up an alert box.&lt;/p&gt;

&lt;p&gt;The point here is to keep your users in the loop&amp;#8211; at a minimum of pain and suffering to yourself. As in any relationship, communication is keyâ€¦ don&amp;#8217;t make the mistake of neglecting your users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;: (for the use of &lt;code&gt;ActiveRecord::Base#dom_id&lt;/code&gt;)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The Radiant Conversion</title>
   <link href="http://codefluency.com/2006/06/08/the-radiant-conversion.html"/>
   <updated>2006-06-08T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/06/08/the-radiant-conversion</id>
   <content type="html">&lt;h3 id='fixing_issues'&gt;Fixing Issues&lt;/h3&gt;

&lt;p&gt;Hopefully this conversion will fix some of the problems that were cropping up before&amp;#8211; especially the issue with invalid RSS feeds that news readers like &lt;a href='http://www.newsgator.com/NGOLProduct.aspx?ProdID=NetNewsWire'&gt;NetNewsWire&lt;/a&gt; simply wouldn&amp;#8217;t tolerate. I&amp;#8217;ve done my best to preserve things like RSS URLs (and article URLs too, to some degree), but I recommend you update any feed subscriptions you have with the new locations&amp;#8211; using autodiscovery or by looking in the sidebar.&lt;/p&gt;

&lt;p&gt;In terms of running the site, I&amp;#8217;m finding Mongrel with &lt;a href='http://apache.org'&gt;Apache&lt;/a&gt; forwarding to be a lot more reliable than fcgi, so performance should be a better&amp;#8211; especially on heavy &lt;a href='http://weblog.rubyonrails.org/'&gt;Rails Weblog&lt;/a&gt; and &lt;a href='http://project.ioni.st'&gt;project.ioni.st&lt;/a&gt; traffic days.&lt;/p&gt;

&lt;p&gt;If you &lt;em&gt;do&lt;/em&gt; notice any problems, please drop me an email . I&amp;#8217;ve copied over all of the old comments (as of yesterday), but commenting will be down for a few days.&lt;/p&gt;

&lt;h3 id='why_radiant'&gt;Why Radiant?&lt;/h3&gt;

&lt;p&gt;I&amp;#8217;ve known for a while that I needed to move to a full CMS; the plain blog structure is nice and simple&amp;#8211; and don&amp;#8217;t get me wrong, that&amp;#8217;s a Good Thing&amp;#8211; but I&amp;#8217;ve been aching for a bit more control over the format of the site. After a bit of searching, I decided Radiant was the best choice; it&amp;#8217;s written on top of Rails, has an interesting premise&amp;#8211; and is proving to be exceedingly fun to play with.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://wiseheartdesign.com/'&gt;John W. Long&lt;/a&gt; and the rest of the Radiant developers have really put together a compelling system that deserves some attention. Radiant hasn&amp;#8217;t been technically released, so there&amp;#8217;s still some things missing that you might be looking for; but if you&amp;#8217;re an early adopter and like to look at cool new things, I sincerely recommend it.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;ve been here before, you may notice things have changed a bit.&lt;/p&gt;

&lt;p&gt;Besides the obvious design changes, there&amp;#8217;s a lot that&amp;#8217;s different under the covers. I&amp;#8217;ve switched from &lt;a href='http://typosphere.org'&gt;Typo&lt;/a&gt; on fcgi to &lt;a href='http://radiantcms.org'&gt;Radiant CMS&lt;/a&gt; on &lt;a href='http://mongrel.rubyforge.org'&gt;Mongrel&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views,  Using the :with option</title>
   <link href="http://codefluency.com/2006/06/02/rails-views-using-the-with-option.html"/>
   <updated>2006-06-02T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/06/02/rails-views-using-the-with-option</id>
   <content type="html">&lt;p&gt;People forget this little gotcha all the time, even though it&amp;#8217;s in the &lt;a href='http://api.rubyonrails.org'&gt;Rails API Documentation&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If you specify a string &lt;span&gt;for the :with option&lt;/span&gt; without a &amp;#8221;=&amp;#8221;, it&amp;#8217;ll be extended to mean the form key that the value should be assigned to.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What this ends up meaning is that if you do something like &lt;code&gt;:with =&amp;gt; &amp;#39;foo&amp;#39;&lt;/code&gt; Rails will automagically generate a query string that equates to something like: &lt;code&gt;&amp;quot;&amp;#39;foo=&amp;#39; + value&amp;quot;&lt;/code&gt; (just passing along whatever&amp;#8217;s in the value variable, something that makes sense in the context of &lt;code&gt;observe_field&lt;/code&gt;, specifically). Neat, right?&lt;/p&gt;

&lt;p&gt;Right â€¦ but if you try to use your own custom function to generate the whole query string, or make use of something like Form.serialize() without including a = inline in the option, Rails&amp;#8217; magic backfires and you end up with a fizzled remote action. This, for instance, is completely useless:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;%= link_to_remote &amp;quot;Foo&amp;quot;, :url =&amp;gt; some_url, :with =&amp;gt; &amp;quot;Form.serialize(&amp;#39;some-form&amp;#39;)&amp;quot; %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;No &lt;code&gt;=&lt;/code&gt;, so we end up with a mangled query string.&lt;/p&gt;

&lt;p&gt;So, what&amp;#8217;s the solution? Well â€¦ I&amp;#8217;ll tell you what I do; just give it what it wants:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;%= link_to_remote &amp;quot;Foo&amp;quot;, :url =&amp;gt; some_url, :with =&amp;gt; &amp;quot;Form.serialize(&amp;#39;some-form&amp;#39;)+&amp;#39;&amp;amp;=&amp;#39;&amp;quot; %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pass along a bogus query string pair, just to eke out a =. Fight hackery with hackery.&lt;/p&gt;

&lt;p&gt;One more gotcha, before you run off and inexplicably use that little bit of pedantic, arcane lore for some crazy reason:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don&amp;#8217;t&lt;/strong&gt; put a semicolon at the end of the :with option value. Hold back â€¦ or you&amp;#8217;ll just end up with a syntax error. (&lt;em&gt;It&amp;#8217;s inserted into a Javascript options object, essentially a Hash, and doesn&amp;#8217;t stand alone as a separate statement like you might expect.&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;This entry probably has a bit of a specialized audience, but I think it needed saying regardless.&lt;/p&gt;

&lt;p&gt;One of the key &amp;#8220;sneaky&amp;#8221; aspects of developing AJAX applications in Rails is the use of the :with option, available in about all of the AJAX-related methods. This option is used to dynamically generate a query string (meaning params, once it hits the server) using Javascript. This allows you to roll your own parameters, freestyle, with DOM lookups.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s pretty neat stuff (especially when playing with &lt;code&gt;observe_field&lt;/code&gt; and observe&lt;em&gt;form), but it can be pretty tricky. Here&amp;#8217;s a couple things to look out for.&lt;/em&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Ruby for Rails Arrives</title>
   <link href="http://codefluency.com/2006/05/31/ruby-for-rails-arrives.html"/>
   <updated>2006-05-31T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/05/31/ruby-for-rails-arrives</id>
   <content type="html">&lt;p&gt;So, today my fresh, dead-tree copy of &lt;a href='http://www.manning.com/black/'&gt;Ruby for Rails&lt;/a&gt; arrived.&lt;/p&gt;

&lt;p&gt;As the technical proofreader for this excellent book by David A. Black, I&amp;#8217;ve obviously spent some time reading it in depth â€¦ but seeing the final result sitting on my table is still pretty impressive.&lt;/p&gt;

&lt;p&gt;For those of you that don&amp;#8217;t know, David has been a leading member of the Ruby community since long before &lt;a href='http://rubyonrails.org'&gt;Rails&lt;/a&gt; was a twinkle in DHH&amp;#8217;s eye (who, by the way, wrote the foreword for the book). He&amp;#8217;s one of the directors of &lt;a href='http://rubycentral.org'&gt;Ruby Central&lt;/a&gt;, the parent organization for the official Ruby and Rails conferences, and &lt;em&gt;knows&lt;/em&gt; Ruby.&lt;/p&gt;

&lt;p&gt;In the book David did some great work explaining the language in depth and delving into Rails from a Ruby perspective; if you&amp;#8217;re a Ruby programmer by way of being a Rails developer, this book is the one to pick up to help you understand the underlying language.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views,  Block Helper Example</title>
   <link href="http://codefluency.com/2006/05/31/rails-views-block-helper-example.html"/>
   <updated>2006-05-31T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/05/31/rails-views-block-helper-example</id>
   <content type="html">&lt;p&gt;A few articles back, I mentioned how useful helpers that take blocks can be within your views.&lt;/p&gt;

&lt;p&gt;I thought I&amp;#8217;d give a little example, giving a helper I find pretty useful in my own projects.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s the code, which I&amp;#8217;ll explain in a moment:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def link_to_section(name, html_opts={}, &amp;amp;block)
  section_id = name.underscore.gsub(/\s+/,&amp;#39;_&amp;#39;)
  link_id = section_id + &amp;#39;_link&amp;#39;
  # Link
  concat(link_to_function(name,update_page{|page|
    page[section_id].show
    page[link_id].hide
  }, html_opts.update(:id=&amp;gt;link_id)), block.binding)
  # Hidden section
  concat(tag(&amp;#39;div&amp;#39;, {:id=&amp;gt;section_id, :style=&amp;gt;&amp;#39;display:none;&amp;#39;},true),block.binding)
  yield update_page{|page|
 page[section_id].hide
    page[link_id].show
  }
  concat(&amp;#39;&amp;lt;/div&amp;gt;&amp;#39;, block.binding)
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What this makes possible is stuff like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;% link_to_section(&amp;quot;View Details&amp;quot;) do |closer| %&amp;gt;
  &amp;lt;h4&amp;gt;Details&amp;lt;/h4&amp;gt;
  &amp;lt;p&amp;gt;Some detailed text detailing detailed details.&amp;lt;/p&amp;gt;
  &amp;lt;%= link_to_function(&amp;quot;Hide Details&amp;quot;,closer) %&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What&amp;#8217;s going on here is actually pretty simple. The helper generates a link (with the label you&amp;#8217;ve given) to show a a hidden div and hide itself. The block given to the helper is what will end up inside that div, and it&amp;#8217;s yielded the snippet of javascript necessary to switch back (so that you can use that snippet wherever you&amp;#8217;d like).&lt;/p&gt;

&lt;p&gt;Keep in mind assumes you&amp;#8217;ll only have one link per page with the same label â€¦ if you think that won&amp;#8217;t be the case, you&amp;#8217;ll probably want ensure the ids generated inside the helper are unique; using &lt;code&gt;object_id&lt;/code&gt; would be a simple way to do so.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views, ActiveRecord DOM IDs</title>
   <link href="http://codefluency.com/2006/05/30/rails-views-activerecord-dom-ids.html"/>
   <updated>2006-05-30T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/05/30/rails-views-activerecord-dom-ids</id>
   <content type="html">&lt;p&gt;The solution&amp;#8211; or at least a nice, cheap bandaid that can be applied easily, consists of adding a method to ActiveRecord::Base to help generate these ids without any brainpower involved.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s a very simple implementation that I use in my projects, courtesy of &lt;a href='http://jamis.jamisbuck.org/'&gt;Jamis Buck&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class ActiveRecord::Base
  def dom_id(prefix=nil)
    display_id = new_record? ? &amp;quot;new&amp;quot; : id
    prefix ||= self.class.name.underscore
    prefix != :bare ? &amp;quot;#{prefix.to_s.dasherize}-#{display_id}&amp;quot; : display_id
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, you can do stuff like this in your views:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
  &amp;lt;% @entries.each do |entry| %&amp;gt;
    &amp;lt;li id=&amp;#39;&amp;lt;%= entry.dom_id %&amp;gt;&amp;#39;&amp;gt;
      &amp;lt;%= entry.body %&amp;gt;
    &amp;lt;/li&amp;gt;
  &amp;lt;% end %&amp;gt;
&amp;lt;/ul&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And stuff like this in your controller:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def remove_entry
  entry = JournalEntry.find(params[:id])
  update_page do |page|
    page[entry.dom_id].remove
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Isn&amp;#8217;t that nice, simple, and easier to remember than some half-baked scheme you thought up on your own? It is for me.&lt;/p&gt;

&lt;p&gt;One of the things you do when dealing with views that will be modified via AJAX is set DOM IDs on elements you&amp;#8217;ll want to modify or remove.&lt;/p&gt;

&lt;p&gt;This is especially true if you&amp;#8217;re creating elements for a set of ActiveRecord objects. Perhaps you have a JournalEntry model and give a series of list items ids like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;% @entries.each do |entry| %&amp;gt;
  &amp;lt;li id=&amp;#39;&amp;lt;%= entry.id %&amp;gt;&amp;#39;&amp;gt;
    &amp;lt;%= entry.body %&amp;gt;
  &amp;lt;/li&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Isn&amp;#8217;t this a tedious activity to do by hand? It&amp;#8217;s not only frightfully dull to do in any volume, but it also increases the likelihood you&amp;#8217;ll make a mistake, especially since you&amp;#8217;ll need to remember what naming scheme you&amp;#8217;re using in any RJS actions you develop to make use of the ids.&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s a better way, and by &amp;#8220;better&amp;#8221; I mean lazier and generally more satisfying.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views,  Internal Plugins</title>
   <link href="http://codefluency.com/2006/05/29/rails-views-internal-plugins.html"/>
   <updated>2006-05-29T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/05/29/rails-views-internal-plugins</id>
   <content type="html">&lt;p&gt;Each of these consist of a mixin for controllers, a number view templates stored inside the plugin, and a helper for use by those views.&lt;/p&gt;

&lt;p&gt;The module mixed into ActionController::Base provides a declarative way of defining all the actions involved at once, inside any controller we want. This might, for instance, look something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;folder_for :student do
  tabs :general, :attendance, :surveys
  tab :report do
    # get report data
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This declarative method would handle defining each action, and determining what data needs to be prepared for each action, acting somewhat like a before&lt;em&gt;filter, and then render the appropriate views stored inside the plugin (via &lt;code&gt;render :file&lt;/code&gt;).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sure, you could do all of this be defining the controller part in application.rb, manually attaching the helper, and having some type of cross- controller template directory to store its views â€¦ but this way certainly feels cleaner, and who knows if we might want to reuse the code (or even just the concept) in another application?&lt;/p&gt;

&lt;p&gt;Putting stuff in plugins is worth it &amp;#8211; if even just to make things easier to find in your own application.&lt;/p&gt;

&lt;p&gt;One of the techniques we&amp;#8217;ve been using at work to develop our Rails application is based on the Rails plugin system.&lt;/p&gt;

&lt;p&gt;There are several UI components of our application that are a mix of Controller and View pieces. Rather than have each of these strung out across the Rails framework, we package them in plugins.&lt;/p&gt;

&lt;p&gt;Even though we&amp;#8217;re not distributing these, they&amp;#8217;re large enough and used often enough in our application for the separate packaging to really pay off.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views,  Helpers that take Blocks</title>
   <link href="http://codefluency.com/2006/05/28/rails-views-helpers-that-take-blocks.html"/>
   <updated>2006-05-28T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/05/28/rails-views-helpers-that-take-blocks</id>
   <content type="html">&lt;p&gt;Helpers that take blocks are a core element of the new approach to developing views for Rails. What are they, and why should they be used? To put it plainly, block helpers are a bit of Ruby magic that will save you time and no little amount of sanity.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s use a simple example. Imagine a situation where you are wrapping chunks of markups in a div with the same CSS class. This is happening in various templates.&lt;/p&gt;

&lt;p&gt;The old approach would either be to just type in the wrapping div manually every time, or maybe have two partials; one rendered before, and the other after the chunk of markup.&lt;/p&gt;

&lt;p&gt;This is the type of &lt;em&gt;insert header here&lt;/em&gt;, and &lt;em&gt;insert footer here&lt;/em&gt; PHP-like clunkiness I try to avoid.&lt;/p&gt;

&lt;p&gt;Block helpers make this inelegant kludge unnecessary. They allow you insert &amp;#8220;common&amp;#8221; markup before and after the block, and also to yield whatever object you&amp;#8217;d like to the block so it can be used &amp;#8211; like &lt;code&gt;form_for&lt;/code&gt;&amp;#8217;s builders.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;re going to make a quick little helper to generate little &amp;#8220;tip&amp;#8221; sidebar items with optional headers. Here&amp;#8217;s the type of API we want:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;% tip &amp;quot;Block Helpers Help!&amp;quot; do %&amp;gt;
  &amp;lt;p&amp;gt;They really do!&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;Use them, or deprecate yourself immediately.&amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice the first line is in an ERB &lt;em&gt;evaluation&lt;/em&gt; block, meaning we&amp;#8217;re not trying to insert its result into the template&amp;#8211; since we&amp;#8217;re not even finished passing all the arguments to it, after all; the block.&lt;/p&gt;

&lt;p&gt;And here&amp;#8217;s how to make it all happen:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def tip(name=nil,&amp;amp;block)
  concat(&amp;quot;&amp;lt;div class=&amp;#39;tip&amp;#39;&amp;gt;&amp;quot;, block.binding)
  concat(content_tag(&amp;#39;h3&amp;#39;,name), block.binding) if name
  yield  # now insert the markup in the block
  concat(&amp;#39;&amp;lt;/div&amp;gt;&amp;#39;, block.binding)
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, what&amp;#8217;s this &lt;code&gt;block.binding&lt;/code&gt; tomfoolery?&lt;/p&gt;

&lt;p&gt;To add anything to the page, we need to use &lt;code&gt;concat&lt;/code&gt;, and ERB needs to know where add our text &amp;#8211; the context. Handily, our block lives out in the template, and its binding is exactly what we need.&lt;/p&gt;

&lt;p&gt;And that&amp;#8217;s about it. It&amp;#8217;s really not very complex, provided you have at least a little bit of Ruby experience, know what a block is, and can deal with ERB&amp;#8217;s foibles.&lt;/p&gt;

&lt;p&gt;So use block helpers!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;: &lt;code&gt;form_helper.rb&lt;/code&gt; (in Rails) has some fairly decent examples. &lt;a href='http://www.pragmaticprogrammer.com/titles/fr_rr/'&gt;Rails Recipes&lt;/a&gt;, a great book by Chad Fowler also has a recipe on the subject. Buy it &amp;#8211; you&amp;#8217;re a smart Rails developer, right?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update 2008&lt;/em&gt; This article is pretty old (2 years is practically eons!). &lt;code&gt;concat&lt;/code&gt; no longer needs &lt;code&gt;block.binding&lt;/code&gt;, and other things have changed. Just consider this a historical document!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views,  Use update_page in link_to_function</title>
   <link href="http://codefluency.com/2006/05/27/rails-views-use-update_page-in-link_to_function.html"/>
   <updated>2006-05-27T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/05/27/rails-views-use-update_page-in-link_to_function</id>
   <content type="html">&lt;p&gt;Here&amp;#8217;s a quick example, two ways. Let&amp;#8217;s make all paragraphs on the page have green text using CSS class irish, just for the hell of it &amp;#8211; just pretend it&amp;#8217;s St. Patrick&amp;#8217;s day for the moment. In fact, let&amp;#8217;s quickly slide down a nice &amp;#8220;Happy St. Paddy&amp;#8217;s&amp;#8221; banner, as well.&lt;/p&gt;

&lt;p&gt;First, a traditional (if still prototype-enhanced) &lt;code&gt;link_to_function&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;link_to_function(&amp;quot;Pinch Me!&amp;quot;, &amp;quot;$$(&amp;#39;p&amp;#39;).each(
    function(tag) {tag.addClassName(&amp;#39;irish&amp;#39;);}
  );
  new Effect.SlideDown(&amp;#39;banner&amp;#39;,{duration:0.4});&amp;quot;
)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And, with update&lt;em&gt;page:&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;link_to_function(&amp;quot;Pinch Me!&amp;quot;, update_page{|page|
  page.select(&amp;#39;p&amp;#39;).each{|p| p.addClassName(&amp;#39;irish&amp;#39;)}
  page[:banner].visual_effect :slide_down, :duration =&amp;gt; 0.4
})&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, they&amp;#8217;re about the same length .. so what&amp;#8217;s the big deal?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ruby is more powerful and easier read than Javascript. Keep in mind this is a very simplistic example.&lt;/li&gt;

&lt;li&gt;Once you start dynamically interpolating different element ids, etc, into a string of javascript (using &lt;code&gt;escape_javascript&lt;/code&gt;, of course), the non- update&lt;em&gt;page version gets harder and harder to maintain (or even look at while holding down your lunch).&lt;/em&gt;&lt;/li&gt;

&lt;li&gt;It&amp;#8217;s easier to extend this technique using other helpers and frameworks (passing page to add common code, for instance) than passing around strings to be concatenated&amp;#8211; and risking javascript syntax errors in the process (can anyone say &amp;#8220;Missing semicolon?&amp;#8221;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hopefully you&amp;#8217;ll get some mileage out of this technique. It&amp;#8217;s a small, very simple favorite of mine.&lt;/p&gt;

&lt;p&gt;One of the least used techniques I&amp;#8217;ve seen used in Rails applications&amp;#8211; and one I think is not only very elegant, but also saves time &amp;#8211; is the use of &lt;code&gt;update_page&lt;/code&gt; directly in link&lt;em&gt;to&lt;/em&gt;function.&lt;/p&gt;

&lt;p&gt;Why aren&amp;#8217;t more people using this? I just don&amp;#8217;t get it. A lot of work went into RJS â€¦ so why not use it?&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Introducing Rails Views</title>
   <link href="http://codefluency.com/2006/05/27/introducing-rails-views.html"/>
   <updated>2006-05-27T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/05/27/introducing-rails-views</id>
   <content type="html">&lt;p&gt;I &lt;strong&gt;live&lt;/strong&gt; in the land of Rails templates and helpers. To give you an idea of how seriously I&amp;#8217;m talking here, let me just say the following. Our application currently has around 670 separate template files (around 8500 lines) and 75 helpers (around 2350 lines), and it&amp;#8217;s still growing.&lt;/p&gt;

&lt;p&gt;What does this mean&amp;#8211; besides the fact TextMate&amp;#8217;s âŒ˜-T is my best friend? It means that, if there&amp;#8217;s anything I know about Rails, it&amp;#8217;s how to manage a large volume of templates and view-related code, building frameworks to help DRY-up the chaos.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m going to try to help other Developer/Designers out there in the same boat as I am by posting a series of entries titled &lt;strong&gt;Rails Views&lt;/strong&gt;. These posts will highlight techniques I use in my day-to-day work. Maybe you&amp;#8217;ll find them useful; they&amp;#8217;re certainly not the only way to do things, but they&amp;#8217;re the way I do them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rails Views&lt;/strong&gt; will assume you know Ruby fairly well; I won&amp;#8217;t be focusing on explaining details I expect reasonably decent Ruby programmers to understand. I&amp;#8217;ll also assume you&amp;#8217;re using Edge Rails, since that&amp;#8217;s what I work with every day.&lt;/p&gt;

&lt;p&gt;I hope they&amp;#8217;re useful!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views,  render :update, not .rjs</title>
   <link href="http://codefluency.com/2006/05/27/rails-views-render-update-not-rjs.html"/>
   <updated>2006-05-27T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/05/27/rails-views-render-update-not-rjs</id>
   <content type="html">&lt;p&gt;Ok, here&amp;#8217;s the deal. I&amp;#8217;m about to commit blasphemy. I&amp;#8217;m going to recommend you put view-related code in the &lt;em&gt;controller&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Wait a second. What about the whole MVC thingâ€¦ &lt;em&gt;never the twain shall meet&lt;/em&gt;, right? What kind of madness is this??!? (&lt;em&gt;ducks lightning bolt&lt;/em&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Put down the pitchforks and torches, dammit, and listen.&lt;/p&gt;

&lt;p&gt;Why, really, do we avoid putting view stuff in controllers? Why, that&amp;#8217;s easy â€¦ because we&amp;#8217;re talking visual elements here&amp;#8211; things to lay out, things that aren&amp;#8217;t necessarily a function of the application&amp;#8217;s &lt;em&gt;behavior&lt;/em&gt; or &lt;em&gt;workflow&lt;/em&gt;, right? Things get muddled and then everything goes to hell, right?&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s the deal. I say replacing a portion of the page with another due to user interaction is &lt;em&gt;behavioral&lt;/em&gt;. Granted, changing this or that element of the page can lead to some tight coupling, so it needs to be approached with caution â€¦ but there&amp;#8217;s no glittering ivory tower here, folks.&lt;/p&gt;

&lt;p&gt;A quick example, from a controller.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def add_item
  Item.create(params[:item])
  @items = Item.find(:all)
  render :update do |page|
    # Think &amp;quot;inline RJS&amp;quot;
    page[:item_list].reload
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here, we have a listing of items; maybe they&amp;#8217;re sorted alphabetically, so we want to go ahead and reload the whole listing (rather than just inserting the new item, which could also be done).&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s pretty simple. If you know RJS and you look at this action, you &lt;em&gt;know&lt;/em&gt; what&amp;#8217;s going on&amp;#8211; the whole process that occurs when the user submits the form. If the RJS is just an extension of the behavior that&amp;#8217;s occurring in the controller, why put it in a separate file&amp;#8211; why dig when you can just &lt;em&gt;know&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;Sometimes pure, rigid thoughts are just naive, dumb thoughts. Feel free to adhere to doctrine&amp;#8211; but once it&amp;#8217;s counter-productive, cut and run.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails Views,  form_for</title>
   <link href="http://codefluency.com/2006/05/27/rails-views-form_for.html"/>
   <updated>2006-05-27T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/05/27/rails-views-form_for</id>
   <content type="html">&lt;p&gt;The whole thing is pretty simple.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;% form_for :student, @student, :url =&amp;gt; student_url(:action=&amp;gt;&amp;#39;update&amp;#39;) do |f| %&amp;gt;
  &amp;lt;ul&amp;gt;
    &amp;lt;li&amp;gt;Name: &amp;lt;%= f.text_field(:name) %&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;Age: &amp;lt;%= f.text_field(:age,:size=&amp;gt;2) %&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;/ul&amp;gt;
  &amp;lt;%= submit_tag &amp;quot;Save&amp;quot; %&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Some observations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Anything in the block is contained in the resulting form tag (no chance you&amp;#8217;ll forget it)&lt;/li&gt;

&lt;li&gt;Unlike the plain &lt;code&gt;text_field&lt;/code&gt; helper (and others) you&amp;#8217;d have to pass in a symbol (and would expect a similarly named instance variable in scope), you can give the &lt;code&gt;form_for&lt;/code&gt; any object you&amp;#8217;d like, named anything you&amp;#8217;d like, and any field method called on the form object will name the field correctly and use the existing attribute for its value.&lt;/li&gt;

&lt;li&gt;You pass &lt;code&gt;:url&lt;/code&gt; to &lt;code&gt;remote_form_for&lt;/code&gt; as well, meaning there&amp;#8217;s less chance you&amp;#8217;ll forget what API to use for which method, and that&amp;#8217;s good thing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There&amp;#8217;s a lot more to talk about here, including &lt;code&gt;fields_for&lt;/code&gt; and form builders (which are worth a post all by themselves), but I think you get the point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;: &lt;code&gt;form_helper.rb&lt;/code&gt; in a fresh edge rails checkout.&lt;/p&gt;

&lt;p&gt;In the beginning (or nearly so), we had &lt;code&gt;form_tag&lt;/code&gt; and &lt;code&gt;end_form_tag&lt;/code&gt;. Now, these were still better than typing form tags, and trying to throw in form attributes, but they really didn&amp;#8217;t even begin to use the full power of what Ruby (and ERB) had to offer.&lt;/p&gt;

&lt;p&gt;A while back, &lt;code&gt;form_for&lt;/code&gt; (and it&amp;#8217;s sexy friend &lt;code&gt;remote_form_for&lt;/code&gt;) came on the scene, but a lot of people haven&amp;#8217;t noticed. These are cleaner, more elegant, and more flexible ways of making both regular and remote forms, and you should be using them.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Closures; an Italian Sonnet</title>
   <link href="http://codefluency.com/2006/05/18/closures-an-italian-sonnet.html"/>
   <updated>2006-05-18T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/05/18/closures-an-italian-sonnet</id>
   <content type="html">&lt;p&gt;I was &lt;a href='http://project.ioni.st/post/787#post-787'&gt;recently challenged&lt;/a&gt;, in jest, to write a poem on closures. I was waxing poetic on the idea of closures as method &amp;#8220;templates,&amp;#8221; and &lt;a href='http://chadfowler.com'&gt;Chad&lt;/a&gt; called me on it.&lt;/p&gt;

&lt;p&gt;I could have answered Chad&amp;#8217;s joke with a haiku, but who can truly contain their love for closures in only a few lines?&lt;/p&gt;

&lt;p&gt;Instead, I figured an Italian Sonnet would be much more punishing for all involved, and somewhere where I could &lt;em&gt;truly&lt;/em&gt; showcase my inherent nerdiness.&lt;/p&gt;

&lt;p&gt;So, without any more adoâ€¦&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A shame, it seems me, that closures still Are not lauded, not given their just due; Objects rock, but no paradigm&amp;#8217;s so true, That should eschew the useful closure&amp;#8217;s thrill. The outer scope, the fortress on a hill Is not opaque; the closure has a view Of variables assigned before&amp;#8211; into The closure goes a binding&amp;#8217;s heart and will. Closures seem like method templates; see Filled with variables that are in turn contained, This stencil used to fill a binding&amp;#8217;s dreams, No banal limits, no local scope constrained. So pivotal, these functional gems agree With metaprogramming and other utopian schemes.&lt;/p&gt;
&lt;/blockquote&gt;</content>
 </entry>
 
 <entry>
   <title>Getting a Handle on Rake</title>
   <link href="http://codefluency.com/2006/05/02/getting-a-handle-on-rake.html"/>
   <updated>2006-05-02T00:00:00-07:00</updated>
   <id>http://codefluency.com/2006/05/02/getting-a-handle-on-rake</id>
   <content type="html">&lt;p&gt;If you&amp;#8217;re a Rails developer, you use Rake. Sadly, many Rails developers don&amp;#8217;t understand Rake well enough to fully grasp its potential.&lt;/p&gt;

&lt;p&gt;At last month&amp;#8217;s Boulder-Denver Ruby Group meeting, I spoke about Rake and how it can make a developer&amp;#8217;s life easier. The presentation and example code is available &lt;em&gt;here&lt;/em&gt; (&lt;em&gt;Update&lt;/em&gt; These documents have been misplaced since this article was originally posted; sorry).&lt;/p&gt;

&lt;p&gt;Hopefully, the presentation will serve as a good starting point for some out there who haven&amp;#8217;t discovered how powerful and easy to learn Rake truly is.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails RTex Plugin, Generating PDFs</title>
   <link href="http://codefluency.com/2006/03/17/rails-rtex-plugin-generating-pdfs.html"/>
   <updated>2006-03-17T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/03/17/rails-rtex-plugin-generating-pdfs</id>
   <content type="html">&lt;p&gt;One of the challenges that I&amp;#8217;ve recently run into in the midst of Rails work has been PDF generation. For one project, it&amp;#8217;s a mandatory requirement, and, unfortunately, PDF::Writer simply isn&amp;#8217;t fast enough to handle the amount or complexity of the content.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve liked LaTeX for several years; I&amp;#8217;ve used it for resumes, business cards, and letterheads, and have always been impressed with its professional quality&amp;#8211; especially when it comes to fonts. The speed isn&amp;#8217;t bad, either.&lt;/p&gt;

&lt;p&gt;Back in my PHP and Python days, I wrote a number of quick hacks to push generated .tex files through LaTeX, with pretty good results, so the last day or two I started thinkingâ€¦&lt;/p&gt;

&lt;p&gt;Why not offer a template format in Rails to generate LaTeX files for pdfLaTeX?&lt;/p&gt;

&lt;p&gt;Yesterday morning, that&amp;#8217;s exactly what I started putting together, and I&amp;#8217;m happy to release the initial result of the work in a new Rails plugin, RTex.&lt;/p&gt;

&lt;p&gt;If this sounds like something you&amp;#8217;d be interested in, &lt;a href='http://github.com/bruce/rtex'&gt;see the RTex Plugin page&lt;/a&gt; for more details.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Kites of Death!</title>
   <link href="http://codefluency.com/2006/03/09/kites-of-death.html"/>
   <updated>2006-03-09T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/03/09/kites-of-death</id>
   <content type="html">&lt;p&gt;One of the more interesting, frightening stories I&amp;#8217;ve run across recently is one concerning &lt;a href='http://go.reuters.com/newsArticle.jhtml?type=oddlyEnoughNews&amp;amp;storyID=1'&gt;kites that can kill people&lt;/a&gt; in Pakistan.&lt;/p&gt;

&lt;p&gt;This just goes to show you&amp;#8211; some people can take the most inane concept and do something unexpected with it. In this case, by &amp;#8220;unexpected&amp;#8221; I mean &amp;#8220;really, really, bad.&amp;#8221;&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re drawing some kind of development/design/management parallel in your head right now, you think too hard.&lt;/p&gt;

&lt;p&gt;Sometimes a Kite of Death is just a Kite of Death, sheesh.&lt;/p&gt;

&lt;p&gt;1468494&amp;amp;src=rss/oddlyEnoughNews&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Publishing; An Aside</title>
   <link href="http://codefluency.com/2006/02/21/publishing-an-aside.html"/>
   <updated>2006-02-21T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/02/21/publishing-an-aside</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve had the good furtune to be able to work as a Technical Editor/Proofreader for recently, and what an eye opener!&lt;/p&gt;

&lt;p&gt;The publishing industry is definitely an interesting one, and from things I&amp;#8217;ve read lately, one that&amp;#8217;s changing due to some &lt;a href='http://blogs.pragprog.com/cgi-bin/pragdave.cgi/Random/Imitation.rdoc'&gt;really cool ideas&lt;/a&gt; about what it means to publish really good books in new, exciting ways.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The Optional Partial</title>
   <link href="http://codefluency.com/2006/02/09/the-optional-partial.html"/>
   <updated>2006-02-09T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/02/09/the-optional-partial</id>
   <content type="html">&lt;p&gt;A common Rails issue for me is when I have a section of my layout that may change per-controller; a sidebar, for instance, that looks one way in FoosController (&lt;code&gt;foos/&lt;/code&gt;), completely different in BarsController (&lt;code&gt;bars/&lt;/code&gt;), and doesn&amp;#8217;t even show up in BazsContoller (&lt;code&gt;bazs/&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s ways of doing this, of course. Here&amp;#8217;s an evil one:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;render(:partial =&amp;gt; &amp;#39;sidebar&amp;#39;) rescue nil&lt;/code&gt;&lt;/pre&gt;</content>
 </entry>
 
 <entry>
   <title>The not-so-amazing Purple Rock</title>
   <link href="http://codefluency.com/2006/02/06/the-not-so-amazing-purple-rock.html"/>
   <updated>2006-02-06T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/02/06/the-not-so-amazing-purple-rock</id>
   <content type="html">&lt;p&gt;This kind of critical, slightly cynical view is one that&amp;#8217;s very easy to feel about software. After all, &lt;em&gt;there&amp;#8217;s a lot of crap out there&lt;/em&gt;. Bad or poorly trained developers, designers, and managers churning out loads of buzzword- friendly, &amp;#8220;innovative,&amp;#8221; &lt;em&gt;truly crappy&lt;/em&gt; software. It&amp;#8217;s stuff that may look neat, but turns out to be so derivative, unimaginative, and unusable that users eventually &lt;em&gt;despise it&lt;/em&gt;. A lot of this is due to the rather drab view that software development is an engineering, rather than artistic, pursuit.&lt;/p&gt;

&lt;p&gt;I love to find software, especially web-based software, that really breaks this mould. I&amp;#8217;m especially lucky that I ran across &lt;a href='http://37signals.com'&gt;37signals&lt;/a&gt; back when I first started digging into &lt;a href='http://rubyonrails.org'&gt;Rails&lt;/a&gt; (right before RubyConf 2004). Here was a company that made good software, and knew clean design, to boot.&lt;/p&gt;

&lt;p&gt;But nothing could have prepared me for &lt;a href='http://campfirenow.com'&gt;Campfire&lt;/a&gt;. This, simply put, is one of the neatest, cleanest webapps I&amp;#8217;ve ever run across. It&amp;#8217;s easy to use, it&amp;#8217;s &lt;em&gt;useful&lt;/em&gt;, and using for more than a hour doesn&amp;#8217;t make me want to kill myself.&lt;/p&gt;

&lt;p&gt;37signals have really outdone themselves on this one. When it goes public, &lt;em&gt;you owe it to yourself to try it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;(Special kudos go out to &lt;a href='http://conio.net'&gt;Sam Stephenson&lt;/a&gt; for what surely amounts to some serious javascript magic going on behind the scenes.)&lt;/p&gt;

&lt;p&gt;As a young kid living growing up in Tucson, Arizona, I was a Webelo. For those of you that don&amp;#8217;t know what a Webelo is, it&amp;#8217;s a Boy Scout rank below, well.. Boy Scout (and even less cool). I liked it. There was always something new to learn, and, of course, we went camping.&lt;/p&gt;

&lt;p&gt;I love camping.&lt;/p&gt;

&lt;p&gt;At the end of one particular camping trip, I distinctly remember goofing around as everyone was packing things up. Walking by the extinguished campfire, I looked down and saw a &lt;em&gt;neat purple rock&lt;/em&gt;. Being interested in Geology, I was intrigued. &amp;#8220;A purple rock,&amp;#8221; I thought. &amp;#8220;What kind of rock is that?&amp;#8221;&lt;/p&gt;

&lt;p&gt;I found out, about two seconds later, when I grabbed it and discovered it was &lt;em&gt;hot&lt;/em&gt;. How hot? However hot a rock has to be to be &lt;em&gt;purple&lt;/em&gt;, cause excruciating pain, and force me to scream like a pre-pubescent girl. I had, apparently, forgotten that I was pulling the rock &lt;em&gt;out of a newly extinguished campfire&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Luckily, besides feeling very stupid and having a mildly burned hand, no harm was doneâ€¦ and, of course, I&amp;#8217;ve made even worse decisions since then.&lt;/p&gt;

&lt;p&gt;But I did learn something.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not all things that look neat are actually that exciting, or groundbreaking, or difficult to accomplish&lt;/strong&gt;. Sometimes, events conspire to make something look neat, but in the end it just isn&amp;#8217;t a good idea to play around with it.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The Next Great Book</title>
   <link href="http://codefluency.com/2006/02/06/the-next-great-book.html"/>
   <updated>2006-02-06T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/02/06/the-next-great-book</id>
   <content type="html">&lt;p&gt;The Pragmatic Bookshelf has started selling Beta Book copies of &lt;a href='http://chadfowler.com'&gt;Chad Fowler&amp;#8217;s&lt;/a&gt; upcoming book, &lt;a href='http://www.pragmaticprogrammer.com/titles/fr_rr/index.html'&gt;Rails Recipes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As Chad &lt;a href='http://chadfowler.com/index.cgi/Computing/Programming/Ruby/RailsRecipe'&gt;points out&lt;/a&gt;, this book is the next step for those who&amp;#8217;ve read the &lt;a href='http://www.pragmaticprogrammer.com/titles/ruby/index.html'&gt;Pickaxe&lt;/a&gt; or &lt;a href='http://www.pragmaticprogrammer.com/titles/rails/index.html'&gt;Agile Web Development With Rails&lt;/a&gt;. I think it would also be a great resource for the beginning Rails programmer.&lt;/p&gt;

&lt;p&gt;Chad&amp;#8217;s been working incredibly hard to make this book an accessible, thorough reference for Rails developers who care enough about their craft to keep up on the latest patterns, and let me tell you, it&amp;#8217;s &lt;em&gt;already&lt;/em&gt; a useful resource.&lt;/p&gt;

&lt;p&gt;Slam down your extra pennies &lt;a href='http://www.pragmaticprogrammer.com/titles/fr_rr/index.html'&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;sInBeta.rdoc,v&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Partially Painful</title>
   <link href="http://codefluency.com/2006/02/03/partially-painful.html"/>
   <updated>2006-02-03T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/02/03/partially-painful</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve been chatting recently with &lt;a href='http://chadfowler.com'&gt;Chad&lt;/a&gt; about mixing code and content (ie, ERb) and how hard &lt;a href='http://rubyonrails.org'&gt;Rails&lt;/a&gt; partials can be to read. Both of us are language nuts, and I think this is something that&amp;#8217;s very easy for us to get caught-up on.&lt;/p&gt;

&lt;p&gt;As far as I can see, there&amp;#8217;s a decision every Rails developer needs to make&amp;#8211; with two choices that are largely mutually exclusive.&lt;/p&gt;

&lt;p&gt;* More interleaving, meaning less partials and readability, but less files to dig through&lt;/p&gt;

&lt;p&gt;* Less interleaving, meaning more partials and readability, but more files to dig through&lt;/p&gt;

&lt;p&gt;I don&amp;#8217;t think there&amp;#8217;s any &lt;em&gt;right&lt;/em&gt; choice for this type of decision. With the exception of partials for loop content and those necessary for AJAX updates, there&amp;#8217;s not even any general consensus. It&amp;#8217;s a matter of taste, and ultimately something that depends on what makes sense for &lt;em&gt;you&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I tend to make lots of partials and rely on my memory, grep, and &lt;a href='http://macromates.com'&gt;TextMate&amp;#8217;s&lt;/a&gt; Command-T to help me find what I&amp;#8217;m looking for. But it sure can get complex.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Tidbits</title>
   <link href="http://codefluency.com/2006/01/28/tidbits.html"/>
   <updated>2006-01-28T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/01/28/tidbits</id>
   <content type="html">&lt;p&gt;If you haven&amp;#8217;t checked out &lt;a href='http://moebot.com'&gt;Moe Bot&lt;/a&gt;, you should. My personal favorite is &lt;a href='http://moebot.com/2005/scarves.html'&gt;Scarves Scarves Scarves&lt;/a&gt; (it actually frightens me quite a bit, but I get over it by laughing nervously).&lt;/p&gt;

&lt;p&gt;And then there&amp;#8217;s the &lt;a href='http://waterfall2006.com'&gt;Waterfall 2006&lt;/a&gt; site. Links for this have been flying all over geekdom the last couple of days. Who knew we liked tongue-in-cheek humor?&lt;/p&gt;

&lt;p&gt;My favorite tutorial so far &lt;em&gt;has&lt;/em&gt; to be &lt;em&gt;&amp;#8220;User Interaction: It Was Hard to Build, It Should Be Hard to Use&amp;#8221; by Jeff Patton.&lt;/em&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Monkey Business</title>
   <link href="http://codefluency.com/2006/01/27/monkey-business.html"/>
   <updated>2006-01-27T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/01/27/monkey-business</id>
   <content type="html">&lt;p&gt;I respectfully disagree with Python developer &lt;a href='http://blog.ianbicking.org'&gt;Ian Bicking&amp;#8217;s&lt;/a&gt; &lt;a href='http://chadfowler.com/index.cgi/Computing/Programming/Ruby/TheVirtuesO'&gt;most recent comment&lt;/a&gt; with regards to &lt;em&gt;monkey patching&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If a guerilla/monkey patch is something that &amp;#8220;that sneakily changes other code at runtime without any rules&amp;#8221; (&lt;a href='http://plone.org/documentation/glossary/monkeypatch'&gt;see definition&lt;/a&gt;), Rails&amp;#8217; extension of several base classes (such as Fixnum) certainly doesn&amp;#8217;t qualify. It&amp;#8217;s a well- documented aspect of Rails, and just simply makes sense.&lt;/p&gt;

&lt;p&gt;Extending previously declared classes (&lt;em&gt;reopening them&lt;/em&gt;) is a Ruby staple, and rightfully so. No &amp;#8220;object of &lt;span&gt;your&lt;/span&gt; own&amp;#8221; is needed when the right object for the job already exists.. and, as long as you&amp;#8217;re not submitting your &lt;em&gt;patches&lt;/em&gt; to unsuspecting &lt;em&gt;victims&lt;/em&gt; (ie, you &lt;a href='http://api.rubyonrails.org/'&gt;make it obvious&lt;/a&gt; what&amp;#8217;s going on), I think this approach makes sense&amp;#8211; in the very least from an API design perspective.&lt;/p&gt;

&lt;p&gt;fMonkeyPatching.rdoc,v&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Replacing That Old Sofa</title>
   <link href="http://codefluency.com/2006/01/26/replacing-that-old-sofa.html"/>
   <updated>2006-01-26T00:00:00-08:00</updated>
   <id>http://codefluency.com/2006/01/26/replacing-that-old-sofa</id>
   <content type="html">&lt;p&gt;People like tabs because they recognize them for exactly what they are: a holdover from the days of file folders. Is this bad? &lt;em&gt;No&lt;/em&gt;. Is this &lt;em&gt;right&lt;/em&gt;&amp;#8211; in the sense that the web has progressed past the days of being merely a document repository to a platform for really neat applications? &lt;em&gt;Maybe not&lt;/em&gt;. Butâ€¦ it&amp;#8217;s just &lt;em&gt;comfortable&lt;/em&gt;. Everyone&amp;#8217;s seen a file folder. It&amp;#8217;s a physical object they&amp;#8217;ve touched, they&amp;#8217;ve used, they recognize. It makes sense.&lt;/p&gt;

&lt;p&gt;And there&amp;#8217;s the pitfall. Comforting the user just isn&amp;#8217;t that exciting, is it? Jarring, unique layouts and controls are &lt;em&gt;fun&lt;/em&gt;, they feed our creative drive&amp;#8211; and there&amp;#8217;s nothing that makes us right-brainers more pumped than making something only we really understand (comeon, admit it).&lt;/p&gt;

&lt;p&gt;Now, this doesn&amp;#8217;t mean we should necessarily have to use old favorites like tabs. This just means we need to make &lt;em&gt;really good choices&lt;/em&gt; about what makes sense and what doesn&amp;#8217;t. No matter how &lt;em&gt;cool&lt;/em&gt; the control you&amp;#8217;ve designed looks, no matter &lt;em&gt;how neat&lt;/em&gt; its behavior is, if the user has to figure out that it does the same thing &lt;em&gt;those comfortable old tabs&lt;/em&gt; do, they&amp;#8217;ll give just give up.&lt;/p&gt;

&lt;p&gt;Deciding you&amp;#8217;re going to educate the user through some new, ground-breaking interface is risky business. User interface isn&amp;#8217;t about educating, it&amp;#8217;s about mind-reading&amp;#8211; the wise and gentle designer is the one that knows the goal is &lt;em&gt;figuring out how to make really neat things comfortable&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If you can do that&amp;#8211; if you can present your neat design in such a way that it intuitively makes sense, it works, and it&amp;#8217;s understood.. who knows, you just might change the world.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve been up to my neck in tabs lately. User interface tabs, that is. Eventually every complex application hits the point where all (or at least a large portion) of the page content needs to be sliced up into categories that make sense being &lt;em&gt;visually exclusive&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This is where tabs come in. I mean, &lt;a href='http://apple.com'&gt;everyone&lt;/a&gt; &lt;a href='http://www.basecamphq.com/'&gt;is&lt;/a&gt; &lt;a href='http://www.sun.com/download/'&gt;doing&lt;/a&gt; &lt;a href='http://adaptivepath.com/products/'&gt;it&lt;/a&gt;, and it&amp;#8217;s been happening for a long time.&lt;/p&gt;

&lt;p&gt;I don&amp;#8217;t like them. I&amp;#8217;m not sure I ever have. But I also know they work, people like them, and &lt;em&gt;I&amp;#8217;m not the user, so I shouldn&amp;#8217;t pretend to be.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Replacing something that&amp;#8217;s so comfortable and easy to grasp (that we really don&amp;#8217;t like) with some &lt;em&gt;new, neat design&lt;/em&gt; (that&amp;#8217;s actually more powerful) is a difficult challenge. Sometimes it makes sense, and sometimes it doesn&amp;#8217;t.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update 2006-04-03&lt;/strong&gt;: See, I gave in. Tabs here too, these days.&lt;/p&gt;</content>
 </entry>
 
 
</feed>