Gray Soft / Tags / Mix-instag:graysoftinc.com,2014-03-20:/tags/Mix-ins2014-04-30T02:31:45ZJames Edward Gray IIDecorators Verses the Mix-intag:graysoftinc.com,2012-05-21:/posts/1152014-04-30T02:31:45ZIn this article I dig into a topic of recent interest to the Ruby object geeks to see if I can suss out the tradeoffs from both sides.<p>It is a neat time to be involved in the Ruby community, if you ask me. A large portion of us are currently studying the techniques for doing good object oriented development. We are looking at the ideas that have come before and trying to decide the best ways to apply those ideas to our favorite language. This leads to blog posts, forum threads, and conference talks about what we are learning. No matter what, we all gain from explorations like this. Everybody wins as our collective knowledge grows. We all deserve gold stars.</p>
<p>So far, there's one point pretty much everyone agrees on: composition should typically be preferred to inheritance. The trickier part of that discussion though is deciding what composition looks like in Ruby. Generally you see Rubyists comparing the merits of <a href="http://en.wikipedia.org/wiki/Decorator_pattern">decorators</a> and mix-ins. <em>[<strong>Note</strong>: the comments correctly pointed out that this was a bad use of the word "composition" on my part, to describe mix-ins.]</em> There's <a href="https://groups.google.com/forum/?fromgroups#!topic/objects-on-rails/0-GTFdgPTLc">a very representative thread</a> on the excellent Objects on Rails mailing list.</p>
<p>Much of time, decorators seem to come out ahead, but comparing the two is pretty complex. In this article I want to add my opinions to the discussion. Let's start by looking at some examples.</p>
<h4>Decoration</h4>
<p>Let's say that I have a simple server that just receives messages and displays what was sent:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">require</span> <span class="s2">"socket"</span>
<span class="n">server</span> <span class="o">=</span> <span class="no">TCPServer</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"127.0.0.1"</span><span class="p">,</span> <span class="mi">61676</span><span class="p">)</span>
<span class="no">Socket</span><span class="o">.</span><span class="n">accept_loop</span><span class="p">(</span><span class="n">server</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">connection</span><span class="p">,</span> <span class="n">_</span><span class="o">|</span>
<span class="k">while</span> <span class="p">(</span><span class="n">object_sent</span> <span class="o">=</span> <span class="n">connection</span><span class="o">.</span><span class="n">gets</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"Received: %p"</span> <span class="o">%</span> <span class="o">[</span><span class="n">object_sent</span><span class="o">]</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>This is pretty crude. It doesn't even handle concurrent connections, but it will work fine for the purposes of this example.</p>
<p>We also need a simple client to send some messages to our server:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">require</span> <span class="s2">"socket"</span>
<span class="n">server</span> <span class="o">=</span> <span class="no">TCPSocket</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"127.0.0.1"</span><span class="p">,</span> <span class="mi">61676</span><span class="p">)</span>
<span class="n">object_to_send</span> <span class="o">=</span> <span class="s2">"A message."</span>
<span class="n">server</span><span class="o">.</span><span class="n">puts</span> <span class="n">object_to_send</span>
</pre></div>
<p>At this point I can:</p>
<ol>
<li>Start the server in one shell</li>
<li>Run the client in a separate shell</li>
<li>See output in the server's shell</li>
</ol><p>The end result looks like this from the server's shell:</p>
<pre><code>$ ruby server.rb
Received: "A message.\n"
</code></pre>
<p>That's nice, but let's say it's not quite what I want. I can really just send <code>String</code> messages using this simple setup, but perhaps I would prefer to be able to send other Ruby objects, like an <code>Array</code> or <code>Hash</code>.</p>
<p>Let's add that capability to our client and server. I'll start that process by creating a <code>serialization.rb</code> file and defining a couple of decorators in there:</p>
<div class="highlight highlight-ruby"><pre><span class="k">class</span> <span class="nc">Serializer</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">socket</span><span class="p">)</span>
<span class="vi">@socket</span> <span class="o">=</span> <span class="n">socket</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">puts</span><span class="p">(</span><span class="o">*</span><span class="n">objects</span><span class="p">)</span>
<span class="n">objects</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">object</span><span class="o">|</span>
<span class="n">serialized</span> <span class="o">=</span> <span class="no">Marshal</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">object</span><span class="p">)</span>
<span class="vi">@socket</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="o">[</span><span class="n">serialized</span><span class="o">.</span><span class="n">length</span><span class="p">,</span> <span class="n">serialized</span><span class="o">].</span><span class="n">pack</span><span class="p">(</span><span class="s2">"NA*"</span><span class="p">))</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Deserializer</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">socket</span><span class="p">)</span>
<span class="vi">@socket</span> <span class="o">=</span> <span class="n">socket</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">gets</span>
<span class="k">if</span> <span class="p">(</span><span class="n">message</span> <span class="o">=</span> <span class="vi">@socket</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span><span class="p">))</span>
<span class="n">object_size</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s2">"N"</span><span class="p">)</span><span class="o">.</span><span class="n">first</span>
<span class="no">Marshal</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="vi">@socket</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">object_size</span><span class="p">))</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>Both of these objects take a <code>Socket</code>, store it away for later use, then wrap the simple <code>IO</code> methods that my client and server are using to communicate. The wrappers manage a very simple serialization process where we convert a Ruby object to a binary representation and then send the length in bytes followed by those bytes. The other end can peek at the length, read that many bytes, and rehydrate the object.</p>
<p>I've skimped on the error handling here to keep the code simple. A more robust version of this code would need to make sure the serialized object length doesn't overflow the size of the number we're sending and handle the various networking errors that can occur.</p>
<p>Now let's update the client to support serialization:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">require</span> <span class="s2">"socket"</span>
<span class="n">require_relative</span> <span class="s2">"serialization"</span>
<span class="n">server</span> <span class="o">=</span> <span class="no">TCPSocket</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"127.0.0.1"</span><span class="p">,</span> <span class="mi">61676</span><span class="p">)</span>
<span class="n">server</span> <span class="o">=</span> <span class="no">Serializer</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">server</span><span class="p">)</span> <span class="c1"># decorate the socket</span>
<span class="n">object_to_send</span> <span class="o">=</span> <span class="sx">%w[A more complex message.]</span>
<span class="n">server</span><span class="o">.</span><span class="n">puts</span> <span class="n">object_to_send</span>
</pre></div>
<p>Notice that, aside from the added <code>require_relative()</code> call and the switch to a more complex object to show off serialization, there's really just one new line here. That line wraps the socket connection to the server in our decorator. This replaces the default <code>puts()</code> logic with our more involved process. That change actually takes effect on the last line of the client, but we didn't need to modify that code. That's the whole idea behind decoration.</p>
<p>The server is just as easy to update:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">require</span> <span class="s2">"socket"</span>
<span class="n">require_relative</span> <span class="s2">"serialization"</span>
<span class="n">server</span> <span class="o">=</span> <span class="no">TCPServer</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"127.0.0.1"</span><span class="p">,</span> <span class="mi">61676</span><span class="p">)</span>
<span class="no">Socket</span><span class="o">.</span><span class="n">accept_loop</span><span class="p">(</span><span class="n">server</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">connection</span><span class="p">,</span> <span class="n">_</span><span class="o">|</span>
<span class="n">connection</span> <span class="o">=</span> <span class="no">Deserializer</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">connection</span><span class="p">)</span> <span class="c1"># decorate the socket</span>
<span class="k">while</span> <span class="p">(</span><span class="n">object_sent</span> <span class="o">=</span> <span class="n">connection</span><span class="o">.</span><span class="n">gets</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"Received: %p"</span> <span class="o">%</span> <span class="o">[</span><span class="n">object_sent</span><span class="o">]</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>Again, all we need to do is wrap the connection to our client with the decorator. That replaces the <code>gets()</code> operation and we still didn't need to touch that code.</p>
<p>If I run the server and client again, we can see that the <code>Array</code> does come through:</p>
<pre><code>$ ruby server.rb
Received: ["A", "more", "complex", "message."]
</code></pre>
<p>It's time to admit that I purposefully selected this example to be something decorators are just perfect for. They really excel at these layering-on-functionality tasks. <a href="http://www.javaworld.com/javaworld/jw-12-2001/jw-1214-designpatterns.html">Java's IO class hierarchy</a> is built much like the code I just showed for exactly this reason.</p>
<p>For comparison's sake though, let's switch to an example where I don't think decorators are as good of a fit, at least in Ruby.</p>
<h4>Mixing It Up</h4>
<p>I've shown an example very similar to this next one before, in <a href="/rubies-in-the-rough/learn-to-love-mix-ins">an article about mix-ins</a>, but let me flesh it out a bit more this time so we can really discuss why I handle it the way I do.</p>
<p>Let's say that I have some not-quite-CSV data in a file:</p>
<pre><code>"Name (last, first)",Job
"Gray, James \"JEG2\"",Developer
"Gray, Dana",Full-time Mommy
"Gray, Summer","\"Cutie Pie\""
</code></pre>
<p>That data isn't really valid, according to the CSV standard. It should be doubling quotes to escape them (<code>""</code>), not using backslashes (<code>\"</code>).</p>
<p>I would like to read that data with the standard <code>CSV</code> library so I can take advantage of the things it can do for me, like parsing out the headers. I want to use some code like the following:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">require</span> <span class="s2">"csv"</span>
<span class="no">CSV</span><span class="o">.</span><span class="n">foreach</span><span class="p">(</span><span class="s2">"not_quite_csv.csv"</span><span class="p">,</span> <span class="ss">headers</span><span class="p">:</span> <span class="kp">true</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">row</span><span class="o">|</span>
<span class="nb">p</span> <span class="n">row</span><span class="o">.</span><span class="n">to_hash</span>
<span class="k">end</span>
</pre></div>
<p>But the <code>CSV</code> library doesn't recognize this format:</p>
<pre><code>$ ruby read_csv.rb
…: Missing or stray quote in line 2 (CSV::MalformedCSVError)
…
</code></pre>
<p>To handle that, I would use a mix-in that fixes the data between the time when it is read and the time when <code>CSV</code> tries to parse it. Let's code that up:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">require</span> <span class="s2">"csv"</span>
<span class="k">module</span> <span class="nn">CSVNormalizer</span>
<span class="k">def</span> <span class="nf">gets</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="n">line</span> <span class="o">=</span> <span class="k">super</span>
<span class="k">if</span> <span class="n">line</span>
<span class="n">line</span><span class="o">.</span><span class="n">gsub!</span><span class="p">(</span><span class="sr">/"(?:\\\\|\\"|[^"])*"/</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">field</span><span class="o">|</span>
<span class="n">field</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="sr">/(?<!\\)\\"/</span><span class="p">)</span> <span class="p">{</span> <span class="s1">'""'</span> <span class="p">}</span>
<span class="p">}</span>
<span class="k">end</span>
<span class="n">line</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">open</span><span class="p">(</span><span class="s2">"not_quite_csv.csv"</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">file</span><span class="o">|</span>
<span class="n">file</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="no">CSVNormalizer</span><span class="p">)</span>
<span class="n">csv</span> <span class="o">=</span> <span class="no">CSV</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="ss">headers</span><span class="p">:</span> <span class="kp">true</span><span class="p">)</span>
<span class="n">csv</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">row</span><span class="o">|</span>
<span class="nb">p</span> <span class="n">row</span><span class="o">.</span><span class="n">to_hash</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p><code>CSVNormalizer</code> is pretty straight forward. It just wraps <code>gets()</code> and gives me a place to do a few simple substitutions.</p>
<p>Don't lose too much sleep over understanding the regular expressions I used there. They just replace the escapes with the format CSV expects.</p>
<p>In the lower chunk of code, I switched how I do the hand-off to <code>CSV</code>. This lets me get a hold of the <code>File</code> object and <code>extend()</code> it before <code>CSV</code> tries to read from it.</p>
<p>This solution isn't really complete, because it doesn't yet handle the multi-line fields that real CSV data can contain. It does work for the data in my example though:</p>
<pre><code>$ ruby read_csv.rb
{"Name (last, first)"=>"Gray, James \"JEG2\"", "Job"=>"Developer"}
{"Name (last, first)"=>"Gray, Dana", "Job"=>"Full-time Mommy"}
{"Name (last, first)"=>"Gray, Summer", "Job"=>"\"Cutie Pie\""}
</code></pre>
<h4>The Decision</h4>
<p>I said that the second example is better as a mix-in. But why?</p>
<p>I mean you could choose to solve it with a decorator, right? Of course. Let's do that to see how it goes.</p>
<p>At first glance, it looks like we could get away with a few minor changes:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">require</span> <span class="s2">"csv"</span>
<span class="k">class</span> <span class="nc">CSVNormalizer</span> <span class="c1"># switch to a class</span>
<span class="c1"># store the IO for later use</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">io</span><span class="p">)</span>
<span class="vi">@io</span> <span class="o">=</span> <span class="n">io</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">gets</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="n">line</span> <span class="o">=</span> <span class="vi">@io</span><span class="o">.</span><span class="n">gets</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span> <span class="c1"># forward to the IO</span>
<span class="k">if</span> <span class="n">line</span>
<span class="n">line</span><span class="o">.</span><span class="n">gsub!</span><span class="p">(</span><span class="sr">/"(?:\\\\|\\"|[^"])*"/</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">field</span><span class="o">|</span>
<span class="n">field</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="sr">/(?<!\\)\\"/</span><span class="p">)</span> <span class="p">{</span> <span class="s1">'""'</span> <span class="p">}</span>
<span class="p">}</span>
<span class="k">end</span>
<span class="n">line</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">open</span><span class="p">(</span><span class="s2">"not_quite_csv.csv"</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">file</span><span class="o">|</span>
<span class="n">file</span> <span class="o">=</span> <span class="no">CSVNormalizer</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="c1"># decorate</span>
<span class="n">csv</span> <span class="o">=</span> <span class="no">CSV</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="ss">headers</span><span class="p">:</span> <span class="kp">true</span><span class="p">)</span>
<span class="n">csv</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">row</span><span class="o">|</span>
<span class="nb">p</span> <span class="n">row</span><span class="o">.</span><span class="n">to_hash</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>If you run that code, it will probably seem to run the same. But it's not equivalent. In order to show you why, I need to modify my data to use different line endings:</p>
<pre><code>$ ruby -pi -e 'gsub "\n", "\r\n"' not_quite_csv.csv
</code></pre>
<p>I'm on Unix, so I've switched the line endings to something I might have received from a Windows machine. You would need to go the other way if you are on Windows, but the end result is that our decorator is now broken:</p>
<pre><code>$ ruby read_csv.rb # using the decorator
…: Unquoted fields do not allow \r or \n (line 1). (CSV::MalformedCSVError)
…
</code></pre>
<p>That's interesting, because when I switch to the mix-in, it can read this data just fine:</p>
<pre><code>$ ruby read_csv.rb # using the mix-in
{"Name (last, first)"=>"Gray, James \"JEG2\"", "Job"=>"Developer"}
{"Name (last, first)"=>"Gray, Dana", "Job"=>"Full-time Mommy"}
{"Name (last, first)"=>"Gray, Summer", "Job"=>"\"Cutie Pie\""}
</code></pre>
<p>To know why this happens, you have to understand a little about how <code>CSV</code> works internally. As you can see, this whole line ending issue is kind of annoying. <code>CSV</code> tries to save you from needing to worry about that. By default, it will attempt to guess your line endings. You can always specify the ending manually if you need to, but a lot of times the guessing means that your program will just work without you taking any action.</p>
<p>That's what's happening with the mix-in version. No matter which line endings I feed it, <code>CSV</code> correctly guesses them and adapts. It just works.</p>
<p>Obviously we broke that in the decorator version, but how? Well, under the hood, <code>CSV</code> has to peek ahead at the data to guess the endings. It expects to be passed an <code>IO</code> object, so it calls on some <code>IO</code> methods to fetch some data and then reset the position pointer to where it was.</p>
<p>Of course, this feature doesn't always work. Sometimes you can't skip around in a stream like this. Consider <code>STDIN</code> or a <code>Socket</code> for example. So, if <code>CSV</code> cannot guess, it just defaults to the normal line endings for the current platform. That's the best we can do with no information to go on and the user can always specify the line ending manually as needed.</p>
<p>Now you can probably deduce why the decorator broken. It's not a full <code>IO</code> stand-in. We wrapped the method <code>CSV</code> needs to read data, but not the methods it uses to do the line ending guessing. That means it has to give up a go with the platform default.</p>
<p>All of this leads to the question: could we fix that? Sure. One option is that we could delegate the needed methods manually. Multiple methods are needed though, and if I wasn't the guy who wrote <code>CSV</code>, I wouldn't really know what they are. Plus, they could change some day. (That has actually happened. The algorithm was changed at one point to use different methods so it would work with more <code>IO</code>-like objects.) Given that, it's probably better to just forward any messages I don't want to wrap to the underlying <code>IO</code> object. That's easy enough to do:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">require</span> <span class="s2">"csv"</span>
<span class="k">class</span> <span class="nc">CSVNormalizer</span> <span class="o"><</span> <span class="no">BasicObject</span> <span class="c1"># make sure we delegate most calls</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">io</span><span class="p">)</span>
<span class="vi">@io</span> <span class="o">=</span> <span class="n">io</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">gets</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="n">line</span> <span class="o">=</span> <span class="vi">@io</span><span class="o">.</span><span class="n">gets</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="k">if</span> <span class="n">line</span>
<span class="n">line</span><span class="o">.</span><span class="n">gsub!</span><span class="p">(</span><span class="sr">/"(?:\\\\|\\"|[^"])*"/</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">field</span><span class="o">|</span>
<span class="n">field</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="sr">/(?<!\\)\\"/</span><span class="p">)</span> <span class="p">{</span> <span class="s1">'""'</span> <span class="p">}</span>
<span class="p">}</span>
<span class="k">end</span>
<span class="n">line</span>
<span class="k">end</span>
<span class="c1"># forward all other messages to the IO object</span>
<span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="nb">method</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="vi">@io</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="nb">method</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">open</span><span class="p">(</span><span class="s2">"not_quite_csv.csv"</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">file</span><span class="o">|</span>
<span class="n">file</span> <span class="o">=</span> <span class="no">CSVNormalizer</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">file</span><span class="p">)</span>
<span class="n">csv</span> <span class="o">=</span> <span class="no">CSV</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="ss">headers</span><span class="p">:</span> <span class="kp">true</span><span class="p">)</span>
<span class="n">csv</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">row</span><span class="o">|</span>
<span class="nb">p</span> <span class="n">row</span><span class="o">.</span><span class="n">to_hash</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>As the comments show, I only made two changes. First, I explicitly inherited from <code>BasicObject</code> instead of accepting the default <code>Object</code> parent. This means that my decorator responds to very few messages. Almost all incoming messages will hit <code>method_missing()</code> because of that change. The second change was to provide that <code>method_missing()</code> and have it push everything down to the underlying <code>IO</code>. This does restore the line ending guessing functionality and get the decorator fully working:</p>
<pre><code>$ ruby read_csv.rb # using the decorator again with tricky line endings
{"Name (last, first)"=>"Gray, James \"JEG2\"", "Job"=>"Developer"}
{"Name (last, first)"=>"Gray, Dana", "Job"=>"Full-time Mommy"}
{"Name (last, first)"=>"Gray, Summer", "Job"=>"\"Cutie Pie\""}
</code></pre>
<p>We now know what it takes build the equivalent decorator. If we compare the two, I say the mix-in is superior in this case. Here are my reasons:</p>
<ul>
<li>The whole point of the <code>BasicObject</code> and <code>method_missing()</code> trick is to do our own method dispatching here. Why do that? Ruby is better at that kind of thing than we are, so I would rather leave that task to the language whenever we can. What do I mean by "better?" Well, for one thing, we can use <code>super</code> when Ruby is doing the job. For another, Ruby is going to be much faster when dispatching. Rack (another good example of decorators) has a little of this latter problem. As frameworks that use Rack, like Rails, move more and more functionality into middleware, the call stack just gets longer and longer. This is the primary reason that they filter backtraces in Rails and it has slowed things down a little as incoming requests must pass through all of the layers.</li>
<li>The decorator object I ended up creating lies about what it really is. Consider methods like <code>class()</code>, <code>is_a?()</code>, and <code>ancestors()</code>. These are all going to tell me that I have a <code>File</code> object in the case above. That's only sort of accurate though. I could probably drop <code>BasicObject</code>, in this case, but then the lies just change to leave out any mention of the hidden <code>File</code> object. Compare that with the mix-in version which is fully reflection compliant. It can tell you all about its "types" no matter how many there are.</li>
</ul><p>Because of this, I tend to prefer mix-ins for cases where I am going to delegate an entire API. I feel like the advantages are pretty clear for those cases.</p>
<h4>Arguments for and Against Decorators</h4>
<p>I'm not trying to say there's no good uses for decorators. I've already provided some in this article. Greg Brown gives an even more spirited defense of them in <a href="https://practicingruby.com/articles/disciplined-inheritance-1">Practicing Ruby 3.7</a>, which is probably the most detailed, Ruby focused discussion of these issues to date. Greg is discussing higher level inheritance concepts in that article, but his examples largely boil down to an analysis of mix-ins and decorators.</p>
<p>I think Greg has some good and not-so-good points.</p>
<p>The best argument in favor of decorators, by far in my opinion, is the encapsulation issue. I think we normally envision encapsulation as hiding our data from the outside world, but in this case we're talking more about hiding it from ourselves. When you have some object with several mix-ins, how do we know that none of those methods have instance variable conflicts? Heck, the methods could even be accidentally overriding each other with unrelated functionality if we're not careful with naming. This could create some maddening bugs where things like the load order matter. These are very real and tough issues.</p>
<p>How often are we bitten by this encapsulation issue? I wish I knew. I think a strong test suite can help to reduce it. I also imagine it's less of a problem when most of the API is written by a single team. I'm guessing they would be more likely to catch misuses or impose naming conventions the protect themselves from these issues. But in the world where we embrace the value of sending Pull Requests on GitHub to fix most problems, I'm not sure how much of this safety we can count on.</p>
<p>I am less sold on the "bloated contracts" or "too many entry points" arguments that I see in many places, including Greg's post and the Objects on Rails thread I mentioned earlier. The example everyone throws around is <code>ActiveRecord::Base</code> which does have a ton of mix-ins. However, languages, libraries, and frameworks (like ActiveRecord) have different goals than we do for our application code.</p>
<p>We want to keep application code as minimal as possible and expose even less than we write whenever possible. This helps with many, many aspects of application development.</p>
<p>As I mentioned though, languages, libraries, and frameworks have almost the opposite goals. They want to cast their nets far and wide. They expose a lot and let your code decide which pieces it needs to do its work.</p>
<p>This makes sense when you think about it. The more a library does for us, the less application code we end up writing. That satisfies both aims.</p>
<p>Even if you sympathize with the bloated contract argument, I'm not convinced that decorators do much for it. Each individual object may respond to less messages, but is that going to save you from reading the documentation of all of those decorator classes? It didn't save me a ton of memorization when I passed the Java certification, I can tell you that much. The big API is still there, even if we do a better job of hiding it.</p>
<p>Testability is another complaint I often see leveled at mix-ins that I'm skeptical of. By way of example, let's test the mix-in I made earlier. I created a <code>csv_spec.rb</code> file and added this code to it to get started:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">CSVNormalizer</span>
<span class="k">def</span> <span class="nf">gets</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="n">line</span> <span class="o">=</span> <span class="k">super</span>
<span class="k">if</span> <span class="n">line</span>
<span class="n">line</span><span class="o">.</span><span class="n">gsub!</span><span class="p">(</span><span class="sr">/"(?:\\\\|\\"|[^"])*"/</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">field</span><span class="o">|</span>
<span class="n">field</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="sr">/(?<!\\)\\"/</span><span class="p">)</span> <span class="p">{</span> <span class="s1">'""'</span> <span class="p">}</span>
<span class="p">}</span>
<span class="k">end</span>
<span class="n">line</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">describe</span> <span class="no">CSVNormalizer</span> <span class="k">do</span>
<span class="n">let</span><span class="p">(</span><span class="ss">:message_queue</span><span class="p">)</span> <span class="p">{</span> <span class="o">[</span> <span class="o">]</span> <span class="p">}</span>
<span class="k">def</span> <span class="nf">gets</span><span class="p">(</span><span class="o">*</span><span class="n">_</span><span class="p">)</span>
<span class="n">message_queue</span><span class="o">.</span><span class="n">shift</span>
<span class="k">end</span>
<span class="n">before</span> <span class="k">do</span>
<span class="kp">extend</span><span class="p">(</span><span class="no">CSVNormalizer</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">it</span> <span class="s2">"translates escaped quotes as they are read"</span> <span class="k">do</span>
<span class="n">message_queue</span> <span class="o"><<</span> <span class="s1">'"a \"quoted\" field"'</span>
<span class="nb">gets</span><span class="o">.</span><span class="n">should</span> <span class="n">eq</span><span class="p">(</span><span class="s1">'"a ""quoted"" field"'</span><span class="p">)</span>
<span class="k">end</span>
<span class="c1"># ...</span>
<span class="k">end</span>
</pre></div>
<p>As you can see, I just gave my example group the expected <code>gets()</code> method and then extended it with my <code>CSVNormalizer</code>. From there I can test normally. I don't feel like I'm jumping through a lot of extra hoops here compared to testing a normal object, but you be the judge.</p>
<h4>The Winner Is…</h4>
<p>I don't think we can definitively say that one approach is superior to the other in all cases. I hope given compelling use cases for both in this article.</p>
<p>Mix-ins seems to be the underdog in most of these discussions, but I'm not quite ready to write them off. I hope I've shown that there are at least some things going for them.</p>
<p>As with most things in programming, I think it pays to try to understand as many of these angles as we can and make the best choices we can on a case by case basis.</p>
<p>The biggest question remaining for me is if we can do better at modeling large API's, like ActiveRecord, with the tools Ruby gives us. Is there a good way to use composition there without the mix-ins? I'm not sure. Hopefully some Rubyist will improve on the formula and enlighten us.</p>
<h4>Further Reading</h4>
<p>If you really enjoy this kind of analysis about how to build objects, there are some terrific resources out there that you might want to take a deeper look at:</p>
<ul>
<li>
<a href="http://www.pearsonhighered.com/educator/product/Smalltalk-Best-Practice-Patterns/9780134769042.page">Smalltalk Best Practice Patterns</a> can be expensive to pick up these days and you may need to learn a new language just to read it. The truth is though that it's totally worth it. I learned more about objects from this one book than probably all others combined. While it doesn't cover these issues directly, it gave me a lot of the foundation that I use to think through these issues.</li>
<li>
<a href="https://groups.google.com/forum/#!forum/objects-on-rails">The Objects on Rails mailing list</a> started out as a place to give Avdi Grimm feedback for <a href="http://objectsonrails.com/">the ebook of the same name</a>. Luckily, it seems to be sticking around even now that the book is out and, better yet, growing into the go-to source for these discussions in Rubyland. Reading that list is pretty addictive for object geeks like me.</li>
<li>
<a href="http://designpatternsinruby.com/">Design Patterns in Ruby</a> does a great job of looking the various design patterns, like decorators, both in a traditional light and through Ruby colored glasses. This can provide quite a bit of insight when it comes to adapting patterns from other languages.</li>
</ul>James Edward Gray IISingle Method Classestag:graysoftinc.com,2012-05-01:/posts/1132014-04-29T03:10:09ZIn this article I discuss one of my pet peeves and show how you can avoid it by understanding what Ruby's modules are really for.<p><em>[<strong>Update</strong>: I've changed my mind about some of the following due to <a href="http://blog.codeclimate.com/blog/2012/11/14/why-ruby-class-methods-resist-refactoring/">this excellent counter argument</a>.]</em></p>
<p>In the words of Dennis Miller, "I don't want to get off on a rant here, but…"</p>
<p>There's something that drives me crazy and I see it in so much Ruby code. I see it in the documentation for our key projects; I see Rubyists of all skill levels doing it; it's just everywhere.</p>
<p>Let's talk about when the use of a <code>Class</code> is and is not appropriate.</p>
<h4>The Chained new()</h4>
<p>Here's an example of one form of code that bugs me:</p>
<div class="highlight highlight-ruby"><pre><span class="k">class</span> <span class="nc">Adder</span>
<span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
<span class="mi">40</span> <span class="o">+</span> <span class="n">n</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="no">Adder</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
</pre></div>
<p>The problem here is that a <code>Class</code> has been used, probably because as Rubyists that's always our default choice, but it's the wrong fit for this code. A <code>Class</code> is for state and behavior. The example above is just using behavior. No state is maintained.</p>
<p>A handy tip for sniffing out this problem is watching for a call to <code>new()</code> in the middle of method chaining as we have here. If you always use a <code>Class</code> like that, it's not really a <code>Class</code>. Put another way, if an instance never gets assigned to a variable, something has likely gone wrong with the design.</p>
<p>Here's a slightly trickier version:</p>
<div class="highlight highlight-ruby"><pre><span class="k">class</span> <span class="nc">Adder</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
<span class="vi">@n</span> <span class="o">=</span> <span class="n">n</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
<span class="vi">@n</span> <span class="o">+</span> <span class="n">n</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>Does this code have the same problem? It depends on how it gets used. If it's always used with a chained <code>new()</code> then it's the same thing we looked at above:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">p</span> <span class="no">Adder</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="mi">40</span><span class="p">)</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
</pre></div>
<p>State isn't really being tracked here. It's just an illusion.</p>
<p>However, it may be fine if the <code>Adder</code> is sometimes used like this:</p>
<div class="highlight highlight-ruby"><pre><span class="n">forty</span> <span class="o">=</span> <span class="no">Adder</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="mi">40</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"40 + 1 = </span><span class="si">#{</span><span class="n">forty</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span>
<span class="nb">puts</span> <span class="s2">"40 + 2 = </span><span class="si">#{</span><span class="n">forty</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span>
<span class="nb">puts</span> <span class="s2">"40 + 3 = </span><span class="si">#{</span><span class="n">forty</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span>
</pre></div>
<p>Note the variable assignment. As I said before, this is our hint that things are on the up and up. In this case, some value is locked-in so we can then run some experiments on it. That initial value is state, so this is a fine use for a <code>Class</code>.</p>
<p>This isn't the only form of the problem we need to watch out for though.</p>
<h5>The Unused new()</h5>
<p>Some programmers see my first example and think, "No problem. Let's remove the <code>new()</code>." They will often change the code to be something like this:</p>
<div class="highlight highlight-ruby"><pre><span class="k">class</span> <span class="nc">Adder</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">add</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
<span class="mi">40</span> <span class="o">+</span> <span class="n">n</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="no">Adder</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
</pre></div>
<p>This isn't any better. Yes, the chained call to <code>new()</code> is gone. However, now we have a new problem. What does this mean?</p>
<div class="highlight highlight-ruby"><pre><span class="n">what_am_i</span> <span class="o">=</span> <span class="no">Adder</span><span class="o">.</span><span class="n">new</span>
</pre></div>
<p>A <code>Class</code> is a factory for manufacturing instances of some type. With this code, I am still allowed to make those instances, but they are completely pointless. There's no meaningful state or behavior for my new instance.</p>
<p>We could used some Ruby tricks to make <code>new()</code> uncallable, but that's not really better. Introspection would still tell us that <code>Adder</code> is a <code>Class</code>. That's a lie. It's not for manufacturing instances.</p>
<p>That's why this problem bugs me when I see it in code, by the way. Remember, the primary purpose of code is to communicate with the reader. Always. Period. Code that uses <code>Class</code>es in this way does not do that well. When I see a <code>Class</code>, I am thinking about the instances it will be used to manufacture. If that's not its purpose, I have been lead astray. We want our code to communicate better.</p>
<h4>The One Word Fix</h4>
<p>We have multiple choices for how to improve code like this, when we see it. The easiest is to make a one word change to my last example:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">Adder</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">add</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
<span class="mi">40</span> <span class="o">+</span> <span class="n">n</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="no">Adder</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
</pre></div>
<p>Now we are working with a <code>Module</code> instead of a <code>Class</code>. The rules have changed. A <code>Module</code> is not used to manufacture instances. It can't do that. It's not really for maintaining state (though I admit that there are minor exceptions to this).</p>
<p>The important point is that I won't be thinking about instances when I read this code. It communicates better.</p>
<p>Is it the best we can do though?</p>
<h5>Dual Natured</h5>
<p>While a <code>Module</code> is not an instance factory, it does fill multiple roles in Ruby. This isn't your fault. A <code>Module</code> is a bit of an overloaded concept in the language.</p>
<p>First, a <code>Module</code> is often used as a namespace in Ruby. It can group together related constants and methods. We are fine with that meaning here. It just says that the <code>add()</code> method is part of the <code>Adder</code> namespace. No problem.</p>
<p>A <code>Module</code> is also a place to hang methods that don't belong on a <code>Class</code>, typically because they don't maintain any state. Conversion methods are a great example of this. Think of <code>ERB::Util.h()</code>. Again, this meaning is fine. We actually switched to a <code>Module</code> for exactly this reason.</p>
<p>Finally, a <code>Module</code> can be used as a mix-in in Ruby. This essentially allows plugging it into any other scope. It will add its methods and constants to that scope. This last meaning is a bit of a problem for our "fixed" code. The reason is that it's possible to write this code using our last example:</p>
<div class="highlight highlight-ruby"><pre><span class="k">class</span> <span class="nc">SomeMathyThing</span>
<span class="kp">include</span> <span class="no">Adder</span>
<span class="k">end</span>
</pre></div>
<p>This is similar to our unused <code>new()</code> problem. While we can mix this <code>Module</code> in (because you can do that with any Ruby <code>Module</code>), it has no meaning. Only instance-level methods and constants matter when mixing a <code>Module</code> in and we didn't define either of those.</p>
<p>I want to stress that this isn't your fault. This is a quirk of how Ruby is designed. Switching to a <code>Module</code> is still an acceptable fix.</p>
<p>The question is, could we do even better? Could we bring our code in line with all three meanings of Ruby's <code>Module</code>. If we can, it might just communicate even better. That's a noble goal, so let's try it.</p>
<p>It turns out that Ruby includes a not-too-well-known tool just for this reason. A <code>Module</code> that uses this tool can be used both as a bag of methods and a mix-in. For example, take a look at the built-in <code>Math</code> <code>Module</code>:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">SomeMathyThing</span>
<span class="kp">extend</span> <span class="no">Math</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">do_math</span>
<span class="n">sqrt</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="no">Math</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="nb">p</span> <span class="no">SomeMathyThing</span><span class="o">.</span><span class="n">do_math</span>
</pre></div>
<p>As you can see we can call methods on <code>Math</code> directly and we can also add <code>Math</code> to other scopes when it makes sense. It fits all three definitions of a <code>Module</code> in Ruby.</p>
<p>The <code>Kernel</code> <code>Module</code> also behaves this way. If you were in some context that defined a <code>p()</code> method, you could still get to the one in <code>Kernel</code> if you needed it. The code for that would be <code>::Kernel.p()</code>. The leading <code>::</code> forces the constant lookup to happen from the top level, where <code>Kernel</code> lives. That ensures you will get the right <code>Kernel</code>, even if another constant with the same name is available in your current scope. Then we just call <code>p()</code> on the <code>Module</code> normally.</p>
<p>This is done with the help of <code>module_function()</code> and we can use it ourselves:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">Adder</span>
<span class="kp">module_function</span>
<span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
<span class="mi">40</span> <span class="o">+</span> <span class="n">n</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">SomeMathyThing</span>
<span class="kp">extend</span> <span class="no">Adder</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">do_add</span>
<span class="n">add</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="no">Adder</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="nb">p</span> <span class="no">SomeMathyThing</span><span class="o">.</span><span class="n">do_add</span>
</pre></div>
<p>Notice that I just defined normal instance-level methods after calling <code>module_function()</code>. <code>module_function()</code> is like Ruby's <code>public()</code> and <code>private()</code> in that it will affect methods that follow, when used without an argument. (It does support passing arguments to affect specific methods as well.)</p>
<h5>Controlling Access</h5>
<p>Transforming a method with <code>module_function()</code> does a couple of things. First, the instance level methods are copied up to the <code>Module</code> level. This is what allows for the dual interface.</p>
<p>Another effect of <code>module_function()</code> is that the instance level methods are made <code>private()</code>. This prevents them from adding to any external interface when they are used as a mix-in. This is also why things like <code>Kernel</code>'s <code>p()</code> cannot be called with a receiver, except in the <code>Module</code> level access case I showed earlier. In other words, this code will throw a "private method called" error even with our last example:</p>
<div class="highlight highlight-ruby"><pre><span class="no">Object</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="no">Adder</span><span class="p">)</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
</pre></div>
<p>This is usually desirable, but if you have a case where you would prefer to control access for the methods you define, you're probably going to lock horns with <code>module_function()</code>.</p>
<p>There's a trick you can use to get around even that. Checkout this example:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">AccessControlled</span>
<span class="kp">extend</span> <span class="nb">self</span>
<span class="k">def</span> <span class="nf">share_me</span>
<span class="n">hide_me</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s2">"private"</span><span class="p">,</span> <span class="s2">"public"</span><span class="p">)</span>
<span class="k">end</span>
<span class="kp">private</span>
<span class="k">def</span> <span class="nf">hide_me</span>
<span class="s2">"I am a private interface."</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="no">AccessControlled</span><span class="o">.</span><span class="n">share_me</span>
<span class="nb">p</span> <span class="no">Object</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="no">AccessControlled</span><span class="p">)</span><span class="o">.</span><span class="n">share_me</span>
</pre></div>
<p>The magic line is <code>extend self</code> which mixes the <code>Module</code> into itself at the <code>Module</code> level. This gives the same kind of dual interface we had before, but it also respects the access control we have setup for the methods. You can see that <code>share_me()</code> does add to the public interface of objects it is mixed into. Also, both of the following lines are errors, assuming the code above:</p>
<div class="highlight highlight-ruby"><pre><span class="no">AccessControlled</span><span class="o">.</span><span class="n">hide_me</span>
<span class="no">Object</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="no">AccessControlled</span><span class="p">)</span><span class="o">.</span><span class="n">hide_me</span>
</pre></div>
<p>I tend to reach for <code>module_function()</code> first, preferring to keep as much <code>private()</code> as I can get away with. If I find myself in a situation where I need more control over visibility though, I'll switch to <code>extend self</code>.</p>
<h4>The One True Interface</h4>
<p>I want to cover one last semi-related point.</p>
<p>A lot of API's ask us to pass an object that responds to a certain method. If you are expecting just one method, make it <code>call()</code>.</p>
<p>I think the downside to this approach is that programmer's worry it's not as expressive. While that's the right concern to have, I don't think it's as bad we think. It basically comes to this code <code>validater.valid?(whatever)</code> verses <code>validater.call(whatever)</code>. While the former does clearly express what is happening, the second still comes out pretty OK in plain English, "Mr. Validater I am now calling upon you to do your job."</p>
<p>Plus there's just too much gain for going with <code>call()</code>. It's already been decided: <code>call()</code> is the preferred one method interface in Ruby. This makes you compatible with <code>Proc</code> (and <code>lambda()</code>) and <code>Rack</code>, just to give some key examples. That allows me to skip defining a <code>Class</code>/<code>Module</code> altogether if my needs are simple or possibly to serve whatever I am defining in a Web application. That's just because you chose to go with <code>call()</code>. Standard interfaces are handy.</p>
<p>If I haven't swayed you, at least support both, with some code like this:</p>
<div class="highlight highlight-ruby"><pre><span class="k">if</span> <span class="n">validater</span><span class="o">.</span><span class="n">respond_to?</span><span class="p">(</span><span class="ss">:valid?</span><span class="p">)</span>
<span class="n">validater</span><span class="o">.</span><span class="n">valid?</span><span class="p">(</span><span class="n">whatever</span><span class="p">)</span>
<span class="k">else</span>
<span class="n">validater</span><span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">whatever</span><span class="p">)</span>
<span class="k">end</span>
</pre></div>
<h4>Help Me End This Bad Habit</h4>
<p>You now know that every time I see these single method stateless <code>Class</code>es in the wild I die a little inside. Have pity on my aging heart! Here's what you can do to help:</p>
<ul>
<li>Check your code. I know you were reading this whole article thinking, "I don't do that." However, you probably do. Find code like this and improve it.</li>
<li>Ignore bad documentation. Whenever a Ruby project's documentation tells you to define these silly <code>Class</code>es, try it my way first. It pretty much always works just fine.</li>
<li>Fix the code and documentation of others. Start sending patches. Share a link to this article when you do. Let's make this less common. I'll live longer.</li>
</ul>James Edward Gray IILearn to Love Mix-instag:graysoftinc.com,2012-03-21:/posts/1102014-04-27T15:37:55ZIn this article I distill all of my hard-won knowledge of how we should use mix-ins in Ruby code for type construction and method overriding.<p>The road to mastering Ruby is paved with understanding some key Ruby concepts. Mix-ins are one of those concepts. I'm sure everyone reading this knows the mechanics of how mix-ins work, but it pays to spend some time really thinking about all that mix-ins imply. Let's do just that.</p>
<h4>Adding a Type</h4>
<p>One of the primary reasons that Ruby needs mix-ins is that it does not support multiple inheritance. That leaves mix-ins as our only option for modeling hybrid objects. It's the way Ruby programmers can add another type.</p>
<p>That's a good way to think about it too: adding a type.</p>
<p>Take pagination, for example. Pagination methods are usually defined to return an object like this:</p>
<div class="highlight highlight-ruby"><pre><span class="k">class</span> <span class="nc">PaginatedCollection</span> <span class="o"><</span> <span class="nb">Array</span>
<span class="c1"># ... paginated helpers defined here ...</span>
<span class="k">end</span>
</pre></div>
<p>That's never really felt right to me though.</p>
<p>First, inheriting from Ruby's core classes can come back to bite you in some scenarios. The reason is that Ruby makes some performance tradeoffs to keep the core classes fast, but those tradeoffs mean that those classes don't always perfectly follow Ruby's rules.</p>
<p>You can get around some of these issues by delegating to an <code>Array</code>, instead of inheriting from it. But that creates even more structure for this setup when it seems that Ruby has a totally workable built-in solution.</p>
<p>The name of the created <code>Class</code> is another hint that it's not ideal, in my opinion: <code>PaginatedCollection</code>. <code>Collection</code> is just another way to say <code>Array</code>, right? So why can't we just say <code>Array</code>? In truth, <code>Collection</code> implies a lot more than just an <code>Array</code>, but solutions like this don't generally adapt to other types.</p>
<p>That leaves just <code>Paginated</code>, which is used as an adjective here. Adjectives are generally better modeled by a <code>Module</code> than a <code>Class</code>. It's almost like Ruby is telling us the right way to model this concept, if we listen closely enough.</p>
<p>To me, it's telling us to build this:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">Paginated</span>
<span class="k">def</span> <span class="nf">paginate</span><span class="p">(</span><span class="n">page</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="n">items_per_page</span> <span class="o">=</span> <span class="n">size</span><span class="p">,</span> <span class="n">total_items</span> <span class="o">=</span> <span class="n">size</span><span class="p">)</span>
<span class="vi">@page</span> <span class="o">=</span> <span class="n">page</span>
<span class="vi">@items_per_page</span> <span class="o">=</span> <span class="n">items_per_page</span>
<span class="vi">@total_items</span> <span class="o">=</span> <span class="n">total_items</span>
<span class="k">end</span>
<span class="kp">attr_reader</span> <span class="ss">:page</span><span class="p">,</span> <span class="ss">:items_per_page</span><span class="p">,</span> <span class="ss">:total_items</span>
<span class="k">def</span> <span class="nf">total_pages</span>
<span class="p">(</span><span class="n">total_items</span> <span class="o">/</span> <span class="n">items_per_page</span><span class="o">.</span><span class="n">to_f</span><span class="p">)</span><span class="o">.</span><span class="n">ceil</span>
<span class="k">end</span>
<span class="c1"># etc...</span>
<span class="k">end</span>
<span class="n">collection</span> <span class="o">=</span> <span class="sx">%w[first second third]</span>
<span class="n">collection</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="no">Paginated</span><span class="p">)</span>
<span class="n">collection</span><span class="o">.</span><span class="n">paginate</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"There are </span><span class="si">#{</span><span class="n">collection</span><span class="o">.</span><span class="n">total_pages</span><span class="si">}</span><span class="s2"> pages."</span>
<span class="nb">puts</span> <span class="s2">"The collection is an Array."</span> <span class="k">if</span> <span class="n">collection</span><span class="o">.</span><span class="n">is_a?</span><span class="p">(</span><span class="nb">Array</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"The collection is a Paginated object."</span> <span class="k">if</span> <span class="n">collection</span><span class="o">.</span><span class="n">is_a?</span><span class="p">(</span><span class="no">Paginated</span><span class="p">)</span>
</pre></div>
<p>That seems more natural. The item is an <code>Array</code>. It also happens to be <code>Paginated</code>. We can understand that duality and so can Ruby.</p>
<p>Semantics aside though, this has actual benefits. The code works just fine if I change this line:</p>
<div class="highlight highlight-ruby"><pre><span class="n">collection</span> <span class="o">=</span> <span class="sx">%w[first second third]</span>
</pre></div>
<p>to:</p>
<div class="highlight highlight-ruby"><pre><span class="nb">require</span> <span class="s2">"set"</span>
<span class="n">collection</span> <span class="o">=</span> <span class="no">Set</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="sx">%w[first second third]</span><span class="p">)</span>
</pre></div>
<p>or even:</p>
<div class="highlight highlight-ruby"><pre><span class="n">collection</span> <span class="o">=</span> <span class="p">{</span><span class="ss">first</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="ss">second</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="ss">third</span><span class="p">:</span> <span class="mi">3</span><span class="p">}</span>
</pre></div>
<p>In other words, we can now paginate whatever we want, including our own classes. We can also mix <code>Paginated</code> into any result set we need to, without needing to use some special collection and a <code>replace()</code> method (as you sometimes see in Rails code using <a href="https://github.com/mislav/will_paginate">will_paginate</a>).</p>
<p>There's even another plus to this approach though: you can make these type decisions as the code runs. Let's dig into what that can do for us.</p>
<h4>What do I Need Now?</h4>
<p>Another great aspect of using mix-ins to build up these types is that objects can be different things at different times. We'll start with a somewhat silly, but illustrative, example:</p>
<div class="highlight highlight-ruby"><pre><span class="k">class</span> <span class="nc">Human</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span> <span class="n">strength</span><span class="p">)</span>
<span class="vi">@name</span> <span class="o">=</span> <span class="nb">name</span>
<span class="vi">@strength</span> <span class="o">=</span> <span class="n">strength</span>
<span class="k">end</span>
<span class="kp">attr_reader</span> <span class="ss">:name</span><span class="p">,</span> <span class="ss">:strength</span>
<span class="k">def</span> <span class="nf">move</span>
<span class="s2">"</span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2"> walks."</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">Werewolf</span>
<span class="k">module</span> <span class="nn">HybridForm</span>
<span class="k">def</span> <span class="nf">strength</span>
<span class="k">super</span> <span class="o">+</span> <span class="mi">5</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">move</span>
<span class="k">super</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s2">"walks"</span><span class="p">,</span> <span class="s2">"lopes"</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">WolfForm</span>
<span class="k">def</span> <span class="nf">strength</span>
<span class="mi">2</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">move</span>
<span class="k">super</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s2">"walks"</span><span class="p">,</span> <span class="s2">"runs on all fours"</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">human</span> <span class="o">=</span> <span class="no">Human</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">"James"</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"Normally, </span><span class="si">#{</span><span class="n">human</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2"> is a </span><span class="si">#{</span><span class="n">human</span><span class="o">.</span><span class="n">class</span><span class="si">}</span><span class="s2"> "</span> <span class="o">+</span>
<span class="s2">"with a strength of </span><span class="si">#{</span><span class="n">human</span><span class="o">.</span><span class="n">strength</span><span class="si">}</span><span class="s2">. </span><span class="si">#{</span><span class="n">human</span><span class="o">.</span><span class="n">move</span><span class="si">}</span><span class="s2">"</span>
<span class="nb">puts</span>
<span class="n">werewolf</span> <span class="o">=</span> <span class="n">human</span><span class="o">.</span><span class="n">dup</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="no">Werewolf</span><span class="o">::</span><span class="no">HybridForm</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"But when there's a full moon, "</span> <span class="o">+</span>
<span class="s2">"strength raises to </span><span class="si">#{</span><span class="n">werewolf</span><span class="o">.</span><span class="n">strength</span><span class="si">}</span><span class="s2"> and </span><span class="si">#{</span><span class="n">werewolf</span><span class="o">.</span><span class="n">move</span><span class="si">}</span><span class="s2">"</span>
<span class="nb">puts</span>
<span class="n">wolf</span> <span class="o">=</span> <span class="n">human</span><span class="o">.</span><span class="n">dup</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="no">Werewolf</span><span class="o">::</span><span class="no">WolfForm</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"Some also claim to have seen him as a normal wolf, "</span> <span class="o">+</span>
<span class="s2">"with a strength of </span><span class="si">#{</span><span class="n">wolf</span><span class="o">.</span><span class="n">strength</span><span class="si">}</span><span class="s2">."</span>
<span class="nb">puts</span> <span class="s2">"In this form </span><span class="si">#{</span><span class="n">wolf</span><span class="o">.</span><span class="n">move</span><span class="si">}</span><span class="s2">"</span>
</pre></div>
<p>That code outputs:</p>
<pre><code>Normally, James is a Human with a strength of 3. James walks.
But when there's a full moon, strength raises to 8 and James lopes.
Some also claim to have seen him as a normal wolf, with a strength of 2.
In this form James runs on all fours.
</code></pre>
<p>As you can see, we're able to change the <code>human</code> object as needed. We can add in the abilities of the <code>Werewolf::HybridForm</code> or the <code>Werewolf::WolfForm</code>. The object then has those behaviors.</p>
<p>Believe it or not, this does have practical value outside of building fantasy games. For example, I once worked on a Rails application that had some pretty complex reporting needs. The queries used to do the reporting were a bit sluggish, so we wanted to make sure that kind of thing never got run during a normal request. Thus we had a model and a separate <code>Module</code> for the reporting code. They looked something like:</p>
<div class="highlight highlight-ruby"><pre><span class="k">class</span> <span class="nc">User</span> <span class="o"><</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
<span class="c1"># no generate_report method here</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">Reportable</span>
<span class="k">def</span> <span class="nf">generate_report</span>
<span class="c1"># build and return a processing intensive report</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>The <code>Module</code> wasn't even loaded by our normal application. Instead, we ran a nightly background process, on a different server, that used our backup dump of the database to do the reporting. That code is where the <code>Module</code> actually lived. The reporting process then used it in a loop like this:</p>
<div class="highlight highlight-ruby"><pre><span class="no">User</span><span class="o">.</span><span class="n">find_each</span> <span class="k">do</span> <span class="o">|</span><span class="n">user</span><span class="o">|</span>
<span class="n">user</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="no">Reportable</span><span class="p">)</span>
<span class="n">report</span> <span class="o">=</span> <span class="n">user</span><span class="o">.</span><span class="n">generate_report</span>
<span class="c1"># report sending code here...</span>
<span class="k">end</span>
</pre></div>
<p>This has other benefits besides safety. For example, it really helps with code organization. The reporting code was quite complex and it just didn't apply to the normal workings of the application. With this setup, we only had to dig through that code when it was relevant to what we were doing. The rest of the time we could pretty much forget it was there. (We did have tests to ensure <code>User</code> kept the contract <code>Reportable</code> counted on, so we wouldn't accidentally break it.)</p>
<p>I would like to see Rails move towards supporting a system like this. I'll build a plugin at some point that lets you add various mix-ins for the models. They could be stored in the application like this:</p>
<pre><code>app/models/user.rb
app/models/user/authenticatible.rb
app/models/user/reportable.rb
…
</code></pre>
<p>Then I'll add a method for mixing these into the query results they apply to. For example:</p>
<div class="highlight highlight-ruby"><pre><span class="n">user_logging_in</span> <span class="o">=</span> <span class="no">User</span><span class="o">.</span><span class="n">behavior</span><span class="p">(</span><span class="no">Authenticatible</span><span class="p">)</span><span class="o">.</span><span class="n">find_by_email</span><span class="p">(</span><span class="n">email</span><span class="p">)</span>
</pre></div>
<p>and:</p>
<div class="highlight highlight-ruby"><pre><span class="no">User</span><span class="o">.</span><span class="n">behavior</span><span class="p">(</span><span class="no">Reportable</span><span class="p">)</span><span class="o">.</span><span class="n">find_each</span> <span class="k">do</span> <span class="o">|</span><span class="n">user</span><span class="o">|</span>
<span class="c1"># ... generate reports...</span>
<span class="k">end</span>
</pre></div>
<p>You get the idea.</p>
<p>OK, let's consider modules in one more way to round out this exercise.</p>
<h4>Monkey Patching is Generally Silly</h4>
<p>We always say that we love how dynamic Ruby is. It allows us to rewrite the rules as we go. The ultimate expression of this is how we can just reopen a class and replace some of its methods wholesale. We lovingly refer to this practice as "monkey patching."</p>
<p>When you think about it though, the practice is almost silly for most of the cases we use it for.</p>
<p>To explain that claim, we need to take a quick detour and discuss Ruby's method lookup. Instead of explaining how it works, let's just ask Ruby to show us:</p>
<div class="highlight highlight-ruby"><pre><span class="k">class</span> <span class="nc">Object</span>
<span class="k">def</span> <span class="nf">show_yourself</span>
<span class="nb">puts</span> <span class="s2">"In Object."</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Parent</span>
<span class="k">def</span> <span class="nf">show_yourself</span>
<span class="nb">puts</span> <span class="s2">"In Parent."</span>
<span class="nb">puts</span> <span class="s2">"Handing up the line..."</span>
<span class="nb">puts</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Child</span> <span class="o"><</span> <span class="no">Parent</span>
<span class="k">def</span> <span class="nf">show_yourself</span>
<span class="nb">puts</span> <span class="s2">"In Child."</span>
<span class="nb">puts</span> <span class="s2">"Handing up the line..."</span>
<span class="nb">puts</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">o</span> <span class="o">=</span> <span class="no">Child</span><span class="o">.</span><span class="n">new</span>
<span class="n">o</span><span class="o">.</span><span class="n">show_yourself</span>
</pre></div>
<p>That code prints:</p>
<pre><code>In Child.
Handing up the line...
In Parent.
Handing up the line...
In Object.
</code></pre>
<p>Hopefully, that's pretty straightforward. We called a method on a <code>Child</code> instance. That method then handed up to the same method defined in <code>Parent</code>, because <code>Child</code> inherits from <code>Parent</code>. That method then hands up to <code>Object</code>, because anything that doesn't declare a superclass, like <code>Parent</code>, gets <code>Object</code>.</p>
<p>In Ruby though, that's not the full story. Let's change the last chunk of code to this:</p>
<div class="highlight highlight-ruby"><pre><span class="c1"># ...</span>
<span class="n">o</span> <span class="o">=</span> <span class="no">Child</span><span class="o">.</span><span class="n">new</span>
<span class="k">class</span> <span class="o"><<</span> <span class="n">o</span>
<span class="k">def</span> <span class="nf">show_yourself</span>
<span class="nb">puts</span> <span class="s2">"In the hidden singleton class."</span>
<span class="nb">puts</span> <span class="s2">"Handing up the line..."</span>
<span class="nb">puts</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">o</span><span class="o">.</span><span class="n">show_yourself</span>
</pre></div>
<p>Now we get this output:</p>
<pre><code>In the hidden singleton class.
Handing up the line...
In Child.
Handing up the line...
In Parent.
Handing up the line...
In Object.
</code></pre>
<p>Each instance in Ruby has its own <code>Class</code>, called the singleton class. (No, we're not talking about the Singleton design pattern here. This is a different use of the term.) This is why we can modify individual objects no matter what their <code>Class</code> is. The specializations end up in the singleton class. Ruby mostly hides this class from us as an implementation detail, which is why I had to open the object's singleton class explicitly to get it to show up above.</p>
<p>We can now see that method lookup is a straight line in Ruby. You start at the bottom, with the object's singleton class and go straight up until you find a matching method.</p>
<p>That leads us to a question though: how do mix-ins play into this? The answer is pretty simple: they are inserted into the call chain <strong>behind</strong> a <code>Class</code>. <em>[<strong>Update</strong>: Ruby 2's <code>prepend()</code> gives us the ability to insert mix-ins <strong>in front of</strong> a <code>Class</code> as well.]</em> To see what I mean, let's mix something into <code>Child</code>:</p>
<div class="highlight highlight-ruby"><pre><span class="c1"># ...</span>
<span class="k">module</span> <span class="nn">Mixin</span>
<span class="k">def</span> <span class="nf">show_yourself</span>
<span class="nb">puts</span> <span class="s2">"In Mixin."</span>
<span class="nb">puts</span> <span class="s2">"Handing up the line..."</span>
<span class="nb">puts</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Child</span> <span class="o"><</span> <span class="no">Parent</span>
<span class="kp">include</span> <span class="no">Mixin</span>
<span class="k">def</span> <span class="nf">show_yourself</span>
<span class="nb">puts</span> <span class="s2">"In Child."</span>
<span class="nb">puts</span> <span class="s2">"Handing up the line..."</span>
<span class="nb">puts</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># ...</span>
</pre></div>
<p>That prints:</p>
<pre><code>In the hidden singleton class.
Handing up the line...
In Child.
Handing up the line...
In Mixin.
Handing up the line...
In Parent.
Handing up the line...
In Object.
</code></pre>
<p>See how <code>Mixin</code> just hopped in line behind <code>Child</code>? That's what they do.</p>
<p>Well, that's what <code>include()</code> does. Isn't <code>extend()</code> special? Not really. The fact is that <code>extend()</code> is just a shortcut that translates to this:</p>
<div class="highlight highlight-ruby"><pre><span class="k">def</span> <span class="nf">extend</span><span class="p">(</span><span class="n">mixin</span><span class="p">)</span>
<span class="n">singleton_class</span><span class="o">.</span><span class="n">class_eval</span> <span class="k">do</span>
<span class="kp">include</span> <span class="n">mixin</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>As you can see, <code>extend()</code> just does an <code>include()</code> under the hood, but it does it on the singleton class. Using that knowledge, we can modify our example one last time to show off a superior form of monkey patching:</p>
<div class="highlight highlight-ruby"><pre><span class="c1"># ...</span>
<span class="k">module</span> <span class="nn">SuperiorMonkeyPatch</span>
<span class="k">def</span> <span class="nf">show_yourself</span>
<span class="nb">puts</span> <span class="s2">"In SuperiorMonkeyPatch."</span>
<span class="nb">puts</span> <span class="s2">"Handing up the line..."</span>
<span class="nb">puts</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">o</span> <span class="o">=</span> <span class="no">Child</span><span class="o">.</span><span class="n">new</span>
<span class="n">o</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="no">SuperiorMonkeyPatch</span><span class="p">)</span>
<span class="k">class</span> <span class="o"><<</span> <span class="n">o</span>
<span class="k">def</span> <span class="nf">show_yourself</span>
<span class="nb">puts</span> <span class="s2">"In the hidden singleton class."</span>
<span class="nb">puts</span> <span class="s2">"Handing up the line..."</span>
<span class="nb">puts</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">o</span><span class="o">.</span><span class="n">show_yourself</span>
</pre></div>
<p>Now the code prints:</p>
<pre><code>In the hidden singleton class.
Handing up the line...
In SuperiorMonkeyPatch.
Handing up the line...
In Child.
Handing up the line...
In Mixin.
Handing up the line...
In Parent.
Handing up the line...
In Object.
</code></pre>
<p>Note the <code>SuperiorMonkeyPatch</code> is <strong>behind</strong> the singleton class, because mix-ins are always inserted behind a <code>Class</code>. But that puts it <strong>in front of</strong> <code>Child</code>, which is right where we need it to be if we want to override some behavior.</p>
<p>To sum this up, the key insights are:</p>
<ul>
<li>Ruby's method lookup is just a straight line</li>
<li>Using mix-ins, we can insert code at various points along that line</li>
</ul><p>This is the ideal way to override behavior. Why? Well, if you monkey patch a <code>Class</code>, you have changed it for the whole world. We've already seen though that mix-ins give us the choice of when we want the changes and when we don't.</p>
<p>Furthermore, you have to be very careful when monkey patching if you want to keep the old code. This involves a dance of aliasing (really copying) the old method, replacing it, and then referring to the renamed code. (That's how the infamous <code>alias_method_chain()</code> in Rails works.) With a mix-in though, <code>super</code> can be used normally.</p>
<p>This makes using a <code>Module</code> safer. We're not all playing in one namespace and aliasing a bunch of names that could eventually collide.</p>
<p>To give a realistic example of how you can use this technique in practice, let's talk about a support email I received recently. The programmer who wrote me was working with a database that spit out some pretty goofy CSV. It would escape quotes with <code>\"</code>, even though the CSV format calls for <code>""</code>. It also escaped other things, like null characters as <code>\0</code>. Because this created a non-standard data format, he couldn't find anything that could read it. That made him write me and ask if there were some way he could modify the <code>CSV</code> library to read it.</p>
<p>"No need," I told him. CSV is a simple wrapper over a normal Ruby <code>IO</code> object and it mostly just counts on one method <code>gets()</code>. When you call <code>CSV#gets</code>, it pulls some data from <code>IO#gets</code>, then parses it and returns it to you. That gives us a familiar method lookup line:</p>
<pre><code> IO#gets
^
|
CSV#gets
</code></pre>
<p>All we need to do is get some code in the middle of that line. That code can translate from the broken CSV format to the correct format the library expects and everything else will just work. No monkey patching is required. Here's the code I sent to him:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">CSVNormalizer</span>
<span class="k">def</span> <span class="nf">gets</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="k">super</span>
<span class="k">if</span> <span class="n">result</span>
<span class="c1"># FIXME: Improve escape handling</span>
<span class="n">result</span><span class="o">.</span><span class="n">gsub!</span><span class="p">(</span><span class="sr">/\\(["0])/</span><span class="p">)</span> <span class="p">{</span> <span class="vg">$1</span> <span class="o">==</span> <span class="s2">"0"</span> <span class="p">?</span> <span class="s2">"</span><span class="se">\0</span><span class="s2">"</span> <span class="p">:</span> <span class="s1">'""'</span> <span class="p">}</span>
<span class="k">end</span>
<span class="n">result</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">if</span> <span class="bp">__FILE__</span> <span class="o">==</span> <span class="vg">$PROGRAM_NAME</span>
<span class="nb">require</span> <span class="s2">"csv"</span>
<span class="nb">abort</span> <span class="s2">"</span><span class="si">#{</span><span class="vg">$PROGRAM_NAME</span><span class="si">}</span><span class="s2"> FILE_PATH"</span> <span class="k">unless</span> <span class="no">ARGV</span><span class="o">.</span><span class="n">first</span>
<span class="nb">open</span><span class="p">(</span><span class="no">ARGV</span><span class="o">.</span><span class="n">first</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">io</span><span class="o">|</span>
<span class="n">io</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="no">CSVNormalizer</span><span class="p">)</span>
<span class="n">csv</span> <span class="o">=</span> <span class="no">CSV</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">io</span><span class="p">)</span>
<span class="n">csv</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">row</span><span class="o">|</span>
<span class="c1"># use row here...</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>My unescaping code may not be perfect, if there are other scenarios than those he described, but that's not the point. Note how easy this was to setup: I defined a module that uses <code>super</code> to get the data, transforms it, and returns the fixed data; I manually setup the <code>IO</code> object, instead of letting <code>CSV</code> do it for me; I used my mix-in to make that object return good data; then I hand the now safe-to-use object on to <code>CSV</code>. This is a clean patch job that won't affect any other code, even if we use it in a project that also processes some normal CSV data. Perfect.</p>
<h4>Keep Modules in Mind</h4>
<p>Ruby gives us these different ways to construct types using mix-ins. We can combine them, use them conditionally, and even build up modified behaviors with them, as needed.</p>
<p>A lot of this power comes the elegance of how Ruby handles method lookup. Once you realize that message passing happens down a straight line and that you can make interceptions at points along that line, you gain a lot of control over what is happening in your programs.</p>
<p>I strongly encourage to play with these techniques in your programs, or just on the side. It can take a while for all of this to click, but it really expands your understanding of Ruby when you get there.</p>
<h4>Learn More About Modules</h4>
<p>If you enjoyed this discussion of how to make mix-ins work for you, I'm pretty sure you would also enjoy:</p>
<ul>
<li>
<a href="http://www.confreaks.com/videos/201-lsrc2009-module-magic">Module Magic</a> is a presentation I gave at the Lone Star Ruby Conference in 2009. I showed some of the tricks discussed above (in less detail) and some other handy tricks you can use. My <a href="http://www.slideshare.net/JamesEdwardGrayII/module-magic">slides</a> are also available.</li>
<li>The book <a href="http://pragprog.com/book/jvrails/crafting-rails-applications">Crafting Rails Applications</a> is a detailed explanation of how Rails 3 works under the hood. One of the most significant changes from Rails 2 to Rails 3, was to rework the framework from using old style monkey patching (with <code>alias_method_chain()</code>) to the <code>Module</code> approach I've covered here. This had many benefits which this book covers very well. We <a href="http://rubyrogues.com/048-rr-crafting-rails-applications-with-jose-valim/">discussed this book on the Ruby Rogues podcast</a>.</li>
<li>Dave Thomas did a screencast series a while back on <a href="http://pragprog.com/screencasts/v-dtrubyom/the-ruby-object-model-and-metaprogramming">The Ruby Object Model and Metaprogramming</a>. Though it uses an old version of Ruby, and misses out on some niceties added later (like the <code>singleton_class()</code> method), it's easily one of the best discussions of Ruby's method lookup system and a lot more. If you have struggled to understand the tricks we are using when metaprogramming, this is the place to get those questions answered.</li>
</ul>James Edward Gray IIClass Level Mix-instag:graysoftinc.com,2006-02-22:/posts/112014-03-28T21:32:39ZIn this article, I show how to mix methods in as class methods, instead of instance methods.<p>A question that comes up pretty often in Ruby circles was posed again today, by Xavier Noria:</p>
<div class="highlight highlight-ruby"><pre><span class="c1">#</span>
<span class="c1"># Is there standard idiom to add module methods to classes that mix them in?</span>
<span class="c1">#</span>
<span class="c1"># That is, I would like class C to croak:</span>
<span class="c1">#</span>
<span class="k">module</span> <span class="nn">M</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">croak</span>
<span class="nb">puts</span> <span class="s2">"Croak!"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">C</span>
<span class="kp">include</span> <span class="n">M</span>
<span class="n">croak</span> <span class="c1"># doesn't work</span>
<span class="k">end</span>
</pre></div>
<p>This brings up a couple of interesting points about mix-ins. Obviously, class methods are not easily added to things, but we generally want class methods so we can call them directly from the module. Here's how I deal with this issue.</p>
<p>First, instance methods are the way to go for anything you will be mixing in, period. With instance methods, you can inject them into a class or object. With anything else you have to start hacking. That gives us our first change:</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">M</span>
<span class="k">def</span> <span class="nf">croak</span>
<span class="nb">puts</span> <span class="s2">"Croak!"</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>Now, we really wanted a module method, so I've made things worse. However, as I've said, we have all the choices with this setup. Let's just mix the module into it's own class!</p>
<div class="highlight highlight-ruby"><pre><span class="k">module</span> <span class="nn">M</span>
<span class="kp">extend</span> <span class="nb">self</span> <span class="c1"># creates self.croak</span>
<span class="k">def</span> <span class="nf">croak</span>
<span class="nb">puts</span> <span class="s2">"Croak!"</span>
<span class="k">end</span>
<span class="k">end</span>
</pre></div>
<p>This trick of duplicating all instance methods as module methods is quite handy. I use it in Rails to make testing helper methods trivial, for example. You basically get two interfaces for the price of one. You can call module methods or mix it into objects.</p>
<p>We've already seen how to fix Xavier's class using the new module, but here it is in writing:</p>
<div class="highlight highlight-ruby"><pre><span class="k">class</span> <span class="nc">C</span>
<span class="kp">extend</span> <span class="n">M</span>
<span class="n">croak</span> <span class="c1"># works fine now</span>
<span class="k">end</span>
</pre></div>
<p>Remember, module methods are more powerful if they are instance methods, because you then have all the easy choices. Just mix them into whatever you like, even if it is the module itself.</p>James Edward Gray II