<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ernie Miller</title>
	<atom:link href="http://erniemiller.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://erniemiller.org</link>
	<description>No, I don&#039;t work in NYC, DC, or the valley, and I&#039;m cool with that.</description>
	<lastBuildDate>Sat, 15 Dec 2012 19:56:08 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5</generator>
		<item>
		<title>Why I Love Being A Programmer in Louisville (or, Why I Won&#8217;t Relocate to Work for Your Startup)</title>
		<link>http://erniemiller.org/2012/12/15/why-i-love-being-a-programmer-in-louisville-or-why-i-wont-relocate-to-work-for-your-startup/</link>
		<comments>http://erniemiller.org/2012/12/15/why-i-love-being-a-programmer-in-louisville-or-why-i-wont-relocate-to-work-for-your-startup/#comments</comments>
		<pubDate>Sat, 15 Dec 2012 19:56:08 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[life]]></category>
		<category><![CDATA[philosophy]]></category>

		<guid isPermaLink="false">http://erniemiller.org/?p=1247</guid>
		<description><![CDATA[For a while now, I&#8217;ve had the tagline you see on this site&#8217;s header as of this writing: No, I don&#8217;t work in NYC, DC, or the valley, and I&#8217;m cool with that. Like many (if not most) of you, I&#8217;m regularly contacted by recruiters. Unsurprisingly, they generally haven&#8217;t learned anything specific about me, aside [...]]]></description>
				<content:encoded><![CDATA[<p>For a while now, I&#8217;ve had the tagline you see on this site&#8217;s header as of this writing:</p>
<blockquote><p>
No, I don&#8217;t work in NYC, DC, or the valley, and I&#8217;m cool with that.
</p></blockquote>
<p>Like many (if not most) of you, I&#8217;m regularly contacted by recruiters. Unsurprisingly, they generally haven&#8217;t learned anything specific about me, aside from what they find on my <a href="http://www.linkedin.com/in/erniemiller">LinkedIn</a> or <a href="http://github.com/ernie">GitHub</a> profile. If they <em>have</em> visited this site, they certainly haven&#8217;t read the tagline. I&#8217;m getting tired of sending out what amounts to the same e-mail (though still probably more customized than the typical recruiter e-mail) over and over again, so I hope those of you who primarily read this blog for useful bits of Ruby info will forgive me this brief and selfish digression.</p>
<p>I am a software developer in Louisville, Kentucky, and I am really freaking happy here.<br />
<span id="more-1247"></span></p>
<h2 id="optimizingforhappiness">Optimizing for Happiness</h2>
<p>A common theme in the development community I most readily identify with (the Ruby community) is one of <a href="http://tom.preston-werner.com/2010/10/18/optimize-for-happiness.html">optimizing for happiness</a>. I&#8217;d like to think this is largely because the language itself makes developer happiness a design goal. Whatever the reason, in the same way that GitHub has optimized their company for happiness, and Ruby has optimized itself for happiness, I strive to optimize my daily life for happiness.</p>
<p><em>Duh. Everyone does that,</em> you might think.</p>
<p>Maybe. As I&#8217;ve talked to other programmers, I get the distinct impression that if they are optimizing for happiness, they&#8217;re being a good deal less <em>intentional</em> about it.</p>
<p>Let&#8217;s get this out of the way: Being a programmer is one of the most singularly satifying careers in the world. We get to wake up every morning and create things, solve interesting problems, and, if we&#8217;re doing our jobs well, make people happy. <strong>AND WE CAN DO THIS FROM ANYWHERE IN THE WORLD.</strong> This means that we get to shape our lives and careers in ways that are impossible in many professions. If that doesn&#8217;t make you smile, please see your doctor (who, by the way, doesn&#8217;t get to have as much fun on his job as you do).</p>
<p>Anyway, back to shaping our lives. Since we can do our job from anywhere in the world, and only a company that is either ignorant or supremely distrustful of its employees would insist otherwise (Right? <em>RIGHT?</em>), we can live anywhere, and that choice impacts so many other areas of our lives that we should pick a place that works for us, and then sort out the rest.</p>
<p>So, why did I pick Louisville?</p>
<h2 id="louisvilleismorethanhorseracingandfriedchicken.">Louisville is more than horse racing and fried chicken.</h2>
<p>We also have bourbon. ;)</p>
<p>But seriously, I first chose to relocate to Louisville when I was 24. I remember joking when considering the move: &#8220;I&#8217;m not sure why I&#8217;m doing this, all they&#8217;ve got there is horse racing and fried chicken.&#8221; I was incredibly wrong, and it&#8217;s only gotten better since then. By the way, you should totally come visit: among a number of other <a href="http://www.louisvilleky.gov/Mayor/IWantTo/rankings.htm">rankings and recognitions</a>, Louisville was named the <a href="http://www.lonelyplanet.com/usa/travel-tips-and-articles/77583">#1 US Travel Destination</a> of 2013 by Lonely Planet.</p>
<p>Aside from the obvious horse racing and tons of great dining options, it&#8217;s got a number of other things you&#8217;d expect from a &#8220;respectable&#8221; city:</p>
<ul>
<li>A <a href="http://en.wikipedia.org/wiki/History_of_Louisville,_Kentucky">rich history</a>.</li>
<li>A great <a href="http://www.flickr.com/photos/moseleyfoto/5888775499/">skyline</a></li>
<li>Enjoy live performances? The <a href="http://www.kentuckycenter.org/">Kentucky Center for the Performing Arts</a> has you covered.</li>
<li>Are museums your thing? There are <a href="http://en.wikipedia.org/wiki/List_of_museums_in_Louisville,_Kentucky">plenty</a> of them <a href="http://www.museumrowonmain.com/">here</a>. My personal favorite is the <a href="http://www.fraziermuseum.org/">Frazier History Museum</a> (formerly the Frazier Historical Arms Museum) which regularly has <a href="http://www.myarmoury.com/feature_visit_frazier.html">exhibits on loan from The Royal Armouries, Leeds</a>.</li>
<li>Into the night life? We&#8217;ve got lots of <a href="http://louisville.metromix.com/bars-and-clubs">bars and clubs</a> downtown.</li>
<li>Hipster type? There&#8217;s a definite hipster/college-town vibe going on in the Highlands.</li>
</ul>
<p>There&#8217;s more, but the general point I&#8217;m trying to make is that Louisville has what you&#8217;d expect from any great city, the difference being that you can drive about 15 minutes in almost any direction and be in a more rural setting. This is a huge pro in my book, because&#8230;</p>
<h2 id="louisvillehelpsmemanagecomplexity">Louisville Helps Me Manage Complexity</h2>
<p>Ask any competent programmer his or her thoughts on managing complexity in code, and you&#8217;re likely to receive a lengthy response. We have an instinctive and universally negative reaction to the introduction of unnecessary complexity in our code, but somehow fail to maintain those defenses in our day-to-day lives.</p>
<p>I grew up in a very rural town in Pennsylvania. I enjoy the quiet, and, though you wouldn&#8217;t know it if you met me on the street or at a conference, I&#8217;m an introvert. Louisville gives me the option of plenty of stuff to do, but plenty of peace and quiet when I want to recharge. I work remotely, but having experienced what we call &#8220;rush hour&#8221; here, compared to other cities, even if I did have to work in a local office, I wouldn&#8217;t lose much of my life to the commute (more on commutes in a second).</p>
<p>I think I&#8217;m one of the only people in the country who doesn&#8217;t hate his <a href="http://www.myinsight.com/">cable company</a>. They provide me with really reliable and surprisingly-high-speed cable Internet access (50/5 asymmetrical) for what I consider a reasonable price. This makes working remotely a breeze. This is important, because working remotely is a key part of my personal optimization for happiness.</p>
<h2 id="timeisnotmoney">Time is Not Money&#8230;</h2>
<p>It&#8217;s often said that &#8220;time is money,&#8221; but nothing could be more misleading. Time is most definitely <em>not</em> money. Some of us have much more of the latter than others, but everyone has the same 24 hours in their day. Therefore, I value my time, and I protect it. When I do decide to &#8220;waste&#8221; time, I try very hard to do so on my terms. Here, again, Louisville helps me.</p>
<p>I already mentioned that I crave peace and quiet to recharge. If having that place to recharge meant dealing with an hour-long commute each day, or long drives every time I wanted to do anything even remotely entertaining, I don&#8217;t think I&#8217;d make the trade.</p>
<p>Because Louisville is basically a small town with big city perks, I can engineer a simplicity in my daily life that lets me conserve my time and energy for things I find important. It all ties together nicely:</p>
<ul>
<li>Availability of extremely reliable, very fast Internet access makes working remotely a breeze, which eliminates a commute, giving me more time in my day, and allowing me to pick the location that makes my life simplest, instead of paying a mortgage to live in a location based on where my employer decided to do business.</li>
<li>I bought a house near my stepdaughter&#8217;s school, so she can walk to and from school, and transportation for extracurriculars is less of a problem.</li>
<li>The same house is 2 minutes away from my <a href="http://www.kokofitclub.com/">Koko FitClub</a>. Since their program fits both weight and interval-based cardio training into 45 minutes, I can make a trip to the gym over lunch, and grab a protein smoothie before coming home. Because I&#8217;m working from home, until Google Hangouts support the olfactory senses, my coworkers needn&#8217;t suffer as a result of my choice. This single thing has been so key to increasing my quality of life over the past 4 months it can&#8217;t be overstated. Seriously. Find a way to make workouts work into your schedule, and if you have a Koko FitClub near you, check them out. Their system is exceptionally appealing to nerds like me who like seeing numbers. :)</li>
<li>I&#8217;m about 10 minutes from my <a href="http://www.southeastchristian.org/">place of worship</a>, which is also a very important factor in my overall quality of life, and certainly my peace.</li>
<li>Louisville is the worldwide air hub for UPS. This means that everything I ship (or receive) is super-speedy for no extra cost, and makes online ordering even more of a no-brainer (which makes for less errands to run)</li>
</ul>
<h2 id="butmoneyisnicetoo">&#8230;But Money is Nice, Too</h2>
<p>The really awesome thing about being a remote worker is that your cost of living is dependent on where you live, but your value to the company that&#8217;s hiring you isn&#8217;t dependent on that, at all. Living in Louisville lets my dollar go farther than any of the &#8220;usual places&#8221; recruiters are trying to convince me to relocate.</p>
<p>To be honest, it leaves me scratching my head at interactions like this one, an actual exchange with a recruiter from a well-known NYC-based firm:</p>
<blockquote><p>
Hi Ernie,</p>
<p>I work at **** in R&amp;D.</p>
<p>I came across your profile today while searching for people with Ruby experience.</p>
<p>**** is always interested in speaking with top notch technologists.</p>
<p>I would like to schedule a quick call to discuss current and future opportunities here at ****. Can you provide some times and a phone number?
</p></blockquote>
<p>First, holy form-letter, Batman! But still, in the interest of education, I responded:</p>
<blockquote><p>
Would this position require relocation to NYC?
</p></blockquote>
<p>&#8230;and received this response:</p>
<blockquote><p>
Yes, we do provide relo package.
</p></blockquote>
<p>Right. Because the cost of <strong>moving</strong> would be what prevents me from taking a job in NYC.</p>
<p>Let&#8217;s assume for a moment here that I was anything less than completely satisfied with working for LivingSocial (I&#8217;m completely satisfied).</p>
<p>The cost of living in Louisville is 7.6% below national average. The cost of living in NYC is 123.8% above national average. In other words, I&#8217;d need to earn over twice as much money to maintain the same quality of life in NYC.</p>
<p>&#8220;So live in Jersey, and commute,&#8221; you say? See previous discussion about exercising control over how I spend my time. Also, Jersey is still significantly more expensive than Louisville.</p>
<p>Similar arguments against San Francisco, DC, and pretty much anywhere else that would require a lengthy commute to make the cost of living increase even bearable. Life&#8217;s too short to spend so much of it in between the places you truly want to be.</p>
<h2 id="intangibles">Intangibles</h2>
<p>So, time and money are easy to quantify. Here are some other reasons I love working in Louisville:</p>
<ul>
<li>We have generally mild winters without completely missing out on the change of seasons. I grew up with snow and wouldn&#8217;t enjoy living somewhere it never snowed (my wife will disagree with me on this one).</li>
<li>People are just nicer here. It&#8217;s good to live in a town where people still randomly say hello on the street. I don&#8217;t realize it&#8217;s odd until I travel and get strange &#8220;do I know you?&#8221; looks when I say &#8220;good morning&#8221; to someone.</li>
<li>I used to be depressed by the lack of a strong Ruby community here, but with recent developments (<a href="http://openhack.github.com/louisville/">OpenHack Louisville</a>, <a href="http://coderetreat.org/events/global-day-of-coderetreat-2012-louisville-kentucky-usa">Code Retreat Louisville</a>, and even <a href="http://www.codelouisville.org/">Code Louisville</a>) I&#8217;ve started to see this as a chance to help grow a community from the start, and especially to melt the brains of some of the Java/.Net-centric folks around here. I think good things are afoot in the Louisville tech scene, and I&#8217;m psyched to play a part in them.</li>
</ul>
<h2 id="beintentional--andbeyourownproductmanager">Be Intentional &#8211; and Be Your Own Product Manager</h2>
<p>If you aren&#8217;t a recruiter (many of whom I will no doubt be sending to this page) but a programmer, and somehow got to this point without getting bored:</p>
<ol>
<li>Congratulations!</li>
<li>Since you&#8217;re here, let me talk to you for a second.</li>
</ol>
<p>Are you happy where you are right now? Or, do you want to move to one of those &#8220;it&#8221; places when a recruiter asks you to? <strong>Great!</strong> I&#8217;m not going to try to convince you that Louisville&#8217;s a better choice for you (but it totally is). I just hope you&#8217;re taking a hard look at the choices you&#8217;ve made and the way you&#8217;ve always looked at your career. Be <em>intentional</em> about your choices.</p>
<p>I&#8217;ll leave you with this:</p>
<p>I was simultaneously encouraged and frustrated when I read Chad Fowler&#8217;s <a href="http://www.amazon.com/gp/product/1934356344/ref=as_li_ss_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1934356344&amp;linkCode=as2&amp;tag=metautonomous-20">The Passionate Programmer</a>. Encouraged, because he was eloquently and succinctly summarizing some of the things I&#8217;d come to realize over 15 years in software development. Frustrated, because I wished that I had been able to give that book to my 20-year-old self and prevent him from spending a decade in the cable telecommunications industry, being the guy doing things in a decidedly non-enterprise way, and being seen as the enemy for embracing &#8220;agile&#8221; techniques before I had ever even heard the term.</p>
<p>In the book, Chad dedicates an entire section to investing in your &#8220;product,&#8221; that product being yourself and your career. For many of us who grew up with parents who encouraged us to work hard and keep our heads down, that&#8217;s a foreign concept. These are the lessons I wish I had taught my 20 year old self, so he could be a better Product Manager:</p>
<ol>
<li>&#8220;Job security&#8221; is a myth created by big companies to trap you in a boring and unchallenging job. You will sign an employment-at-will agreement at every job you take.</li>
<li>Being good at what you do <em>does</em> ensure that when that day comes that you&#8217;re looking for work, you&#8217;ll find (or create) it in short order. <em>That</em> is job security.</li>
<li>Strive to feel stupid. If you aren&#8217;t regularly finding yourself uncomfortable with what you don&#8217;t know, then you aren&#8217;t pushing yourself hard enough. Don&#8217;t get comfortable. See #1.</li>
<li>Don&#8217;t take (or keep) a job because you like the people. If you&#8217;re a decent person, you&#8217;ll find people you like (and who like you) at any job you take. More importantly, if you really like them, you will want them to invest in their &#8220;product,&#8221; even if that means they won&#8217;t be working with you any more. Take the job that makes you excited to get out of bed in the morning. If it doesn&#8217;t exist, create it.</li>
</ol>
<h2 id="whewthatwasalongrant.">Whew! That was a long rant.</h2>
<p>Yeah, longer than I thought it would be, actually. Thanks for sticking with me. We now return you to your regularly scheduled Ruby ramblings.</p>
]]></content:encoded>
			<wfw:commentRss>http://erniemiller.org/2012/12/15/why-i-love-being-a-programmer-in-louisville-or-why-i-wont-relocate-to-work-for-your-startup/feed/</wfw:commentRss>
		<slash:comments>92</slash:comments>
		</item>
		<item>
		<title>Ruby Tidbit: Include vs Extend with Module Class Variables</title>
		<link>http://erniemiller.org/2012/11/29/ruby-tidbit-include-vs-extend-with-module-class-variables/</link>
		<comments>http://erniemiller.org/2012/11/29/ruby-tidbit-include-vs-extend-with-module-class-variables/#comments</comments>
		<pubDate>Thu, 29 Nov 2012 16:48:08 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://erniemiller.org/?p=1242</guid>
		<description><![CDATA[Ruby class variables don&#8217;t see a lot of use, largely due to one of their more interesting properties &#8212; inheriting classes see (and modify) the same object as their parent. Still, you will at some point find yourself using them, so it&#8217;s good to understand as much as possible about their behavior. Since modules can [...]]]></description>
				<content:encoded><![CDATA[<p>Ruby class variables don&#8217;t see a lot of use, largely due to one of their more interesting properties &#8212; inheriting classes see (and modify) the same object as their parent. Still, you will at some point find yourself using them, so it&#8217;s good to understand as much as possible about their behavior. Since modules can have &#8220;class variables&#8221;, I ran a quick experiment last night to see how they behaved. I found the result a little surprising, so I thought I would share.<br />
<span id="more-1242"></span></p>
<h2>Modules are Inheritance</h2>
<p>First, a quick reminder. Module inclusion in Ruby is inheritance. To demonstrate:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">module</span> Foo
  @@foo = <span style="color:#996600;">'foo'</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Bar
  <span style="color:#9966CC; font-weight:bold;">include</span> Foo
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
Bar.<span style="color:#9900CC;">ancestors</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>Foo<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;"># =&gt; true</span></pre></td></tr></table></div>

<p>Module extension adds the module&#8217;s methods to the extending object&#8217;s singleton class. So, as you might expect:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Baz
  extend Foo
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
Baz.<span style="color:#9900CC;">singleton_class</span>.<span style="color:#9900CC;">ancestors</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>Foo<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;"># =&gt; true</span></pre></td></tr></table></div>

<p>This is because extending the <tt>Foo</tt> module on <tt>Baz</tt> is the same as:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;">Baz.<span style="color:#9900CC;">singleton_class</span>.<span style="color:#9900CC;">send</span> :<span style="color:#9966CC; font-weight:bold;">include</span>, Foo</pre></td></tr></table></div>

<p>When I say &#8220;the same,&#8221; I mean it. Here&#8217;s the relevant code from MRI (eval.c):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span>
rb_extend_object<span style="color: #009900;">&#40;</span>VALUE obj<span style="color: #339933;">,</span> VALUE module<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    rb_include_module<span style="color: #009900;">&#40;</span>rb_singleton_class<span style="color: #009900;">&#40;</span>obj<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> module<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h2>So?</h2>
<p>Yeah, you know all this. OK, fine. Did you expect this? I didn&#8217;t.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;">Bar.<span style="color:#9900CC;">class_variable_get</span> :@@foo <span style="color:#008000; font-style:italic;"># =&gt; &quot;foo&quot;</span>
Baz.<span style="color:#9900CC;">singleton_class</span>.<span style="color:#9900CC;">class_variable_get</span> :@@foo
<span style="color:#008000; font-style:italic;"># =&gt; NameError: uninitialized class variable @@foo in Class</span></pre></td></tr></table></div>

<p>I did a bit more digging, and it would appear that <tt>rb_include_module</tt> (which, by the way, is known as <tt>Module#append_features</tt> in Ruby-land, in a clear attempt to screw with my brain) doesn&#8217;t actually append constants and class variables from a module to a singleton, but does add the module&#8217;s instance methods. This is from experimentation only &#8212; mentally parsing through the many #defines invoked in <tt>rb_include_module</tt> and <tt>include_class_new</tt> (which does the actual appending) was giving me a headache, and I suspect digging deeper would turn this from a Tidbit post into something more substantial, which I don&#8217;t have time to write up, anyway. I&#8217;d welcome explanation from someone with deeper insight into MRI internals, though! :)</p>
<p>Anyway, that&#8217;s it for now &#8212; hope you found this little tidbit as interesting as I did!</p>
<h2>[Update] BUT WAIT, THERE&#8217;S MORE!!</h2>
<p>So, I had a few minutes to play around this evening, and I decided to see how JRuby and Rubinius handled this situation. I&#8217;m glad I did! As it turns out, both JRuby and Rubinius do what I initially expected to see:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;">Baz.<span style="color:#9900CC;">singleton_class</span>.<span style="color:#9900CC;">class_variable_get</span> :@@foo <span style="color:#008000; font-style:italic;"># =&gt; &quot;foo&quot;</span></pre></td></tr></table></div>

<p>So, now I guess the question (in absence of an official Ruby spec) is whether or not this means the behavior in MRI is a bug.</p>
]]></content:encoded>
			<wfw:commentRss>http://erniemiller.org/2012/11/29/ruby-tidbit-include-vs-extend-with-module-class-variables/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Ruby Tidbit: String, the original value object</title>
		<link>http://erniemiller.org/2012/11/01/ruby-tidbit-string-the-original-value-object/</link>
		<comments>http://erniemiller.org/2012/11/01/ruby-tidbit-string-the-original-value-object/#comments</comments>
		<pubDate>Thu, 01 Nov 2012 05:03:15 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://erniemiller.org/?p=1235</guid>
		<description><![CDATA[Recently, a really great article was published over on the Code Climate Blog. Titled &#8220;7 Patterns to Refactor Fat ActiveRecord Models&#8221;, it&#8217;s a must read for everyone who works with Rails. If you haven&#8217;t read it, go do so. Seriously. I&#8217;ll wait. Anyway, at the very top of this list is a recommendation to extract [...]]]></description>
				<content:encoded><![CDATA[<p>Recently, a really great article was published over on the <a href="http://blog.codeclimate.com/">Code Climate Blog</a>. Titled <a href="http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/" title="7 Patterns to Refactor Fat ActiveRecord Models">&#8220;7 Patterns to Refactor Fat ActiveRecord Models&#8221;</a>, it&#8217;s a must read for everyone who works with Rails. If you haven&#8217;t read it, go do so.</p>
<p>Seriously. I&#8217;ll wait.</p>
<p>Anyway, at the very top of this list is a recommendation to extract value objects, and it got me thinking about a pattern I really like, which I wanted to share with you today.<br />
<span id="more-1235"></span><br />
In my day to day work, my value objects most often represent some special kind of string. A &#8220;slug&#8221; for a URL, a tag name, a specially formatted record name&#8230; whatever. </p>
<p>When that formatting logic needs to be reused, I&#8217;ve often seen code that places it into a mixin. Instead, I&#8217;ve taken to creating a value object by subclassing string, allowing simple reuse of the formatting logic anywhere in the codebase, and the ability to check the class of the object, to see if it&#8217;s been formatted. A couple of examples:</p>
<p>Aformentioned &#8220;slug&#8221;:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Slug <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#CC0066; font-weight:bold;">String</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>object<span style="color:#006600; font-weight:bold;">&#41;</span>
   object = object.<span style="color:#9900CC;">to_s</span>.<span style="color:#9900CC;">downcase</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#91;</span>^<span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">-</span>9a<span style="color:#006600; font-weight:bold;">-</span>z<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">+/</span>, <span style="color:#996600;">'-'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>^<span style="color:#006600; font-weight:bold;">-|-</span>$<span style="color:#006600; font-weight:bold;">/</span>, <span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">&#41;</span>
   <span style="color:#9966CC; font-weight:bold;">super</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>A formatted &#8220;record name&#8221; (name attribute on an ActiveRecord object) &#8212; I use a unique index on the column, so I want to make sure the records are formatted consistently to avoid differences in spacing (that people might not immediately notice) from causing success/failure:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> RecordName <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#CC0066; font-weight:bold;">String</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>object<span style="color:#006600; font-weight:bold;">&#41;</span>
   object = object.<span style="color:#9900CC;">to_s</span>.<span style="color:#9900CC;">strip</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>\s<span style="color:#006600; font-weight:bold;">+/</span>, <span style="color:#996600;">' '</span><span style="color:#006600; font-weight:bold;">&#41;</span>
   <span style="color:#9966CC; font-weight:bold;">super</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Ruby treats String subclasses just like strings. Unlike the kinds of equality tests you might implement in your own objects, no check is first made that both classes are the same, and it doesn&#8217;t matter which side of the operator you put them on. So:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;">Slug.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Unformatted Text!&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> == <span style="color:#996600;">'unformatted-text'</span> <span style="color:#008000; font-style:italic;"># =&gt; true</span>
<span style="color:#996600;">'unformatted-text'</span> == Slug.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Unformatted Text!&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;"># =&gt; true</span></pre></td></tr></table></div>

<p>Now, you can check that the string you&#8217;re receiving has been formatted elsewhere in the codebase without a regexp, and format it if needed:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;">str = Slug.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>str<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> str.<span style="color:#9900CC;">is_a</span>? Slug</pre></td></tr></table></div>

<p>If you&#8217;re concerned about mutability, you can always freeze in the initializer &#8212; I prefer to adhere to a contract that I won&#8217;t mutate these objects. Or, with some additional work, the mutator methods could be updated to support the formatting requirements, too.</p>
<p>Now, a final example that yields somewhat mixed results: a refactoring of the Rating class in the article at Code Climate.</p>
<p>A case could be made that a Rating is, in fact, a special kind of string. It has a value from A-F, allows comparison against other things in string form, hashes like its string value, etc. The comparison order being reversed, however, removes much of the benefit of &#8220;being a string,&#8221; since we can&#8217;t use strings and ratings on either side of all operators, as above.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Rating <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#CC0066; font-weight:bold;">String</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>object<span style="color:#006600; font-weight:bold;">&#41;</span>
    object = cost_to_rating<span style="color:#006600; font-weight:bold;">&#40;</span>object<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#CC00FF; font-weight:bold;">Numeric</span> === object
    object = object.<span style="color:#9900CC;">to_s</span>.<span style="color:#9900CC;">upcase</span>
    <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#CC00FF; font-weight:bold;">ArgumentError</span>, <span style="color:#996600;">&quot;Ratings are A-F!&quot;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'A'</span>..<span style="color:#996600;">'F'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9966CC; font-weight:bold;">include</span>? object
    <span style="color:#9966CC; font-weight:bold;">super</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#006600; font-weight:bold;">&lt;=&gt;</span><span style="color:#006600; font-weight:bold;">&#40;</span>other<span style="color:#006600; font-weight:bold;">&#41;</span>
    val = <span style="color:#9966CC; font-weight:bold;">super</span> <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#006600; font-weight:bold;">-</span>val
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">alias</span> better_than? <span style="color:#006600; font-weight:bold;">&gt;</span>
  <span style="color:#9966CC; font-weight:bold;">alias</span> worse_than? <span style="color:#006600; font-weight:bold;">&lt;</span>
&nbsp;
  private
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> cost_to_rating<span style="color:#006600; font-weight:bold;">&#40;</span>cost<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">case</span> cost
    <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006666;">0</span>..<span style="color:#006666;">2</span>
      <span style="color:#996600;">'A'</span>
    <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006666;">2</span>..<span style="color:#006666;">4</span>
      <span style="color:#996600;">'B'</span>
    <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006666;">4</span>..<span style="color:#006666;">8</span>
      <span style="color:#996600;">'C'</span>
    <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006666;">8</span>..<span style="color:#006666;">16</span>
      <span style="color:#996600;">'D'</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      <span style="color:#996600;">'F'</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>To be clear, if your object differs significantly enough from a string (as above) then you probably want to reconsider using this pattern. For quick and easily reusable formatting consistency that fits your domain model, however? The original value object, String, is hard to beat.</p>
<p>[Update] To be even clearer, this pattern is for value objects &#8212; that is, you shouldn&#8217;t be changing them. As nicholaides correctly points out in the comments below, Ruby does some voodoo to optimize certain string operations. Don&#8217;t expect your custom initializer to be called on objects instantiated as a result of things like <tt>String#gsub</tt>.</p>
]]></content:encoded>
			<wfw:commentRss>http://erniemiller.org/2012/11/01/ruby-tidbit-string-the-original-value-object/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ruby Tidbit: Super and Parameter Reassignment</title>
		<link>http://erniemiller.org/2012/10/11/ruby-tidbit-super-and-parameter-reassignment/</link>
		<comments>http://erniemiller.org/2012/10/11/ruby-tidbit-super-and-parameter-reassignment/#comments</comments>
		<pubDate>Fri, 12 Oct 2012 00:11:42 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://erniemiller.org/?p=1229</guid>
		<description><![CDATA[Something I&#8217;ve always loved about Ruby is that no matter how long I&#8217;ve been using it, it continues to surprise and delight me with neat little tricks. Here&#8217;s one I was really surprised I never knew until now: Let&#8217;s say you want to enforce some kind of parameter formatting on an inherited method. You probably [...]]]></description>
				<content:encoded><![CDATA[<p>Something I&#8217;ve always loved about Ruby is that no matter how long I&#8217;ve been using it, it continues to surprise and delight me with neat little tricks. Here&#8217;s one I was really surprised I never knew until now:</p>
<p>Let&#8217;s say you want to enforce some kind of parameter formatting on an inherited method. You probably already know that you can write something like:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> my_nifty_method<span style="color:#006600; font-weight:bold;">&#40;</span>value<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">super</span><span style="color:#006600; font-weight:bold;">&#40;</span>nifty_parameter_formatter<span style="color:#006600; font-weight:bold;">&#40;</span>value<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>But, did you know that you can also do this?</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> my_nifty_method<span style="color:#006600; font-weight:bold;">&#40;</span>value<span style="color:#006600; font-weight:bold;">&#41;</span>
  value = nifty_parameter_formatter<span style="color:#006600; font-weight:bold;">&#40;</span>value<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">super</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>I didn&#8217;t, until I just gave it a try this evening, for giggles. I figured it might work for methods that mutate an object, like <tt>Array#unshift</tt>, but since variable assignment is creating a new reference, I just assumed I&#8217;d need to explicitly pass in my modified <tt>value</tt>. Chalk me up as pleasantly surprised! Since I don&#8217;t ever remember seeing this information before, and a few quick Google searches turned up empty, I thought I&#8217;d share.</p>
<p>[Update: I've been informed this specific behavior was one of the topics covered in James Edward Gray II's (aptly named) talk, <a href="https://speakerdeck.com/u/jeg2/p/10-things-you-didnt-know-ruby-could-do">"10 Things You Didn't Know Ruby Could Do"</a>. Worth a look for some other nifty tricks!]</p>
]]></content:encoded>
			<wfw:commentRss>http://erniemiller.org/2012/10/11/ruby-tidbit-super-and-parameter-reassignment/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Making Ruby Dance!</title>
		<link>http://erniemiller.org/2012/09/23/making-ruby-dance/</link>
		<comments>http://erniemiller.org/2012/09/23/making-ruby-dance/#comments</comments>
		<pubDate>Sun, 23 Sep 2012 20:54:39 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rubyhoedown]]></category>
		<category><![CDATA[talk]]></category>

		<guid isPermaLink="false">http://erniemiller.org/?p=1223</guid>
		<description><![CDATA[I just got back from Ruby Hoedown 2012, and it was even more fun than last year. Huge thanks to Jeremy McAnally for making it happen. I gave a lightning talk again this year. This one was entitled &#8220;Making Ruby Dance!&#8221; and it was about dependency injection and stupid Ruby tricks. I had way more [...]]]></description>
				<content:encoded><![CDATA[<p>I just got back from Ruby Hoedown 2012, and it was even more fun than last year. Huge thanks to <a href="http://www.jeremymcanally.com/">Jeremy McAnally</a> for making it happen. I gave a lightning talk again this year. This one was entitled &#8220;Making Ruby Dance!&#8221;  and it was about dependency injection and stupid Ruby tricks. I had way more fun working on it than should be legal. Have I said lately just how much I love Ruby, and our community? I don&#8217;t care, I&#8217;m saying it again. We&#8217;re so ridiculously blessed to get to have this much fun doing what we do. <a href="https://twitter.com/intent/tweet?text=%22We%E2%80%99re%20so%20ridiculously%20blessed%20to%20get%20to%20have%20this%20much%20fun%20doing%20what%20we%20do.%22%20--%40erniemiller%20http%3A%2F%2Ferniemiller.org%2F2012%2F09%2F23%2Fmaking-ruby-dance%2F" rel="nofollow" target="_blank" title="Tweet This Quote">(tweet this)</a> Video and links below.<br />
<span id="more-1223"></span><br />
<iframe width="640" height="360" src="http://www.youtube.com/embed/so8-u4F6K5s" frameborder="0" allowfullscreen></iframe></p>
<p>Code: <a href="https://gist.github.com/3772859">here</a> and <a href="https://gist.github.com/3772848">here</a><br />
Slides: <a href="https://speakerdeck.com/u/erniemiller/p/making-ruby-dance">here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://erniemiller.org/2012/09/23/making-ruby-dance/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Ruby Tidbit: __LINE__ and heredocs</title>
		<link>http://erniemiller.org/2012/09/10/ruby-tidbit-__line__-and-heredocs/</link>
		<comments>http://erniemiller.org/2012/09/10/ruby-tidbit-__line__-and-heredocs/#comments</comments>
		<pubDate>Mon, 10 Sep 2012 12:00:17 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://erniemiller.org/?p=1201</guid>
		<description><![CDATA[You&#8217;re probably familiar with __LINE__ keyword in Ruby. Wherever it&#8217;s used, it refers to the line number in the current file. It says so right here in the Ruby docs. QUICK! What&#8217;s the output of the following code? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #!/usr/bin/env ruby &#160; [...]]]></description>
				<content:encoded><![CDATA[<p>You&#8217;re probably familiar with <tt>__LINE__</tt> keyword in Ruby. Wherever it&#8217;s used, it refers to the line number in the current file. It says so <a href="http://ruby-doc.org/docs/keywords/1.9/Object.html#method-i-__LINE__">right here in the Ruby docs</a>.</p>
<p><strong>QUICK!</strong> What&#8217;s the output of the following code?</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="" style="font-family:monospace;">#!/usr/bin/env ruby
&nbsp;
class LineDemo
  def self.process<span class="br0">&#40;</span>text, lineno<span class="br0">&#41;</span>
    # do important processing on text
    puts lineno
  end
end
&nbsp;
LineDemo.process &lt;&lt;TEXT, __LINE__
Here is some text on which we will do some important processing.
Here, also, is some important text to process.
TEXT
# All done!</pre></td></tr></table></div>

<p>The answer is obvious. <em>Of course</em>, it prints <strong>13</strong>.<br />
<span id="more-1201"></span></p>
<h2>Wait, what?</h2>
<p>Yes, it prints 13. Why not 10? Because Ruby does interesting things when parsing heredocs.</p>
<p>When you pass a heredoc to a method as a parameter, Ruby will, in general, stop what it&#8217;s doing, read through the file until it encounters the token that terminates the heredoc (TEXT, in our case), and then pick up where it left off.</p>
<p>Sort of.</p>
<p>You see, by passing <tt>__LINE__</tt> to our method, we asked Ruby to give us the value of <tt>ruby_sourceline</tt> (see <a href="https://github.com/ruby/ruby/blob/8ee2226068bca03aba3dade555ccce3d64e4397a/parse.y#L8523-8524">parse.y</a> in the Ruby source tree). It just so happens that this value is equal to the line that contains the token which ends the heredoc. Note that I added a comment at the end of the script &#8212; interestingly, if Ruby encounters the end of the file on the same line that terminates the heredoc, <tt>__LINE__</tt> returns 10, as you might have expected, and of course if the heredoc came after the <tt>__LINE__</tt> keyword, then the line number wouldn&#8217;t be incorrect, either. This only occurs if the heredoc comes <em>before</em> <tt>__LINE__</tt>.</p>
<p>However, that problematic ordering of parameters is necessary in a very common use case for <tt>__LINE__</tt>, namely, evals, such as <tt><a href="http://www.ruby-doc.org/core-1.9.3/BasicObject.html#method-i-instance_eval">instance_eval</a></tt>:</p>
<blockquote><p>
<strong>instance_eval(string [, filename [, lineno]] ) → obj</strong><br />
<strong>instance_eval {| | block } → obj</strong><br />
Evaluates a string containing Ruby source code, or the given block, within the context of the receiver (obj). In order to set the context, the variable self is set to obj while the code is executing, giving the code access to obj’s instance variables. In the version of instance_eval that takes a String, the optional second and third parameters supply a filename and starting line number that are used when reporting compilation errors.
</p></blockquote>
<p>What&#8217;s a Rubyist to do? Trick Ruby&#8217;s parser into evaluating <tt>__LINE__</tt> before things get all wacky-like. It just so happens that doing some math against <tt>__LINE__</tt> will do so, since the computation will need to take place before the method is dispatched. This is why you will commonly see code like this in Rails:</p>
<p><strong>activemodel/lib/active_model/callbacks.rb</strong>:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="" style="font-family:monospace;">def _define_before_model_callback<span class="br0">&#40;</span>klass, callback<span class="br0">&#41;</span> #:nodoc:
  klass.class_eval &lt;&lt;-CALLBACK, __FILE__, __LINE__ + <span style="">1</span>
    def self.before_#<span class="br0">&#123;</span>callback<span class="br0">&#125;</span><span class="br0">&#40;</span>*args, &amp;block<span class="br0">&#41;</span>
      set_callback<span class="br0">&#40;</span>:#<span class="br0">&#123;</span>callback<span class="br0">&#125;</span>, :before, *args, &amp;block<span class="br0">&#41;</span>
    end
  CALLBACK
end</pre></td></tr></table></div>

<p>The operation forces the line number to be computed first, and the <tt>+ 1</tt> tells <tt>class_eval</tt> that while evaluating, line numbering starts at the line just below the method call, which is the first line of heredoc code. You could call any method against <tt>__LINE__</tt>, such as <tt>__LINE__.to_i</tt>, and get the first behavior. It just so happens that in the typical <tt>eval</tt> use case, we&#8217;ll want the addition anyway, so that&#8217;s what we&#8217;ll normally use.</p>
<h2>Tying it all together</h2>
<p>To summarize: here&#8217;s an example script that demonstrates the different behaviors.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
</pre></td><td class="code"><pre class="" style="font-family:monospace;">#!/usr/bin/env ruby
&nbsp;
class LineNumber
  def self.before lineno, param
    puts &quot;line number is #<span class="br0">&#123;</span>lineno<span class="br0">&#125;</span>&quot;
  end
&nbsp;
  def self.after param, lineno
    puts &quot;line number is #<span class="br0">&#123;</span>lineno<span class="br0">&#125;</span>&quot;
  end
end
&nbsp;
print &quot;before with __LINE__: &quot;
LineNumber.before __LINE__, &lt;&lt;TEXT
This is some text.
As is this.
This, also, is some text.
TEXT
&nbsp;
print &quot;after with __LINE__: &quot;
LineNumber.after &lt;&lt;TEXT, __LINE__
This is some text.
As is this.
This, also, is some text.
TEXT
&nbsp;
print &quot;after with __LINE__ + <span style="">0</span>: &quot;
LineNumber.after &lt;&lt;TEXT, __LINE__ + <span style="">0</span>
This is some text.
As is this.
This, also, is some text.
TEXT
# fin</pre></td></tr></table></div>

<p>The output of this script:</p>
<pre>
before with __LINE__: line number is 14
after with __LINE__: line number is 25
after with __LINE__ + 0: line number is 28
</pre>
<p>That concludes this look at an interesting and odd little corner of Ruby. Now, the next time you tack on &#8220;+ 1&#8243; to an eval&#8217;s __LINE__ parameter, you&#8217;ll know exactly why you&#8217;re doing so.</p>
]]></content:encoded>
			<wfw:commentRss>http://erniemiller.org/2012/09/10/ruby-tidbit-__line__-and-heredocs/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Squeel 1.0.11, 1.1, and the Future</title>
		<link>http://erniemiller.org/2012/09/03/squeel-1-0-11-1-1-and-the-future/</link>
		<comments>http://erniemiller.org/2012/09/03/squeel-1-0-11-1-1-and-the-future/#comments</comments>
		<pubDate>Mon, 03 Sep 2012 20:03:41 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[squeel]]></category>

		<guid isPermaLink="false">http://erniemiller.org/?p=1195</guid>
		<description><![CDATA[Over the weekend, I released Squeel 1.0.10 (and then yanked it and released 1.0.11, because I fail at semantic versioning, putting a deprecation into a patch release). It&#8217;s been a while since I made a post about a Squeel release, so I thought maybe it was time for an update on what&#8217;s new, as well [...]]]></description>
				<content:encoded><![CDATA[<p>Over the weekend, I released Squeel 1.0.10 (and then yanked it and released 1.0.11, because I fail at semantic versioning, putting a deprecation into a patch release). It&#8217;s been a while since I made a post about a Squeel release, so I thought maybe it was time for an update on what&#8217;s new, as well as what you can expect in Squeel 1.1/2.0.<br />
<span id="more-1195"></span></p>
<h2>1.0.3 &#8211; 1.0.9, summarized</h2>
<p>Bug fixes. That&#8217;s been just about it, really. Many of them are related to an ongoing battle I&#8217;ve had with <tt>ActiveRecord::Relation#merge</tt>. Oh man, how I hate that method. I&#8217;ve had a draft queued up for a while about that, actually. I&#8217;ll get around to polishing it up one day.</p>
<p>Anyway, I believe I&#8217;ve currently arrived at <a href="https://github.com/ernie/squeel/commit/81e3577ced8cca93c31682aba427b79b5baddb09">a solution</a> that&#8217;s working as well as can be hoped for. With that out of the way, what else is new?</p>
<h2>1.0.11</h2>
<p>Here&#8217;s what&#8217;s new as of 1.0.11:</p>
<ul>
<li>Resolve issues when joining the same table twice in two different scopes (<a href="https://github.com/ernie/squeel/issues/157">#157</a>)</li>
<li>Allow predicates in order and select clauses. (<a href="https://github.com/ernie/squeel/issues/128">#128</a>)</li>
<li>Support Squeel syntax in <tt>Relation#from</tt> (<a href="https://github.com/ernie/squeel/issues/155">#155</a>)</li>
</ul>
<p>There&#8217;s a bit of behind the scenes work that&#8217;s been done to support some of these changes, that should allow for easier support of one-off behavior in specific clauses in the future. Namely, <a href="https://github.com/ernie/squeel/commit/67022403441b7e8faddccbcee719932f2d4d2bb5">each clause now has its own Visitor class</a>. This was really an oversight in the way I modeled things initially. I made a naive assumption that there wer clauses that would contain predicates, and clauses that would contain attributes (or attribute-likes), with no overlap. That&#8217;s just not the case. As a side effect of this work, I finally had the impetus I needed to clean house in the visitors, and removed a bunch of duplicated code. The result is a cleaner and easier to understand codebase.</p>
<h2>What&#8217;s in store for the future?</h2>
<p>Squeel 2.0 will have some changes in store. Here are a couple, with more to come later.</p>
<ol>
<li>Sifters will better coexist with scopes. Currently, I&#8217;m planning to have a sifter definition create a scope of the same name (either automatically or with an option, undecided as of yet). The sifter will be prefixed with &#8220;sift_&#8221; in its method name, and the <tt>sift</tt> syntax within the DSL will take this into account when referencing sifters.In current versions of Squeel, a sifter and a scope with the same name cannot coexist.</li>
<li>Core extensions will be removed. The symbol and hash extensions in Squeel 1.0 were provided as a convenience for those migrating from MetaWhere. A quick check of <a href="https://rubygems.org/profiles/43966">RubyGems.org</a> shows that Squeel has surpassed MetaWhere in current usage, which means that the time is right to remove support for this stopgap measure. As of 1.1.0, loading these extensions will trigger a <a href="https://github.com/ernie/squeel/commit/df12f2e36d56b1faa73f1ef275712f481b23be0c">deprecation notice</a>.</li>
</ol>
<p>As both of the changes outlined above will result in modifications to the public-facing API of Squeel, they&#8217;ll only happen in version 2.0. You can safely continue to use Squeel 1.x without being concerned about a backport of these changes causing breakage.</p>
]]></content:encoded>
			<wfw:commentRss>http://erniemiller.org/2012/09/03/squeel-1-0-11-1-1-and-the-future/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Toward a More Egalitarian ObjectSpace</title>
		<link>http://erniemiller.org/2012/08/21/toward-a-more-egalitarian-objectspace/</link>
		<comments>http://erniemiller.org/2012/08/21/toward-a-more-egalitarian-objectspace/#comments</comments>
		<pubDate>Tue, 21 Aug 2012 18:52:56 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[equivalence]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://erniemiller.org/?p=1160</guid>
		<description><![CDATA[Egalitarianism (from French égal, meaning &#8220;equal&#8221;) is a trend of thought that favors equality among living entities. &#8211;Wikipedia So, I may have taken a bit of poetic licence with this post&#8217;s title. A completely egalitarian ObjectSpace would be insane. We don&#8217;t want all of our objects to be equal, but we do generally want the [...]]]></description>
				<content:encoded><![CDATA[<blockquote><p><strong>Egalitarianism</strong> (from French égal, meaning &#8220;equal&#8221;) is a trend of thought that favors equality among living entities.<br />
<cite>&#8211;<a href="http://en.wikipedia.org/wiki/Egalitarianism">Wikipedia</a></cite></p></blockquote>
<p>So, I may have taken a bit of poetic licence with this post&#8217;s title. A completely egalitarian ObjectSpace would be insane. We don&#8217;t want all of our objects to be equal, but we do generally want the ability to recognize when two objects are equal. Today, I&#8217;d like to share a story about an ActiveRecord refactoring I worked on over the weekend, and how it relates to the topic.</p>
<p><span id="more-1160"></span></p>
<h2>Relation merges and equality conditions</h2>
<p>When you merge two ActiveRecord::Relation objects, ActiveRecord makes a few decisions on your behalf. One of them involves what to do if both relations have equality conditions against the same attribute. When you pass a hash of column/value pairs to Relation#where, ActiveRecord&#8217;s PredicateBuilder creates ARel Equality nodes (or In nodes, in the case of an array or range value). Here&#8217;s an example (altered for legibility/brevity):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;">relation = Person.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Bob'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">where_values</span>
<span style="color:#008000; font-style:italic;"># =&gt; [</span>
<span style="color:#008000; font-style:italic;">#      #&lt;Arel::Nodes::Equality:0x1075fbfb0</span>
<span style="color:#008000; font-style:italic;">#      @left=#&lt;struct Arel::Attributes::String relation=#&lt;Arel::Table (...)&gt;,</span>
<span style="color:#008000; font-style:italic;">#      @right=&quot;Bob&quot;, (...)</span>
<span style="color:#008000; font-style:italic;">#    ]</span></pre></td></tr></table></div>

<p>When you merge two relations, ActiveRecord normally just appends the <tt>where_values</tt> of the second relation to those of the first relation, which results in all of the conditions being joined by <tt>AND</tt> in the resulting SQL. But what happens if we next write:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;">relation = relation.<span style="color:#9900CC;">merge</span><span style="color:#006600; font-weight:bold;">&#40;</span>Person.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Jim'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></td></tr></table></div>

<p>Well, generating a query that selects all people whose name is Bob <em>and</em> whose name is Jim makes no sense, since both conditions can&#8217;t be true. As you probably already know, ActiveRecord uses the last equality node. In this case, that means we get all people whose name is Jim.</p>
<p>Here&#8217;s the code, straight from ActiveRecord that made this work:</p>
<p><strong>lib/active_record/relation/merger.rb (from <a href="https://github.com/rails/rails/blob/8f58d6e5074a623bed752d5ba38513305f03fae9/activerecord/lib/active_record/relation/merger.rb">8f58d6e5</a> in master):</strong></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">unless</span> relation.<span style="color:#9900CC;">where_values</span>.<span style="color:#9900CC;">empty</span>?
  <span style="color:#008000; font-style:italic;"># Remove duplicates, last one wins.</span>
  seen = <span style="color:#CC00FF; font-weight:bold;">Hash</span>.<span style="color:#9900CC;">new</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>h,table<span style="color:#006600; font-weight:bold;">|</span> h<span style="color:#006600; font-weight:bold;">&#91;</span>table<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
  merged_wheres = merged_wheres.<span style="color:#9900CC;">reverse</span>.<span style="color:#9900CC;">reject</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>w<span style="color:#006600; font-weight:bold;">|</span>
    nuke = <span style="color:#0000FF; font-weight:bold;">false</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> w.<span style="color:#9900CC;">respond_to</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:operator</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> w.<span style="color:#9900CC;">operator</span> == :==
      name              = w.<span style="color:#9900CC;">left</span>.<span style="color:#9900CC;">name</span>
      table             = w.<span style="color:#9900CC;">left</span>.<span style="color:#9900CC;">relation</span>.<span style="color:#9900CC;">name</span>
      nuke              = seen<span style="color:#006600; font-weight:bold;">&#91;</span>table<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span>name<span style="color:#006600; font-weight:bold;">&#93;</span>
      seen<span style="color:#006600; font-weight:bold;">&#91;</span>table<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span>name<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF; font-weight:bold;">true</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    nuke
  <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">reverse</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>This code reverses the order of the combined <tt>where_values</tt>, and if any of the objects quack like an Equality node, it notes the ARel Attribute on the left hand side has been seen, so it can discard any later Equality nodes. When the array is again reversed, this has the effect of keeping only the last occurrence of each Equality condition against a specific attribute.</p>
<h2>Problem?<img src="/wp-content/uploads/2012/08/trollface-small.png" width="50" height="46" /></h2>
<p>Yes, there&#8217;s a problem here. It makes sense to only do this for Equality nodes, but what happens if the left hand side of the Equality node isn&#8217;t an attribute? What if it&#8217;s a function, instead? <a href="https://github.com/ernie/squeel/issues/156">This happens</a>:</p>
<blockquote><p>undefined method `relation&#8217; for #&lt;Arel::Nodes::NamedFunction&gt;</p></blockquote>
<p>This is because once we&#8217;ve detected an Equality node, we make an assumption that the left hand of that node is an ARel Attribute. That&#8217;s unfortunate, as it&#8217;s unnecessarily limiting. As a quick fix, we can tweak things like so, to prevent an exception being raised:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># We might have non-attributes on the left side of equality nodes,</span>
<span style="color:#008000; font-style:italic;"># so we need to make sure they quack like an attribute.</span>
<span style="color:#9966CC; font-weight:bold;">if</span> w.<span style="color:#9900CC;">respond_to</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:operator</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> w.<span style="color:#9900CC;">operator</span> == :== <span style="color:#006600; font-weight:bold;">&amp;&amp;</span>
  w.<span style="color:#9900CC;">left</span>.<span style="color:#9900CC;">respond_to</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:relation</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  name              = w.<span style="color:#9900CC;">left</span>.<span style="color:#9900CC;">name</span>
  table             = w.<span style="color:#9900CC;">left</span>.<span style="color:#9900CC;">relation</span>.<span style="color:#9900CC;">name</span>
  nuke              = seen<span style="color:#006600; font-weight:bold;">&#91;</span>table<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span>name<span style="color:#006600; font-weight:bold;">&#93;</span>
  seen<span style="color:#006600; font-weight:bold;">&#91;</span>table<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span>name<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF; font-weight:bold;">true</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>But, as you can probably imagine, that&#8217;s only a partial fix. Now, we&#8217;ll ignore that Equality node altogether, meaning that we could end up with two conflicting equality conditions against identical functions. Far from ideal.</p>
<h2>Refactoring for fun and profit</h2>
<p>So, it&#8217;d be really great if we could just satisfy the obvious intent of the code in a more straightforward manner: <em>Given an array of <tt>where</tt> conditions, we want to keep only the last equality condition for each left-hand value.</em> Wouldn&#8217;t it be nice if we didn&#8217;t need to know anything at all about what that left-hand object was, and could just write:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># Remove equalities with duplicated left-hand. Last one wins.</span>
seen = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
merged_wheres = merged_wheres.<span style="color:#9900CC;">reverse</span>.<span style="color:#9900CC;">reject</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>w<span style="color:#006600; font-weight:bold;">|</span>
  nuke = <span style="color:#0000FF; font-weight:bold;">false</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> w.<span style="color:#9900CC;">respond_to</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:operator</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> w.<span style="color:#9900CC;">operator</span> == :==
    nuke         = seen<span style="color:#006600; font-weight:bold;">&#91;</span>w.<span style="color:#9900CC;">left</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    seen<span style="color:#006600; font-weight:bold;">&#91;</span>w.<span style="color:#9900CC;">left</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF; font-weight:bold;">true</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  nuke
<span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">reverse</span></pre></td></tr></table></div>

<p>Good news: We can! But first, we have to do some work. :(</p>
<h2>What constitutes equality?</h2>
<p>The answer to that question depends on who&#8217;s asking. And, for that matter, how they ask it. Oh, and also, what your object considers an equal.</p>
<p>The default Ruby implementation of object equality is extremely narrow. To demonstrate:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> MyNiftyObject <span style="color:#008000; font-style:italic;"># &lt; Object is implied</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>value<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@value</span> = value
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
MyNiftyObject.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'hi'</span><span style="color:#006600; font-weight:bold;">&#41;</span> == MyNiftyObject.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'hi'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;"># =&gt; false</span></pre></td></tr></table></div>

<p>What? This is because the Object class has one concept of equality: two Objects are equal if and only if they refer to the exact same instance in memory. We created two instances of MyNiftyObject, and just because they happen to have the same values doesn&#8217;t mean they&#8217;re &#8220;equal&#8221; to Ruby.</p>
<p>Think about it: how else could you really compare two instances of the Object class, which has no attributes? Ruby leaves it up to the subclasses of Object to implement the various equality checks in ways that make sense for them, but it provides some <a href="http://ruby-doc.org/core-1.9.3/Object.html#method-i-eql-3F">guidelines</a>. Here&#8217;s a quick rundown, by decreasing strictness:</p>
<ul>
<li><strong>equal?</strong> &#8211; Shouldn&#8217;t be overridden. Returns <tt>true</tt> if both objects are literally the same object (the same in-memory instance)</li>
<li><strong>eql?</strong> &#8211; Should return true if both objects have the same value. This is normally synonymous with <tt>==</tt>, but there can be subtle differences. Could be more accurately described by saying &#8220;objects have equal values, and are also the same class&#8221;. For instance, Numerics like Float and Fixnum return false when compared with <tt>1.eql?(1.0)</tt></li>
<li><strong>==</strong> &#8211; Should return true if the objects have the same values. Again, except in certain odd cases, synonymous with <tt>eql?</tt></li>
<li><strong>===?</strong> &#8211; More commonly referred to as &#8220;case equality&#8221;. Normally the same as <tt>==</tt> but often overridden to provide useful behavior in case statements (each <tt>when</tt> value will call its <tt>===</tt> method to compare with the value being checked). For instance, <tt>Class#===(object)</tt> behaves like <tt>object.is_a?(Class)</tt>. Note that other methods, like <tt>Enumerable#grep</tt> may call this as well.</li>
</ul>
<p>So, with these considerations in mind, your first instinct might reasonably be to try defining the <tt>==(other)</tt> method on your objects. <strong>HAH!</strong> Your first instinct would be <strong>WRONG</strong>! But, for giggles, let&#8217;s try it.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> MyNiftyObject <span style="color:#008000; font-style:italic;"># &lt; Object is implied</span>
  attr_reader <span style="color:#ff3333; font-weight:bold;">:value</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>value<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@value</span> = value
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> ==<span style="color:#006600; font-weight:bold;">&#40;</span>other<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9966CC; font-weight:bold;">class</span> == other.<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> <span style="color:#008000; font-style:italic;"># Not just any object with a &quot;value&quot; attr</span>
      <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">value</span> == other.<span style="color:#9900CC;">value</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
MyNiftyObject.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'hi'</span><span style="color:#006600; font-weight:bold;">&#41;</span> == MyNiftyObject.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'hi'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;"># =&gt; true</span></pre></td></tr></table></div>

<p>&#8220;I thought you said my instinct was wrong, Mr. Smarty Q. Pantsington, III,&#8221; I hear you saying. Not so fast! Remember, we wanted to implement object equality in a way that would work with our &#8220;seen&#8221; hash, in ActiveRecord. Let&#8217;s try it.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;">hi1 = MyNiftyObject.<span style="color:#9900CC;">new</span> <span style="color:#996600;">'hi'</span>
hi2 = MyNiftyObject.<span style="color:#9900CC;">new</span> <span style="color:#996600;">'hi'</span>
hi1 == hi2 <span style="color:#008000; font-style:italic;"># =&gt; true</span>
hi_hash = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
hi_hash<span style="color:#006600; font-weight:bold;">&#91;</span>hi1<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;hello, good sir&quot;</span>
hi_hash<span style="color:#006600; font-weight:bold;">&#91;</span>hi2<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;i hope this missive finds you well&quot;</span>
hi_hash.<span style="color:#9900CC;">size</span>   <span style="color:#008000; font-style:italic;"># =&gt; 2</span>
hi_hash.<span style="color:#9900CC;">values</span> <span style="color:#008000; font-style:italic;"># =&gt; [&quot;hello, good sir&quot;, &quot;i hope this missive finds you well&quot;]</span></pre></td></tr></table></div>

<p>Well, that sucked.</p>
<h2>The oddly-yet-aptly-named Object#hash</h2>
<p>Why didn&#8217;t it work? Because there&#8217;s another Object method we need to implement, <tt>Object#hash</tt>. What&#8217;s that do? Let&#8217;s <a href="http://ruby-doc.org/core-1.9.3/Object.html#method-i-hash">consult the docs</a>:</p>
<blockquote><p>
Generates a Fixnum hash value for this object. This function must have the property that a.eql?(b) implies a.hash == b.hash. The hash value is used by class Hash. Any hash value that exceeds the capacity of a Fixnum will be truncated before being used.
</p></blockquote>
<p>The first time I read this in the docs, I&#8217;ll admit that I still had no idea what the method needed to do, or how, exactly, the Hash class used this method. In English, here&#8217;s how this all fits together:</p>
<p>The <tt>hash</tt> method is sort of an optimization trick used by Ruby. Certain Ruby classes (Hash and Array, notably) make use of a hash table (see <a href="https://github.com/ruby/ruby/blob/v1_9_3_195/st.c">st.c</a> in the Ruby source) which &#8220;bins&#8221; data based on the Fixnums returned by their <tt>hash</tt> methods. As more values are stored in the hash, the number of bins can be increased. Since it&#8217;s super-efficient to look up entries in this table, it can be used to quickly determine whether there&#8217;s a <em>chance</em> the object might exist, and roughly where to find it, before bothering to actually retrieve or set it.</p>
<p>Using this trick, a <tt>Hash</tt> knows very quickly whether it can just stow your data in the given key, because there&#8217;s no chance of needing to overwrite an existing object, or whether it needs to do a bit more legwork. Likewise, an Array knows whether it might need to remove an object when you call <tt>uniq</tt>. There&#8217;s a bit more to it than that, but this post is already too long, so let&#8217;s skip to the chase, shall we? The short version is that unless your hash method returns the same value as another object&#8217;s hash method, Ruby won&#8217;t even bother calling your object&#8217;s <tt>eql?</tt> method, which is why our little experiment failed.</p>
<h2>Implementing a custom hash method</h2>
<p>How should we write a custom hash method? If you only have one instance variable in your class, it&#8217;s easy. Just have your hash method call its hash method, and you&#8217;ll be set. If you have more than one, there are a couple of ways to do it. The general idea is that whatever method you choose should return a Fixnum, and not a Bignum, so it&#8217;s probably not best to just add all of your instance variables&#8217; hashes together. That being said, Ruby is kind enough to <a href="https://github.com/ruby/ruby/blob/trunk/hash.c#L68-69">truncate the value for you</a> if you violate this &#8220;rule&#8221;, or even <a href="https://github.com/ruby/ruby/blob/trunk/hash.c#L71-73">coerce your returned value to a Fixnum </a> if you return something really crazy (as long as whatever you return implements <tt>to_int</tt>).</p>
<p>My personal favorite way to handle hashing an object with multiple instance variables is to let <tt>Array</tt> do the work for me:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> hash
  <span style="color:#006600; font-weight:bold;">&#91;</span>@var1, <span style="color:#0066ff; font-weight:bold;">@var2</span>, <span style="color:#0066ff; font-weight:bold;">@var3</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">hash</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<h2>Back to the problem at hand</h2>
<p>Remember our friend <tt>ActiveRecord::Relation#merge</tt>? If we want to use objects as keys in that &#8220;seen&#8221; hash, we have some work to do.</p>
<p>At a minimum, we need to implement the <tt>hash</tt> and <tt>eql?</tt> methods on any objects we think might end up on the left side of the Equality nodes. But taking it one step further, it&#8217;s always a good idea to implement the <tt>==</tt> method, as well. Thankfully, that&#8217;s as easy an aliasing it to <tt>eql?</tt>.</p>
<p>For a moment, pretending our little sample class above was going to be in the left-hand of an equality node, this is our minimal implementation:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> MyNiftyObject
  attr_reader <span style="color:#ff3333; font-weight:bold;">:value</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>value<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@value</span> = value
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> hash
    <span style="color:#0066ff; font-weight:bold;">@value</span>.<span style="color:#9900CC;">hash</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> eql?<span style="color:#006600; font-weight:bold;">&#40;</span>other<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9966CC; font-weight:bold;">class</span> == other.<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">&amp;&amp;</span>
      <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">value</span> == other.<span style="color:#9900CC;">value</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">alias</span> :== <span style="color:#ff3333; font-weight:bold;">:eql</span>?
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>With ARel, it&#8217;s a bit trickier, because most nodes have more than one instance variable (in some cases many more), and even Arel::Attributes::Attribute, which inherits from a Struct (which already has a sane default implementation of the methods shown above), contains an Arel::Table, which itself must implement equality tests, and so on&#8230; Equality all the way down.</p>
<p>What&#8217;s that end up looking like? <a href="https://github.com/rails/arel/commit/6e638bba594b6164190d2a6fb96ffa07a20b11f3">A whole lot of typing.</a> But in the end, <a href="https://github.com/rails/rails/commit/bf80522be4d7ac521fa3c30d889afa68450a0bc2">we get what we wanted</a>!</p>
<h2>Great. So when should I actually go through this hassle?</h2>
<p>It really depends. Do you have complete control over how your objects are used? Then it&#8217;s probably up to you. If you&#8217;re writing code intended for reuse (and aren&#8217;t you always?) then you should consider whether it might be the case that a user of your class (even the future you) might want to compare instances for equality, or use <tt>Array#uniq</tt> on an array containing your objects, or&#8230; My personal rule is this: <strong>If you&#8217;re wondering whether you should write equality methods for your class, you probably should.</strong></p>
<p>As for the hassle? Well, it&#8217;s really not much hassle at all, in most cases. But after typing all that code for ARel, I decided to make it easier, anyway.</p>
<h2>Equivalence</h2>
<p><a href="https://github.com/ernie/equivalence">Equivalence</a> is a tiny gem that implements the equality code discussed in this post via a macro. Check the <a href="https://github.com/ernie/equivalence#readme">README</a> for more info. It&#8217;s easy enough for the most common use cases that you have no excuse, now.</p>
<p>Go forth, and write egalitarian code!</p>
]]></content:encoded>
			<wfw:commentRss>http://erniemiller.org/2012/08/21/toward-a-more-egalitarian-objectspace/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Greenfield App Continuum</title>
		<link>http://erniemiller.org/2012/08/15/the-greenfield-app-continuum/</link>
		<comments>http://erniemiller.org/2012/08/15/the-greenfield-app-continuum/#comments</comments>
		<pubDate>Wed, 15 Aug 2012 18:01:25 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[philosophy]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://erniemiller.org/?p=1138</guid>
		<description><![CDATA[My last post, Persistence is a Solved Problem, got some mixed responses. This post is a bit overdue, as Jeff Iacono asked me to elaborate on the previous post almost a month ago: @jeffreyiacono I&#8217;ll see what I can do. It&#8217;ll probably end up being a separate post if/when I get the time to write [...]]]></description>
				<content:encoded><![CDATA[<p>My last post, <a href="http://erniemiller.org/2012/07/17/persistence-is-a-solved-problem/" title="Persistence is a Solved Problem">Persistence is a Solved Problem</a>, got some mixed responses. This post is a bit overdue, as Jeff Iacono asked me to elaborate on the previous post almost a month ago:</p>
<blockquote class="twitter-tweet" data-in-reply-to="225446349401890816"><p><a href="https://twitter.com/jeffreyiacono"><s>@</s><b>jeffreyiacono</b></a> I&#8217;ll see what I can do. It&#8217;ll probably end up being a separate post if/when I get the time to write it :)</p>
<p>&mdash; Ernie Miller (@erniemiller) <a href="https://twitter.com/erniemiller/status/225950063229272064" data-datetime="2012-07-19T13:47:47+00:00">July 19, 2012</a></p></blockquote>
<p><script src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p>Anyway, better late than never, right? Here goes. Bear with me, this post is going to be heavy on philosophy and light on code.<br />
<span id="more-1138"></span></p>
<h2>Confession</h2>
<p>The previous post&#8217;s title was more than a little hyperbolic. With that out of the way&#8230;</p>
<h2>Why is &#8220;Persistence is a Solved Problem&#8221; a useful viewpoint to hold?</h2>
<p>Imagine that you&#8217;re writing a new, non-trivial application. You haven&#8217;t written a line of code, yet. You&#8217;re just thinking through how the application might be structured, essentially modeling the domain of the application in your head. When an application is in this stage, you start out with tremendous flexibility in how you can choose to think about the problem you&#8217;re addressing.</p>
<p>Now, your thought process is going to fall somewhere on a continuum between &#8220;mental database schema&#8221; and &#8220;there is no spoon.&#8221;</p>
<div id="attachment_1142" class="wp-caption aligncenter" style="width: 710px"><a href="http://erniemiller.org/wp-content/uploads/2012/08/continuum.png"><img src="http://erniemiller.org/wp-content/uploads/2012/08/continuum.png" alt="" title="Greenfield App Continuum" width="700" height="134" class="size-full wp-image-1142" /></a><p class="wp-caption-text">The &#8220;Greenfield App Continuum&#8221;.</p></div>
<p>I&#8217;ve found that my tendencies naturally lie toward the blue-shaded area of this continuum. The result is that I voluntarily and artificially constrain my thought process to the concepts easily described in terms of my chosen persistence layer. This, of course, means that I&#8217;m already deciding on implementation details (which persistence layer will I use as scaffolding for my thought process) before I&#8217;ve written a line of code, which narrows my thinking considerably.</p>
<p>Based on my review of many applications, especially Rails applications, I don&#8217;t believe I&#8217;m alone in this tendency. My taking the (admittedly extreme) view that persistence is a solved problem is an attempt to push that decision forward to some future point, removing friction while thinking about how best to model the domain.</p>
<h2>Why do we (as Rails developers) gravitate toward the &#8220;mental database schema&#8221; way of thought?</h2>
<p>First, because the RDBMS and its associated concepts have been so thoroughly ingrained in us. They&#8217;re like a trusty hammer. Until recent history, in fact, if I sat a group of developers down in a room, we&#8217;d possibly end up in a debate about <em>which</em> RDBMS we should use for the new application, but certainly not <em>if</em> we&#8217;d use one.</p>
<p>Second, because of the Active Record pattern (particularly ActiveRecord, as implemented in Rails), which presents a ridiculously low barrier to entry. I love ActiveRecord for lots of reasons, and a large portion of <a href="https://github.com/ernie/">my open source work</a> relates to ActiveRecord. It makes basic CRUD operations almost effortless. But let&#8217;s remember that the Active Record pattern existed before Rails was a sparkle in DHH&#8217;s eye, and <a href="http://martinfowler.com/">Martin Fowler</a>, who named the pattern, had this to say, in 2002, in <a href="http://www.amazon.com/gp/product/0321127420/ref=as_li_ss_tl?ie=UTF8&#038;camp=1789&#038;creative=390957&#038;creativeASIN=0321127420&#038;linkCode=as2&#038;tag=metautonomous-20">Patterns of Enterprise Application Architecture</a><img src="http://www.assoc-amazon.com/e/ir?t=metautonomous-20&#038;l=as2&#038;o=1&#038;a=0321127420" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> (emphasis mine):</p>
<blockquote><p><strong>Active Record is a good choice for domain logic that isn&#8217;t too complex, such as creates, reads, updates, and deletes.</strong> Derivations and validations <strong>based on a single record</strong> work well in this structure.<br />
[...]<br />
<strong>Their primary problem is that they work well only if the Active Record objects correspond directly to the database tables: an isomorphic schema.</strong><br />
[...]<br />
Another argument against Active Record is the fact that <strong>it couples the object design to the database design.</strong> This makes it more difficult to refactor either design as the project goes forward.
</p></blockquote>
<p>(Incidentally, Martin recommends the Data Mapper pattern as an alternative that addresses these concerns. Thankfully, we have <a href="http://solnic.eu/2012/01/10/ruby-datamapper-status.html">a partial</a> &#8212; thanks for the correction, <a href="http://twitter.com/lsegal">@lsegal</a> &#8212; <a href="http://datamapper.org">implementation of this pattern</a> in the Ruby world, too.)</p>
<p>So, the Active Record pattern excels for simple domain logic such as CRUD operations. It should come as no surprise, then, that following this particular well-worn path as we think about modeling our non-trivial application&#8217;s domain may well end with us looking up to see a dark forest surrounds us, and the path has all but disappeared.</p>
<p>This happens because we allow our persistence model to drive our domain model. The consequences to the resulting code will be that our system is harder to maintain. </p>
<h2>Achieving freedom through ignorance</h2>
<p>What I&#8217;ve come to believe is that this problem, allowing our persistence model to drive our domain model, doesn&#8217;t manifest itself only in our tightly-coupled code. It infects our thought process.</p>
<p>If you&#8217;ve built at least a few web applications, consider this: what is the most significant challenge you typically face when reasoning about a new application? With exceptions for applications requiring massive scalability on day one (hint: your application doesn&#8217;t), I&#8217;m going to guess that &#8220;how to read and write all those ones and zeroes&#8221; wasn&#8217;t your answer. It&#8217;s probably not even in your top three, if you really think about it. Sure, <em>when</em> to persist your data, or <em>where</em> to persist it, or <em>what</em> to do once it&#8217;s persisted (or read). But not <em>how</em>.</p>
<p>Maybe this seems like an oversimplification.</p>
<p>Have you ever inherited responsibility for a large application? Was the application a joy to maintain, or a nightmarish mudball of code with files you were frightened to even open, much less modify?</p>
<p>I&#8217;ve seen my fair share of both kinds of applications, and I&#8217;ve come to the conclusion that <strong>the most difficult part of reasoning about a new system is, in fact, figuring out how to model a system that is easy to reason about.</strong></p>
<p>If success is achieved in this area, other questions will almost seem to answer themselves. Here are a few:</p>
<ul>
<li>What should this internal API look like?</li>
<li>What tests should I write?</li>
<li>How would I extend this object&#8217;s behavior?</li>
</ul>
<p>Of course, now that we&#8217;ve decided the ideal way in which we&#8217;d like to interact with our objects, there&#8217;s one more big question that we can begin to make an informed decision about:</p>
<ul>
<li><strong>What is the most effective way to implement object persistence, while best enabling our ideal method of reasoning about the problem domain?</strong></li>
</ul>
<p>At this point, it is always possible that we might find ourselves without a &#8220;perfect&#8221; solution to our persistence problem, and we are free to make some concessions in our domain model for the sake of performance or pragmatism. But now, we find ourselves at a vantage point from which we recognize the sacrifices we are making. More importantly, because our application will be easier to reason about, we&#8217;re in a stronger position to recover the ground lost by those concessions when a better option presents itself.</p>
<p>Jeff (and anyone else who&#8217;s still reading), I hope this better explains where I was coming from in the previous post.</p>
<h2>Further reading:</h2>
<ul>
<li><a href="http://solnic.eu/2011/08/01/making-activerecord-models-thin.html">Making ActiveRecord Models Thin</a></li>
<li><a href="http://objectsonrails.com/">Objects on Rails</a></li>
<li><a href="http://ohthatjames.github.com/2012/06/17/rails-without-rails/">Building a Rails App Without Rails</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://erniemiller.org/2012/08/15/the-greenfield-app-continuum/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Persistence is a Solved Problem</title>
		<link>http://erniemiller.org/2012/07/17/persistence-is-a-solved-problem/</link>
		<comments>http://erniemiller.org/2012/07/17/persistence-is-a-solved-problem/#comments</comments>
		<pubDate>Wed, 18 Jul 2012 01:30:58 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>

		<guid isPermaLink="false">http://erniemiller.org/?p=1135</guid>
		<description><![CDATA[Confession: as someone who came from a procedural and very much &#8220;roll your own persistence code&#8221; background, I still sometimes find myself thinking a bit too much about persistence when I&#8217;m writing Rails code. There are plenty of articles out there telling you that separating persistence from your domain model is the One True Way, [...]]]></description>
				<content:encoded><![CDATA[<p>Confession: as someone who came from a procedural and very much &#8220;roll your own persistence code&#8221; background, I still sometimes find myself thinking a bit too much about persistence when I&#8217;m writing Rails code. There are plenty of articles out there telling you that separating persistence from your domain model is the One True Way, and plenty that say it&#8217;s overcomplicating matters for simple problems. It&#8217;s just so easy to <tt>rails g model Blah name:string [...]</tt> and start slinging code in that model file.</p>
<p>True, it is easy. But, you know what? Persistence is a solved problem. Granted, solved in any one of about a hundred different ways, depending on what you&#8217;re up to, but solved.</p>
<p>Recently, I&#8217;ve been finding it incredibly <em>freeing</em> to model a domain as if persistence didn&#8217;t matter. That&#8217;s right. Ignore its very existence. Put it out of my mind, completely. It helps me think more clearly about the problem I&#8217;m really trying to solve. Once that part&#8217;s figured out, I&#8217;m in a better position to make a reasoned decision about which persistence solution fits, and what concessions I&#8217;m willing to make, if any.</p>
]]></content:encoded>
			<wfw:commentRss>http://erniemiller.org/2012/07/17/persistence-is-a-solved-problem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
