<?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>The Code Dump &#187; Programming</title>
	<atom:link href="http://www.codelord.net/tag/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.codelord.net</link>
	<description>A place a coder rants at...</description>
	<lastBuildDate>Sat, 04 Feb 2012 12:53:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Stop Bitching: Use the Tools You Want</title>
		<link>http://www.codelord.net/2011/12/18/stop-bitching-use-the-tools-you-want/</link>
		<comments>http://www.codelord.net/2011/12/18/stop-bitching-use-the-tools-you-want/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 21:52:15 +0000</pubDate>
		<dc:creator>Aviv Ben-Yosef</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[autonomouscraftsmanshipcore]]></category>
		<category><![CDATA[pragmatic]]></category>
		<category><![CDATA[software craftsmanship]]></category>

		<guid isPermaLink="false">http://www.codelord.net/?p=682</guid>
		<description><![CDATA[Continuing on the thread of the Autonomous Craftsmanship Core, we reach another problem: &#8220;they&#8221; just won&#8217;t let you use the right tool, or in the right way. As I&#8217;ve said in the previous posts if anything is so bad you can&#8217;t work with it &#8211; leave; otherwise, you gotta learn how to make do. A pragmatic [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing on the thread of the <a href="http://www.codelord.net/tag/autonomouscraftsmanshipcore/">Autonomous Craftsmanship Core</a>, we reach another problem: &#8220;they&#8221; just won&#8217;t let you use the right tool, or in the right way. As I&#8217;ve said in the <a href="http://www.codelord.net/2011/11/12/stop-bitching-the-autonomous-craftsmanship-core/">previous</a> <a href="http://www.codelord.net/2011/11/28/stop-bitching-write-those-damn-tests/">posts</a> if anything is <em>so</em> bad you can&#8217;t work with it &#8211; leave; otherwise, you gotta learn how to make do.</p>
<p>A <a href="http://www.amazon.com/gp/product/020161622X/ref=as_li_tf_tl?ie=UTF8&amp;tag=thcodu02-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=020161622X">pragmatic programmer</a><img style="border: none !important; margin: 0px !important; display: none;" src="http://www.assoc-amazon.com/e/ir?t=thcodu02-20&amp;l=as2&amp;o=1&amp;a=020161622X" alt="" width="1" height="1" border="0" /> uses the right tool for the job. We all know that if you have a hammer, every problem looks like a nail. In this post I&#8217;m talking about the situation where you have an awesome toolbox right <em>there</em> and yet they&#8217;re forcing you to unscrew something with your pinky&#8217;s nail. Excruciating to your brain.</p>
<p>The thing is, a lot of the times you can just use the right tools and the hell with everyone else. Yes, you can&#8217;t just write code in whatever programming language you want, but in a lot of other situations, you can do what you want to. I think this is best shown with a few examples:</p>
<h3>&#8220;Don&#8217;t commit too much. Say once a day&#8221;</h3>
<p>That&#8217;s a real quote a friend&#8217;s boss told him. Turns out committing multiple times a day is too messy. Most programmers might just sulk and do as they&#8217;re told, but with today&#8217;s technology you&#8217;re no longer bound to these stupid rules. Your team uses subversion? So what! You can use Git locally, do whatever you like, and just push once a day everything via <a href="http://trac.parrot.org/parrot/wiki/git-svn-tutorial">git-svn</a>. Same solutions are available for just about any VCS combination you can think of! I&#8217;ve done this several times working on projects with a VCS I didn&#8217;t want to mess with.</p>
<h3>&#8220;We can&#8217;t have a CI server&#8221;</h3>
<p>Why would someone be against that? Maybe your company doesn&#8217;t want to allocate a new server for such a &#8220;useless&#8221; thing, or maybe the system admins don&#8217;t have time for your little &#8220;developer toys.&#8221; Lucky for everyone, it&#8217;s no longer the case that you need complex setup for such stuff. It&#8217;s just a matter of looking around. For example, if you&#8217;re doing open source you just need to give <a href="http://travis-ci.org/">Travis</a> a look and see you&#8217;re suddenly all set. On the other hand if you&#8217;re code isn&#8217;t open sourced setting up a local <a href="http://jenkins-ci.org/">Jenkins</a> server is <em>so so</em> easy. You just double click a file and you&#8217;ve got it running. If your build isn&#8217;t too CPU hogging, you can run it on your box! And I&#8217;m almost certain you can find some server with some spare cycles to install it on.</p>
<h3>Autonomous Craftsmen Make Do</h3>
<p style="text-align: center;"><a href="http://www.codelord.net/wp-content/uploads/2011/12/macgyver.jpg"><img class="size-medium wp-image-683 aligncenter" title="macgyver" src="http://www.codelord.net/wp-content/uploads/2011/12/macgyver-300x200.jpg" alt="" width="300" height="200" /></a></p>
<p>That sums it up. A craftsman&#8217;s gotta do what a craftsman&#8217;s gotta do.</p>
<p>You should <a href="http://feeds.feedburner.com/TheCodeDump">subscribe</a> to my feed and <a href="http://twitter.com/avivby">follow</a> me on twitter!
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F12%2F18%2Fstop-bitching-use-the-tools-you-want%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F12%2F18%2Fstop-bitching-use-the-tools-you-want%2F&amp;source=avivby&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6107bfac7c92ddff62b393d1e8b7abbe&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://www.codelord.net/2011/12/18/stop-bitching-use-the-tools-you-want/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Your Brain Cares About Code Style</title>
		<link>http://www.codelord.net/2011/12/10/your-brain-cares-about-code-style/</link>
		<comments>http://www.codelord.net/2011/12/10/your-brain-cares-about-code-style/#comments</comments>
		<pubDate>Sat, 10 Dec 2011 18:38:18 +0000</pubDate>
		<dc:creator>Aviv Ben-Yosef</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[software craftsmanship]]></category>

		<guid isPermaLink="false">http://www.codelord.net/?p=670</guid>
		<description><![CDATA[My first team had (among many other great attributes) the custom of strictly following a style guide. It was followed so religiously, I&#8217;ve yet to come across another place that does so to the same extent. It wasn&#8217;t really written down anywhere, but after a couple of weeks of pairing with the other guys you [...]]]></description>
			<content:encoded><![CDATA[<p>My first team had (among many other great attributes) the custom of strictly following a style guide. It was followed so religiously, I&#8217;ve yet to come across another place that does so to the same extent. It wasn&#8217;t really written down anywhere, but after a couple of weeks of pairing with the other guys you got it.</p>
<p>What does that mean exactly? It means that we wrote code that looked, to a large extent, like it was written like the same guy. We put 2 blank lines between regions. Members had a specific way of documenting. We even used the same idioms for creating empty lists etc. (Java).</p>
<p>If we paired with someone and saw him indent the code the wrong way, we&#8217;d go all <em>OCD until it was fixed</em>. And it was regarded totally OK. We didn&#8217;t feel like we were nitpicking on each other. It was the way things got done. I even know a guy that would notice extra whitespace at the end of lines (without any IDE help).</p>
<p>Ever since, whenever I see code written with careless indentation and whitespace I feel like the coder who wrote that just doesn&#8217;t care enough for the craft. Yes, <strong>No Whitespace &#8211; No Care</strong>!</p>
<h3>What&#8217;s the big deal?</h3>
<p>If code isn&#8217;t written in a consistent style in your team, whenever you come across code with the spacing a bit wrong, the first thing your head&#8217;s going to process is &#8220;<strong>I didn&#8217;t write this.</strong>&#8221; This is a natural feeling, and as we all know coders have a hard to restrain impulse to rewrite any piece of code they didn&#8217;t write. Once all the code looks the same, that feeling isn&#8217;t that hard and you can actually focus on the code itself and have a better sense of ownership. I know, it sounds stupid, but that&#8217;s the way our stupid minds work in.</p>
<p>A big part of the <a href="http://www.amazon.com/gp/product/0321278658/ref=as_li_tf_tl?ie=UTF8&#038;tag=thcodu02-20&#038;linkCode=as2&#038;camp=1789&#038;creative=9325&#038;creativeASIN=0321278658">Extreme Programming</a><img src="http://www.assoc-amazon.com/e/ir?t=thcodu02-20&#038;l=as2&#038;o=1&#038;a=0321278658" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important; display: none" /> principle Collective Code Ownership is obtained by simply keeping a consistent style. Anything important enough to become a core value of the only methodology that works must be worth the effort to take notice of.</p>
<p>The next time you see code with reckless spacing, change it and let your teammates know. It might be hard at first but the end goal is important &#8211; the ability to fluidly read code, without feeling like you&#8217;re wearing someone else&#8217;s shoes.</p>
<p>You should subscribe to my <a href="http://feeds.feedburner.com/TheCodeDump">blog</a> and follow me on <a href="http://twitter.com/avivby">twitter</a>!
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F12%2F10%2Fyour-brain-cares-about-code-style%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F12%2F10%2Fyour-brain-cares-about-code-style%2F&amp;source=avivby&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6107bfac7c92ddff62b393d1e8b7abbe&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://www.codelord.net/2011/12/10/your-brain-cares-about-code-style/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Stop Bitching: Write Those Damn Tests</title>
		<link>http://www.codelord.net/2011/11/28/stop-bitching-write-those-damn-tests/</link>
		<comments>http://www.codelord.net/2011/11/28/stop-bitching-write-those-damn-tests/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 21:27:09 +0000</pubDate>
		<dc:creator>Aviv Ben-Yosef</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[autonomouscraftsmanshipcore]]></category>
		<category><![CDATA[software craftsmanship]]></category>

		<guid isPermaLink="false">http://www.codelord.net/?p=510</guid>
		<description><![CDATA[Diving deeper into the idea of the Autonomous Craftsmanship Core, this time I&#8217;d like to talk about one of the first problems a lot of developers face when wanting to start doing clean code. You read Uncle Bob&#8217;s Clean Code, or went to a talk and then go all &#8220;Next day at work I&#8217;m gonna [...]]]></description>
			<content:encoded><![CDATA[<p>Diving deeper into the idea of the <a href="http://www.codelord.net/2011/11/12/stop-bitching-the-autonomous-craftsmanship-core/">Autonomous Craftsmanship Core</a>, this time I&#8217;d like to talk about one of the first problems a lot of developers face when wanting to start doing clean code.</p>
<p>You read Uncle Bob&#8217;s <a href="http://www.amazon.com/gp/product/0132350882/ref=as_li_tf_tl?ie=UTF8&amp;tag=thcodu02-20&amp;linkCode=as2&amp;camp=217145&amp;creative=399369&amp;creativeASIN=0132350882">Clean Code</a><img style="border: none !important; margin: 0px !important; display: none;" src="http://www.assoc-amazon.com/e/ir?t=thcodu02-20&amp;l=as2&amp;o=1&amp;a=0132350882&amp;camp=217145&amp;creative=399369" alt="" width="1" height="1" border="0" />, or went to a talk and then go all &#8220;Next day at work I&#8217;m gonna write tests!!&#8221; Then you come to work, and you give the &#8220;let&#8217;s write tests man!&#8221; speech to your teammate, and he just yawns, and slowly the rush fades.</p>
<p>Lots have been written before about introducing tests to a team as a grunt, but I&#8217;ll do a quick recap:</p>
<p>You <em>don&#8217;t have to ask anyone</em> in order to start and write some tests. Write that first test. Make it pass. Commit. Not that hard, isn&#8217;t it?</p>
<p>Usually the next problem is that if no one else on your team runs the tests, they will keep breaking. But can you blame your team? You need to make them understand that running the tests will actually get them something.</p>
<p>For example, I&#8217;ve seen that after someone makes a commit that breaks the tests because of a bug, coming over to him and telling him what went wrong and how you found out might make him more interested in the idea of testing. A friend recently told me that he made running tests as simple as a double-click for the developers that don&#8217;t write tests. Once it got <em>that</em> easy, they started running them because everyone likes knowing that what they wrote works.</p>
<p>What if your boss won&#8217;t let you write tests? Frankly, <em>why the fuck should your boss care</em>? Does he also tell you when to use &#8220;while&#8221; instead of &#8220;for&#8221;? I don&#8217;t find things such as these to be something any boss should decide about. As I&#8217;ve said in the first post, if you find yourself in a place so resistant to change, <strong>leave</strong>. If you have to stay, do what you have to do. If they won&#8217;t let you commit your tests to source control or set up a continuous integration machine, there are solutions, which I&#8217;ll discuss on my next post.</p>
<p>In the mean time, focus on writing tests that help your teammates find problems and see how slowly your little tests get more and more traction. It&#8217;ll work, because <strong>Success begets attention!</strong></p>
<p>You should subscribe to my <a href="http://feeds.feedburner.com/TheCodeDump">feed</a> and follow me on <a href="http://twitter.com/avivby">twitter</a>!
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F11%2F28%2Fstop-bitching-write-those-damn-tests%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F11%2F28%2Fstop-bitching-write-those-damn-tests%2F&amp;source=avivby&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6107bfac7c92ddff62b393d1e8b7abbe&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://www.codelord.net/2011/11/28/stop-bitching-write-those-damn-tests/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Stop Bitching: the Autonomous Craftsmanship Core</title>
		<link>http://www.codelord.net/2011/11/12/stop-bitching-the-autonomous-craftsmanship-core/</link>
		<comments>http://www.codelord.net/2011/11/12/stop-bitching-the-autonomous-craftsmanship-core/#comments</comments>
		<pubDate>Sat, 12 Nov 2011 11:42:40 +0000</pubDate>
		<dc:creator>Aviv Ben-Yosef</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[autonomouscraftsmanshipcore]]></category>
		<category><![CDATA[software craftsmanship]]></category>

		<guid isPermaLink="false">http://www.codelord.net/?p=504</guid>
		<description><![CDATA[A lot of developers I know keep bitching about how their team isn&#8217;t as passionate as they&#8217;d like it to be, or about their boss not letting them do things like it should be done. They get into this habit and never advance in the right direction because something is holding them back. I know [...]]]></description>
			<content:encoded><![CDATA[<p>A lot of developers I know keep bitching about how their team isn&#8217;t as passionate as they&#8217;d like it to be, or about their boss not letting them do things like it should be done. They get into this habit and never advance in the right direction because something is holding them back. I know this situation well, I&#8217;m usually <em>one of these</em> guys.</p>
<p>In the spirit of <a href="http://programmingtour.blogspot.com/2010/11/positivember.html">Positivember</a> I&#8217;d like to tell you a secret. You can stop whining and start improving. You don&#8217;t have to wait for all the stars to align. That cliché about changes starting from yourself is actually right.</p>
<p><strong>I&#8217;ve heard almost every complaint in the book:</strong></p>
<p><em>&#8220;My teammates don&#8217;t write tests.&#8221;</em><br />
<em>&#8220;They won&#8217;t let me have a continuous integration server.&#8221;</em><br />
<em>&#8220;I can&#8217;t use Git.&#8221;</em><br />
<em>&#8220;My boss hates it when I make a lot of commits.&#8221;</em><br />
<em>&#8220;I was told not to write tests.&#8221;</em><br />
<em>&#8220;We&#8217;re not doing agile development.&#8221;</em><br />
<em>&#8220;I can&#8217;t do pair programming.&#8221;</em></p>
<p>If everything above applies, or you really have lots of problems like these, <em>just quit</em>. A developer that really cares about these things usually can find a better job easily. But, if it&#8217;s only some of these, remember that no work is perfect. There will always be suboptimal stuff to live with. The trick is not to be all bitter about it, but to actually try and make changes happen, slowly, so you still have fun.</p>
<p>Most if not all of these problems are things you can work around, technologically, mentally or socially. If you just stick to your good ways, you&#8217;ll eventually get some followers too.</p>
<p>Step up and realize that everything can start by you and your habits. An <strong>Autonomous Craftsmanship Core</strong> as I like to call it. Sometimes, you core will seem so awesome from the outside that people will join in on some of your practices. Sometimes it will go unnoticed and you will happily go on programming better and better.</p>
<p>I will blog more on tackling some of the problems I mentioned above, but as a starting point I recommend <a href="http://amzn.to/vHjrXa">Apprenticeship Patterns</a> and <a href="http://amzn.to/t68iqC">Driving Technical Change</a>. These great books help a lot in accepting that fact you should take matters into your own hands, and stop bitching.</p>
<p>You should subscribe to my <a href="http://feeds.feedburner.com/TheCodeDump">feed</a> and <a href="http://twitter.com/avivby">follow</a> me on twitter!
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F11%2F12%2Fstop-bitching-the-autonomous-craftsmanship-core%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F11%2F12%2Fstop-bitching-the-autonomous-craftsmanship-core%2F&amp;source=avivby&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6107bfac7c92ddff62b393d1e8b7abbe&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://www.codelord.net/2011/11/12/stop-bitching-the-autonomous-craftsmanship-core/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Stepping Up: Do the Pre-Commit Skim</title>
		<link>http://www.codelord.net/2011/11/05/stepping-up-do-the-pre-commit-skim/</link>
		<comments>http://www.codelord.net/2011/11/05/stepping-up-do-the-pre-commit-skim/#comments</comments>
		<pubDate>Sat, 05 Nov 2011 20:38:24 +0000</pubDate>
		<dc:creator>Aviv Ben-Yosef</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[software craftsmanship]]></category>

		<guid isPermaLink="false">http://www.codelord.net/?p=497</guid>
		<description><![CDATA[I&#8217;m always looking for the easiest way to make my code better, or to train myself to pay more attention to the quality of the code I produce. My latest find is quite obvious yet so very powerful I had to share. Simply put, it&#8217;s just going over your code once more before a commit. [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m always looking for the easiest way to make my code better, or to train myself to pay more attention to the quality of the code I produce. My latest find is quite obvious yet so very powerful I had to share. Simply put, it&#8217;s just <em>going over your code once more before a commit</em>.</p>
<p>Every once in a while, I commit code and forget to add a file. Even worse, I sometimes leave around dead code that I really hate. I&#8217;ve found out that simply making a mental note to go over every file I changed before making a commit makes a big difference. It seems like the Boy Scout Rule from <a href="http://amzn.to/sf6KkN">Clean Code</a> is a special case of this rule.</p>
<p>The trick is to simply go over every file you&#8217;ve changed and <strong>look for common pitfalls</strong>:</p>
<p><strong>Unused code</strong> &#8211; Are there methods your changes just made obsolete? Maybe a conditional with an &#8220;else&#8221; clause that can no longer happen? Delete code! It&#8217;s the best code you&#8217;ll write today!</p>
<p><strong>Zombie code</strong> &#8211; Did you start with something that was too complex and is no longer needed? Often in retrospect you can see how to simplify something and spare your colleagues the <a href="http://www.codelord.net/2011/10/28/fight-zombie-code/">woes of zombie code</a>.</p>
<p><strong>Overdue refactoring</strong> &#8211; Look at your changes. Are you pushing a method too far? Maybe making a class too bloated? Maybe it&#8217;s time to for some cleaning.</p>
<p><strong>Do you have a better name for it now?</strong> Sometimes when you start with something you don&#8217;t have a great name for it. After finishing it, you might be able to slap a better name on that class that will make it more obvious to everyone.</p>
<p><strong>Any dangling TODOs?</strong> I hate committing TODOs unintentionally.</p>
<p><strong>Make sure it&#8217;s all coherent in class-level</strong> &#8211; Some changes make sense when you&#8217;re knee-deep in a change. But step back and make sure it all still makes sense.</p>
<p>&nbsp;</p>
<p>You should <a href="http://feeds.feedburner.com/TheCodeDump">subscribe</a> to my feed and <a href="http://twitter.com/avivby">follow</a> me on twitter!
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F11%2F05%2Fstepping-up-do-the-pre-commit-skim%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F11%2F05%2Fstepping-up-do-the-pre-commit-skim%2F&amp;source=avivby&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6107bfac7c92ddff62b393d1e8b7abbe&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://www.codelord.net/2011/11/05/stepping-up-do-the-pre-commit-skim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fight Zombie Code</title>
		<link>http://www.codelord.net/2011/10/28/fight-zombie-code/</link>
		<comments>http://www.codelord.net/2011/10/28/fight-zombie-code/#comments</comments>
		<pubDate>Fri, 28 Oct 2011 14:57:27 +0000</pubDate>
		<dc:creator>Aviv Ben-Yosef</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[software craftsmanship]]></category>
		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://www.codelord.net/?p=490</guid>
		<description><![CDATA[If there&#8217;s anything I hate more than dead code, it&#8217;s zombie code. Dead code is code that&#8217;s remained in the system even though it&#8217;s no longer really used. It might be small, like unused imports, instance variables and methods. It can be whole classes that make up entire features no longer used. The biggest PITA [...]]]></description>
			<content:encoded><![CDATA[<p>If there&#8217;s anything I hate more than dead code, it&#8217;s zombie code. Dead code is code that&#8217;s remained in the system even though it&#8217;s no longer really used.</p>
<p>It might be small, like unused imports, instance variables and methods. It can be whole classes that make up entire features no longer used.</p>
<p>The biggest PITA is when you&#8217;re not really aware of the fact the code&#8217;s dead and unused, sitting there and occupying precious bits, and stumble across it as part of a task, trying to understand how it influences what you want to do next.</p>
<p>Whenever I recognized something that looks like dead code but I&#8217;m not entirely sure, I find it pretty easy to delete it quickly, once I take a look in the version control logs and see when it became no longer in use and why.</p>
<p>Zombie code is code that was never alive, and so couldn&#8217;t really become dead. It&#8217;s the undead code &#8211; code that died right when it was committed. Code that never ran or never worked. The are two reasons I hate zombie code more than &#8220;plain&#8221; dead code.</p>
<p><a href="http://codelord.net/wp-content/uploads/2011/10/test_my_code.jpg"><img class="aligncenter size-medium wp-image-491" title="test_my_code" src="http://codelord.net/wp-content/uploads/2011/10/test_my_code-300x300.jpg" alt="" width="300" height="300" /></a></p>
<p>The first reason is that it simply wastes more of my time. Looking back in version control won&#8217;t help me see the commit in which the code was &#8220;decommissioned&#8221;, it would just appear to always sit there. That means I have to take extra care to verify that it, in fact, never worked.</p>
<p>The second reason is that it&#8217;s plainly someone saying he doesn&#8217;t give a damn. I mean, let&#8217;s put aside TDD. Heck, let&#8217;s put aside unit testing at all. It means the code never even ran the damn thing and saw in his own eyes it did what he claims it did.</p>
<p>Be kind to your teammates. If you&#8217;re not a good enough coder to test it, at least see that it runs <em>once</em> in your own eyes.</p>
<p>&nbsp;</p>
<p>You should <a href="http://feeds.feedburner.com/TheCodeDump">subscribe</a> to my feed and <a href="http://twitter.com/avivby">follow</a> me on twitter!
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F10%2F28%2Ffight-zombie-code%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F10%2F28%2Ffight-zombie-code%2F&amp;source=avivby&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6107bfac7c92ddff62b393d1e8b7abbe&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://www.codelord.net/2011/10/28/fight-zombie-code/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>TIL: Ruby Classes that Look Callable</title>
		<link>http://www.codelord.net/2011/10/18/til-ruby-classes-that-look-callable/</link>
		<comments>http://www.codelord.net/2011/10/18/til-ruby-classes-that-look-callable/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 06:01:07 +0000</pubDate>
		<dc:creator>Aviv Ben-Yosef</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.codelord.net/?p=478</guid>
		<description><![CDATA[One of the concept I had to get used to moving from Python to Ruby was that regular objects aren&#8217;t callable, and that there was a closed set of objects that can be called. Meaning that where in Python it was possible for any class to implement __call__ and so allow us to call it [...]]]></description>
			<content:encoded><![CDATA[<p>One of the concept I had to get used to moving from Python to Ruby was that regular objects aren&#8217;t callable, and that there was a closed set of objects that can be called. Meaning that where in Python it was possible for any class to implement __call__ and so allow us to call it with obj(), Ruby doesn&#8217;t allow this. One of the advantages of that syntax in Python is that each class implements its constructor using this. For example:</p>
<div id="gist-1294707" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">class</span> <span class="nc">MyClass</span><span class="p">:</span></div><div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span></div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="n">my_class</span> <span class="o">=</span> <span class="n">MyClass</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c"># We are calling the class to get</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c"># an instance, instead of</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c"># MyClass.new(1) in Ruby</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1294707/7a760a138fc398385bb88ed224a9068db14acce0/python_class_is_callable.py" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1294707#file_python_class_is_callable.py" style="float:right;margin-right:10px;color:#666">python_class_is_callable.py</a>
            <a href="https://gist.github.com/1294707">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>This was a nice little trick I liked in Python but quickly got used to living without it. That was until I saw Ruby code that seemed to allow the exact same behavior:</p>
<div id="gist-1294707" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="nb">Integer</span><span class="o">.</span><span class="n">class</span></div><div class='line' id='LC2'><span class="c1">#=&gt; Class</span></div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'><span class="nb">Integer</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span></div><div class='line' id='LC5'><span class="c1">#=&gt; 1</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1294707/79c7308c3d48f07d51893c6763e16aa4d7b6ae4f/ruby_class_looks_callable.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1294707#file_ruby_class_looks_callable.rb" style="float:right;margin-right:10px;color:#666">ruby_class_looks_callable.rb</a>
            <a href="https://gist.github.com/1294707">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>How&#8217;s this so? Can we really make classes callable? A quick glance at Integer&#8217;s source code in the Rubinius code reveals that there&#8217;s no magic going on in it, and that it actually has no reference for this method I&#8217;m looking to call. Instead what we&#8217;ll see is that alongside the class definition there&#8217;s also a method definition:</p>
<div id="gist-1294707" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">class</span> <span class="nc">Integer</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="c1">#...</span></div><div class='line' id='LC3'><span class="k">end</span></div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="k">def</span> <span class="nf">Integer</span><span class="p">(</span><span class="n">value</span><span class="p">)</span></div><div class='line' id='LC6'>&nbsp;&nbsp;<span class="c1">#...</span></div><div class='line' id='LC7'><span class="k">end</span></div></pre></div>
          </div>

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

<p>So the whole trick is simply to define both. But how exactly does this work? How are names not clashing?</p>
<p>What actually happens is that whenever we define a new class or module, its name is added as a constant that points to the actual class. Similarly, when we define a method at the top level it&#8217;s added as a private method to Object. That means that whenever we type in a name that looks like a constant (starts with a capital letter) without parenthesis, Ruby will search for that constant:</p>
<div id="gist-1294707" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="no">Object</span><span class="o">.</span><span class="n">const_defined?</span> <span class="ss">:Integer</span></div><div class='line' id='LC2'><span class="c1">#=&gt; true</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1294707/322fcc9dcbbaf8fa55165125b0d3790384075cb3/const_lookup.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1294707#file_const_lookup.rb" style="float:right;margin-right:10px;color:#666">const_lookup.rb</a>
            <a href="https://gist.github.com/1294707">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>But when we add parenthesis, Ruby understands that it should seek for a method instead:</p>
<div id="gist-1294707" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="no">Object</span><span class="o">.</span><span class="n">private_method_defined?</span> <span class="ss">:Integer</span></div><div class='line' id='LC2'><span class="c1">#=&gt; true</span></div></pre></div>
          </div>

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

<p>This nifty little trick is all it takes for Ruby to allow this nice syntax.</p>
<p>Hope you learned a new thing! In case you want to dig deeper, two great books that really helped me wrap my head around dark corners of Ruby are <a href="http://www.amazon.com/gp/product/0321584104/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;tag=thcodu02-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321584104">Eloquent Ruby</a> and <a href="http://www.amazon.com/gp/product/1934356476/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;tag=thcodu02-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1934356476">Metaprogramming Ruby</a>.</p>
<p>You should <a href="http://feeds.feedburner.com/TheCodeDump">subscribe</a> to my feed and <a href="http://twitter.com/avivby">follow</a> me on twitter!
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F10%2F18%2Ftil-ruby-classes-that-look-callable%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F10%2F18%2Ftil-ruby-classes-that-look-callable%2F&amp;source=avivby&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6107bfac7c92ddff62b393d1e8b7abbe&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://www.codelord.net/2011/10/18/til-ruby-classes-that-look-callable/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Submitting your first patch to Rubinius</title>
		<link>http://www.codelord.net/2011/10/11/submitting-your-first-patch-to-rubinius/</link>
		<comments>http://www.codelord.net/2011/10/11/submitting-your-first-patch-to-rubinius/#comments</comments>
		<pubDate>Tue, 11 Oct 2011 05:02:04 +0000</pubDate>
		<dc:creator>Aviv Ben-Yosef</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[rubinius]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.codelord.net/?p=463</guid>
		<description><![CDATA[I always love helping interesting open source projects, and Rubinius is one of those great projects that are very cool to play with. In case you don&#8217;t know it, Rubinius is a Ruby implementation written (almost) entirely in Ruby. Just playing with such a code base is quite interesting and whenever a peek around in [...]]]></description>
			<content:encoded><![CDATA[<p>I always love helping interesting open source projects, and Rubinius is one of those great projects that are very cool to play with. In case you don&#8217;t know it, Rubinius is a Ruby implementation written (almost) entirely in Ruby. Just playing with such a code base is quite interesting and whenever a peek around in the code I learn new stuff about Ruby.</p>
<p>At the moment, the people at Rubinius are working hard on making it compatible with ruby 1.9, and so there are a lot of easy changes that are waiting for you to do and start contributing. I&#8217;d like to show you a quick walk-through of how to find such simple tasks and get started.</p>
<h3>Setup</h3>
<p>Clone the project from the GitHub <a href="https://github.com/rubinius/rubinius">repo</a>. Once that&#8217;s done, to make sure that everything works properly do this:</p>
<p><code> ./configure<br />
rake spec<br />
</code></p>
<p>The specs should be all passing on your machine. It will take a few minutes the first time, but afterwards whenever you make small changes it will be faster.</p>
<h3>Finding interesting work</h3>
<p>Of course you can submit whatever patch you find interesting, but in my opinion a quick way to get started is to find incompatibilities with 1.9. Fortunately for you, it&#8217;s pretty easy to find those.</p>
<p>Rubinius, along with the other Ruby implementations, uses mspec in order to have written specs of the language written in Ruby and is checked against that. These specs are similar to RSpec. Among other options, some specs are simply marked as having to pass only on Ruby 1.9 and of these, those that are currently failing are our hunt.</p>
<p>I came up with this command in order to find and execute such 1.9 specs that were last reported by Rubinius developers to be failing:</p>
<p><code>bin/mspec tag --list fails -tx19 :ci_files</code></p>
<p>This command will list the RubySpecs that are tagged as failing on Rubinius in 1.9 mode.</p>
<p>You should see plenty (at the time of this writing, over 500) of failing specs. Just pick something that seems easy enough to get started with.</p>
<p>Once you spot a spec that looks interesting you can run it specifically and see the code. For example, if you see an interesting spec for String#squeeze, you can run it with:</p>
<p><code>bin/mspec -tx19 spec/ruby/core/string/squeeze_spec.rb</code></p>
<h3>Doing some work</h3>
<p>For example, let&#8217;s look at one of the really simple specs I decided to get passing, you can see the commit <a href="https://github.com/rubinius/rubinius/commit/723fc5ee6c57267c92744b24a100c595375ef39c">here</a>. I wanted to make a simple change to the String#ord method, but only on 1.9 version. The way to do that on Rubinius is that many of the files, say string.rb now have also &#8220;string18.rb&#8221; and &#8220;string19.rb&#8221; that contain the code that differs. In my case, I just made a simple change to the version used on 1.9 by editing the ord method on the string19.rb file (in case the 19 and 18 files don&#8217;t exist yet, you can simply create them like shown <a href="https://github.com/rubinius/rubinius/commit/42fe03c5e6b82b712dcdbdf5875581f854e21af7">here</a>).</p>
<p>After you&#8217;ve made your changes, be sure to run the specs again and see that everything works. Before submitting it, you should make sure to run all specs thoroughly using the command <span style="font-family: monospace;">rake spec</span>. If all is well, just do the regular GitHub <a href="http://help.github.com/send-pull-requests/">pull-request dance</a> and off you go!</p>
<p>Further than that, you can include in your pull request another commit that removes the failing tags from the specs you&#8217;ve just fixed. Find the appropriate file and just remove it, as you can see in <a href="https://github.com/rubinius/rubinius/commit/bfde3637a454eade1972a636dd8a1ad05d9fdc57">this commit</a>.</p>
<p>For some more in depth review of how to start contributing to Rubinius, see this <a href="http://rubini.us/2011/10/18/contributing-to-rubinius/">excellent post</a> on the official blog.</p>
<p>You should subscribe to my <a href="http://feeds.feedburner.com/TheCodeDump">feed</a> and follow me on <a href="http://twitter.com/avivby">twitter</a>!
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F10%2F11%2Fsubmitting-your-first-patch-to-rubinius%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F10%2F11%2Fsubmitting-your-first-patch-to-rubinius%2F&amp;source=avivby&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6107bfac7c92ddff62b393d1e8b7abbe&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://www.codelord.net/2011/10/11/submitting-your-first-patch-to-rubinius/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>When being idiomatic wears you out</title>
		<link>http://www.codelord.net/2011/08/27/when-being-idiomatic-wears-you-out/</link>
		<comments>http://www.codelord.net/2011/08/27/when-being-idiomatic-wears-you-out/#comments</comments>
		<pubDate>Sat, 27 Aug 2011 11:25:33 +0000</pubDate>
		<dc:creator>Aviv Ben-Yosef</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[software craftsmanship]]></category>

		<guid isPermaLink="false">http://www.codelord.net/?p=453</guid>
		<description><![CDATA[I believe that when learning a new programming language, it&#8217;s really important to learn its idioms and use them. I&#8217;ve written procedural C-like code in Java, and bloated Java-like code in Python, but only once you start using a language &#8220;like it was meant to&#8221; can you really say you&#8217;ve started mastering it. Had I [...]]]></description>
			<content:encoded><![CDATA[<p>I believe that when learning a new programming language, it&#8217;s really important to learn its idioms and use them. I&#8217;ve written procedural C-like code in Java, and bloated Java-like code in Python, but only once you start using a language &#8220;like it was meant to&#8221; can you really say you&#8217;ve started mastering it. Had I not read <a href="http://www.amazon.com/gp/product/0321356683/ref=as_li_tf_tl?ie=UTF8&#038;tag=thcodu02-20&#038;linkCode=as2&#038;camp=217145&#038;creative=399381&#038;creativeASIN=0321356683">Effective Java</a><img src="http://www.assoc-amazon.com/e/ir?t=thcodu02-20&#038;l=as2&#038;o=1&#038;a=0321356683&#038;camp=217145&#038;creative=399381" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important; display: none" /> I don&#8217;t think I could have ever written a sensible line in this language.</p>
<p>I practically cringe whenever I see someone creating a new list in Java and then adding to it a single element when he just could have used <span style="font-family: monospace">Collections.singletonList(element)</span>. I&#8217;m that kind of a fanatic.</p>
<p>But, lately I&#8217;m getting worn out of being verbose. Yes, you can use the trick above to save a line of code and a lot of typing, but damn it &#8211; I just want to say <span style="font-family: monospace">[element]</span>!</p>
<p>Less than a month into BillGuard we realized we don&#8217;t want to do all of our coding in Java and started calling Python code from Java (not in the JVM though, since Jython just doesn&#8217;t seem solid enough). Running away from Java&#8217;s notoriously long idioms, we preferred adding the overhead of having multiple programming languages in one project (which I think justified itself plenty, but it is an overhead).</p>
<p>This solution helped us when doing big stuff we didn&#8217;t want to do in Java, stuff that we&#8217;d represent in a unique class. But the smaller stuff just kept nagging us. We kept finding ourselves writing 10-15 lines of code to do something we thought trivial and then putting a 1-2 lines of comments before it saying what we actually meant in Python. These eventually lead to a lot of extracted methods which are generally good, but rarely would I extract such logic in Python/Ruby &#8211; where it would be a single concise line of code.</p>
<p>Lately, we started toying with just saying &#8220;screw the idioms&#8221; and doing what feels right. If that means having a <span style="font-family: monospace">JavaSucksUtils</span> class with methods such as <span style="font-family: monospace">zip()</span> and <span style="font-family: monospace">defaultdict_int()</span> so be it. I think that with time this will lead to using a wholly different language in the JVM mostly, but in the mean time this seems to be a nice transition.</p>
<p>I mean, common:</p>
<div id="gist-1175248" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>// Why write this..</div><div class='line' id='LC2'>public static &lt;T, V&gt; Map&lt;T, List&lt;V&gt;&gt; defaultdict_list() {</div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;return new MapMaker().makeComputingMap(new Function&lt;T, List&lt;V&gt;&gt;() {</div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override public List&lt;V&gt; apply(T unusedCrap) {</div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return Lists.newArrayList();</div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;});</div><div class='line' id='LC8'>}</div><div class='line' id='LC9'><br/></div><div class='line' id='LC10'># When you just want this (Python)</div><div class='line' id='LC11'>defaultdict(list)</div><div class='line' id='LC12'><br/></div><div class='line' id='LC13'># Or this (Ruby)</div><div class='line' id='LC14'>Hash.new {|h,k| h[k] = []}</div></pre></div>
          </div>

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

<p>Now we&#8217;ll have to wait and see where this gets us.</p>
<p>You should <a href="http://feeds.feedburner.com/TheCodeDump">subscribe</a> to my feed and <a href="http://twitter.com/avivby">follow</a> me on twitter!
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F08%2F27%2Fwhen-being-idiomatic-wears-you-out%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F08%2F27%2Fwhen-being-idiomatic-wears-you-out%2F&amp;source=avivby&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6107bfac7c92ddff62b393d1e8b7abbe&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://www.codelord.net/2011/08/27/when-being-idiomatic-wears-you-out/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Guest Post: Lookup Tables with Ruby-on-Rails</title>
		<link>http://www.codelord.net/2011/08/09/guest-post-lookup-tables-with-ruby-on-rails/</link>
		<comments>http://www.codelord.net/2011/08/09/guest-post-lookup-tables-with-ruby-on-rails/#comments</comments>
		<pubDate>Tue, 09 Aug 2011 20:18:07 +0000</pubDate>
		<dc:creator>Aviv Ben-Yosef</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[guestposts]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://www.codelord.net/?p=427</guid>
		<description><![CDATA[This is a guest-post by Nimrod Priell (@nimrodpriell) about the kind of time-saving tricks that I&#8217;m amazed are so easy to pull off in Rails If you want to have an ActiveRecord macro to define memory-cached, dynamically growing, normalized lookup tables for entity &#8216;type&#8217;-like objects, read along. Or in plain English &#8211; if you want [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is a guest-post by Nimrod Priell (<a href="http://twitter.com/nimrodpriell">@nimrodpriell</a>) about the kind of time-saving tricks that I&#8217;m amazed are so easy to pull off in Rails</em></p>
<p>If you want to have an ActiveRecord macro to define memory-cached, dynamically growing, normalized lookup tables for entity &#8216;type&#8217;-like objects, read along. Or in plain English &#8211; if you want to have a table containing, say, ProductTypes which can grow with new types simply when you refer to them, and not keep the Product table containing a thousand repeating <span style="font-family: Courier;">&#8216;type=&#8221;book&#8221;&#8216;</span> entries &#8211; and gain some insight into ruby metaprogramming techniques &#8211; sit down and try to follow through.</p>
<p>A <a href="http://en.wikipedia.org/wiki/Database_normalization">normalized DB</a> means that you want to keep types as separate tables, with foreign keys pointing from your main entity to its type. For instance, instead of:</p>
<table border="1">
<tbody>
<tr>
<td>ID</td>
<td>car_name</td>
<td>car_type</td>
</tr>
<tr>
<td>1</td>
<td>Chevrolet Aveo</td>
<td>Compact</td>
</tr>
<tr>
<td>2</td>
<td>Ford Fiesta</td>
<td>Compact</td>
</tr>
<tr>
<td>3</td>
<td>BMW Z-5</td>
<td>Sports</td>
</tr>
</tbody>
</table>
<p>You want to have two tables:</p>
<table border="1">
<tbody>
<tr>
<td>ID</td>
<td>car_name</td>
<td>car_type_id</td>
</tr>
<tr>
<td>1</td>
<td>Chevrolet Aveo</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>Ford Fiesta</td>
<td>1</td>
</tr>
<tr>
<td>3</td>
<td>BMW Z-5</td>
<td>2</td>
</tr>
</tbody>
</table>
<p>And</p>
<table border="1">
<tbody>
<tr>
<td>car_type_id</td>
<td>car_type_name</td>
</tr>
<tr>
<td>1</td>
<td>Compact</td>
</tr>
<tr>
<td>2</td>
<td>Sports</td>
</tr>
</tbody>
</table>
<p>The pros/cons of a normalized DB can be discussed elsewhere. I&#8217;d just point out a denormalized solution is most useful in settings like <a href="http://en.wikipedia.org/wiki/Column-oriented_DBMS">column oriented DBMSes</a>. For the rest of us folks using standard databases, we usually want to use lookups.</p>
<p>The usual way to do this with ruby on rails is:</p>
<ul>
<li>Generate a CarType model using <span style="font-family: Courier;">rails generate model CarType name:string</span></li>
<li>Link between CarType and Car tables using belongs_to and has_many</li>
</ul>
<p>Then to work with this you can transparently read the car type:</p>
<p><code>car = Car.first<br />
car.car_type.name # returns "Compact"</code></p>
<p>Ruby does an awesome job of caching the results for you, so that you&#8217;ll probably not hit the DB every time you get the same car type from different car objects.</p>
<p>You can even make this shorter, by defining a delegate to car_type_name from CarType:</p>
<p><code># car_type_name.rb<br />
delegate :name, :to =&gt; :car, :prefix =&gt; true</code></p>
<p>And now you can access this as</p>
<p><code># car_type.rb<br />
car.car_type_name<br />
</code></p>
<p>However, it&#8217;s less pleasant to insert with this technique:</p>
<p><code>car.car_type.car_type_name = "Sports"<br />
car.car_type.save!<br />
#Now let's see what happened to the OTHER compact car<br />
Car.all.second.car_type_name #Oops, returns "Sports"<br />
</code></p>
<p>Right, what are we doing? We should&#8217;ve used</p>
<p><code> car.update_attributes(car_type: CarType.find_or_create_by_name(name: "Sports"))<br />
</code></p>
<p>Okay. Probably want to shove that into its own method rather than have this repeated in the code several times. But you also need a helper method for creating cars that way…</p>
<p>Furthermore, ruby is good about caching, but it caches by the exact query used, and the cache expires after the controller action ends. You can configure more advanced caches, perhaps.</p>
<p>The thing is all this can get tedious if you use a normalized structure where you have 15 entities and each has at least one &#8216;type-like&#8217; field. That&#8217;s a whole lot of dangling Type objects. What you really want is an interface like this:</p>
<p><code>car = Car.first<br />
car.car_type #returns "Compact"<br />
car.car_type = "Sports" #No effect on Car.all.second, just automatically use the second constant<br />
car.car_type = "Sedan" #Magically create a new type<br />
</code></p>
<p>Oh, and it&#8217;ll be nice if all of this is cached and you can define car types as constants (or symbols). You obviously still want to be able to run:</p>
<p><code>CarType.where(:id &gt; 3) #Just an example of supposed "arbitrary" SQL involving a real live CarType class<br />
</code></p>
<p>But you wanna minimize generating these numerous type classes. If you&#8217;re like me, you don&#8217;t even want to see them lying around in app/model. Who cares about them?<br />
I&#8217;ve looked thoroughly for a nice rails solution to this, but after failing to find one, I created my own rails metaprogramming hook.<br />
The result of this hook is that you get the exact syntax described above, with only two lines of code (no extra classes or anything):</p>
<p>In your ActiveRecord object simply add</p>
<p><code># car.rb<br />
require 'active_record/lookup'<br />
class Car &lt; ActiveRecord::Base<br />
#...<br />
include ActiveRecord::Lookup<br />
lookup :car_type, :as =&gt; :type<br />
#…<br />
end<br />
</code></p>
<p>That&#8217;s it. the generated CarType class (which you won&#8217;t see as a car_type.rb file, obviously, as it is generated in real-time), contains some nice methods to look into the cache as well: So you can call</p>
<p><code>CarType.id_for "Sports" #Returns 2<br />
CarType.name_for 1 #Returns "Compact"<br />
</code></p>
<p>and you can still hack at the underlying ID for an object, if you need to:</p>
<p><code>car = Car.first<br />
car.car_type = "Sports"<br />
car.car_type_id #Returns 2<br />
car.car_type_id = 1<br />
car.car_type #Returns "Compact"<br />
car.find_car_by_type_and_color("Compact", :blue) #Works, the underlying search is done by the ID<br />
</code></p>
<p>The full source code and gem can be found in <a href="https://github.com/Nimster/RailsLookup" target="_blank">https://github.com/Nimster/RailsLookup</a> . The gem is named rails_lookup so you can just `gem install rails_lookup` to get the functionality required.</p>
<p>Note you do need to create tables for the new Type classes. The table format is very simple:</p>
<p><code> create_table :car_types do |t|<br />
t.string :name<br />
end<br />
add_column :cars, :type, :integer<br />
</code></p>
<p>In this post, however, I would like to elucidate how this is achieved, hopefully teaching some ruby meta-programming and rails considerations on the way.</p>
<p>So how do we achieve that? Well, we start with creating our own Lookup module which can be included into active record classes:</p>
<div id="gist-1129084" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">module</span> <span class="nn">Lookup</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'>&nbsp;&nbsp;<span class="k">module</span> <span class="nn">ClassMethods</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#Any new &quot;macros&quot; go here</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nf">lookup</span><span class="p">(</span><span class="n">lookup_name</span><span class="p">)</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC7'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'>&nbsp;&nbsp;<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">included</span><span class="p">(</span><span class="n">host_class</span><span class="p">)</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">host_class</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="no">ClassMethods</span><span class="p">)</span> </div><div class='line' id='LC11'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC12'><span class="k">end</span></div></pre></div>
          </div>

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

<p>This is the basic setup for inserting a new &#8220;macro&#8221; like belongs_to (which is actually a simple class method). When the Lookup module is included in a class, the ruby interpreter will call the hook method &#8220;self.included&#8221; with the class this was included into. We ask to also extend this class, thereby adding any class methods defined in ClassMethods into it.</p>
<p>We can now call &#8220;lookup :car_type, :as =&gt; :type&#8221; in our Car class, only that it doesn&#8217;t do anything. Let&#8217;s make it do something. We need to achieve the following things:</p>
<ol>
<li>Create the CarType ActiveRecord</li>
<li>Link the CarType and Car ActiveRecords (with the standard has_many, belongs_to link)</li>
<li>Make the Car#car_type=, Car#car_type methods behave in the way we described above.</li>
<li>(Optional) code-fill the caches when the class loads from the data in the DB</li>
</ol>
<p>We will now present the code for each &#8211; when you read through, remember this all runs in the host class context (e.g. Car) so that self is the Car class, and any actions we take are equivalent to having explicitly written them in the Car class itself.</p>
<div id="gist-1129091" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nf">lookup</span><span class="p">(</span><span class="n">as_name</span><span class="p">)</span></div><div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">mycls</span> <span class="o">=</span> <span class="nb">self</span> <span class="c1">#Class I&#39;m defined in</span></div><div class='line' id='LC3'>&nbsp;</div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#We now define the CarType class, as if we were in a file car_type.rb</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">cls</span> <span class="o">=</span> <span class="no">Class</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span><span class="p">)</span> <span class="k">do</span> <span class="c1">#Define a new class, extending AR::Base</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#CarType should have the has_many :cars link</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">has_many</span> <span class="n">mycls</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">tableize</span><span class="o">.</span><span class="n">to_sym</span></div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#These are optional. You can define any additional constraints you like.</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">validates_uniqueness_of</span> <span class="ss">:name</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">validates</span> <span class="ss">:name</span><span class="p">,</span> <span class="ss">:presence</span> <span class="o">=&gt;</span> <span class="kp">true</span></div><div class='line' id='LC12'><br/></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#Methods for using the cache. Providing a second argument saves data into the cache.</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">id_for</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span> <span class="nb">id</span> <span class="o">=</span> <span class="kp">nil</span><span class="p">)</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#We cannot access the class variable for CarType as simply &#39;@@rcaches&#39; because it will</span></div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#look for @@rcaches in the scope of the module we&#39;re in.</span></div><div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">class_variable_get</span><span class="p">(</span><span class="ss">:@@rcaches</span><span class="p">)</span><span class="o">[</span><span class="nb">name</span><span class="o">]</span> <span class="o">||=</span> <span class="nb">id</span></div><div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC19'><br/></div><div class='line' id='LC20'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#This helper method is the &quot;find_or_create&quot; of the class that also</span></div><div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#updates the cache and the DB.</span></div><div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">gen_id_for</span><span class="p">(</span><span class="n">val</span><span class="p">)</span></div><div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nb">id</span> <span class="o">=</span> <span class="n">id_for</span> <span class="n">val</span></div><div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="nb">id</span><span class="o">.</span><span class="n">nil?</span></div><div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#Define this new possible value</span></div><div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">new_db_obj</span> <span class="o">=</span> <span class="n">find_or_create_by_name</span> <span class="n">val</span></div><div class='line' id='LC27'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">id_for</span> <span class="n">val</span><span class="p">,</span> <span class="n">new_db_obj</span><span class="o">.</span><span class="n">id</span></div><div class='line' id='LC28'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">name_for</span> <span class="n">new_db_obj</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">val</span></div><div class='line' id='LC29'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nb">id</span> <span class="o">=</span> <span class="n">new_db_obj</span><span class="o">.</span><span class="n">id</span></div><div class='line' id='LC30'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC31'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nb">id</span></div><div class='line' id='LC32'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC33'><br/></div><div class='line' id='LC34'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#Query the cache for the value that goes with a certain DB ID</span></div><div class='line' id='LC35'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">name_for</span><span class="p">(</span><span class="nb">id</span><span class="p">,</span> <span class="nb">name</span> <span class="o">=</span> <span class="kp">nil</span><span class="p">)</span></div><div class='line' id='LC36'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">class_variable_get</span><span class="p">(</span><span class="ss">:@@caches</span><span class="p">)</span><span class="o">[</span><span class="nb">id</span><span class="o">]</span> <span class="o">||=</span> <span class="nb">name</span></div><div class='line' id='LC37'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC38'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC39'><br/></div><div class='line' id='LC40'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#Finally, Bind the created class to a name</span></div><div class='line' id='LC41'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">lookup_cls_name</span> <span class="o">=</span> <span class="n">lookup_name</span><span class="o">.</span><span class="n">to_s</span><span class="o">.</span><span class="n">camelize</span></div><div class='line' id='LC42'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="no">Object</span><span class="o">.</span><span class="n">const_set</span> <span class="n">lookup_cls_name</span><span class="p">,</span> <span class="n">cls</span> <span class="c1">#Define it as a global class</span></div></pre></div>
          </div>

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

<p>The important parts to note here are:</p>
<ul>
<li>How we define a new class and then bind it to the constant &#8220;CarType&#8221; so that after a class containing the lookup (like Car) is referred to (just calling Car.to_s is enough), the CarType is not accessible as if it were inside of a car_type.rb file in our app/models directory.</li>
<li>How we use Rails&#8217; built-in Inflections module which it mixes in to string, to move from so-called &#8220;table_notation&#8221; to CamelNotation and vice versa.</li>
<li>How we use class_variable_get and class_variable_set to access the class variables of the newly created CarType class &#8211; because confusingly enough @@var will refer to the class we&#8217;re in now and not the one being defined inside the block, when the code is executed. We discuss initialization of these two variables later on, during part (4).</li>
</ul>
<blockquote>
<div>Side note: This is not the complete class definition &#8211; I shortened it a bit to remove details which are handled in the gem version, like supporting Rails&#8217; where() methods, support anonymous classes that have lookups and supporting multiple classes using the same lookup. If you&#8217;re interested in these, I urge you to check out the gem.</div>
</blockquote>
<p>Note also that we have already included the has_many link inside of CarType. In the same way, we will include the belongs_to in the other direction. We do this and also define the special accessors for getting and setting the CarType as a String:</p>
<div id="gist-1129101" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nf">lookup</span><span class="p">(</span><span class="n">as_name</span><span class="p">)</span></div><div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#...</span></div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#Now, define the foreign key from Car to CarType.</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">belongs_to</span> <span class="n">lookup_name</span><span class="o">.</span><span class="n">to_s</span><span class="o">.</span><span class="n">to_sym</span><span class="p">,</span> <span class="ss">:foreign_key</span> <span class="o">=&gt;</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">as_name</span><span class="si">}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">to_sym</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">validates</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">as_name</span><span class="o">.</span><span class="n">to_s</span><span class="si">}</span><span class="s2">_id&quot;</span><span class="o">.</span><span class="n">to_sym</span><span class="p">,</span> <span class="ss">:presence</span> <span class="o">=&gt;</span> <span class="kp">true</span></div><div class='line' id='LC7'><br/></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#Now we define the &quot;delegates&quot; that will allow us to just set call car.car_type = &quot;Sports&quot;</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#Define a setter for car_type</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">define_method</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">#{</span><span class="n">as_name</span><span class="o">.</span><span class="n">to_s</span><span class="si">}</span><span class="s2">_id=&quot;</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="nb">id</span><span class="o">|</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#We would have used instance_variable_get. However rails maintains a hash of attributes </span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#that we must use to play nicely along with rails. Here we write the ID of the value</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#instead of the value itself inside the field.</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">write_attribute</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">as_name</span><span class="o">.</span><span class="n">to_s</span><span class="si">}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">to_sym</span><span class="p">,</span> <span class="nb">id</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC16'><br/></div><div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1"># Setter via String</span></div><div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">define_method</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">#{</span><span class="n">as_name</span><span class="o">.</span><span class="n">to_s</span><span class="si">}</span><span class="s2">=&quot;</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">val</span><span class="o">|</span></div><div class='line' id='LC19'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nb">id</span> <span class="o">=</span> <span class="n">cls</span><span class="o">.</span><span class="n">gen_id_for</span> <span class="n">val</span></div><div class='line' id='LC20'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">write_attribute</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">as_name</span><span class="o">.</span><span class="n">to_s</span><span class="si">}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">to_sym</span><span class="p">,</span> <span class="nb">id</span></div><div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC22'><br/></div><div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1"># Getter for the ID</span></div><div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">define_method</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">#{</span><span class="n">as_name</span><span class="o">.</span><span class="n">to_s</span><span class="si">}</span><span class="s2">_id&quot;</span><span class="p">)</span> <span class="k">do</span> </div><div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">read_attribute</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">as_name</span><span class="o">.</span><span class="n">to_s</span><span class="si">}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">to_sym</span></div><div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC27'><br/></div><div class='line' id='LC28'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#Define the getter</span></div><div class='line' id='LC29'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">define_method</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">#{</span><span class="n">as_name</span><span class="o">.</span><span class="n">to_s</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span> <span class="k">do</span> </div><div class='line' id='LC30'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nb">id</span> <span class="o">=</span> <span class="n">read_attribute</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">as_name</span><span class="o">.</span><span class="n">to_s</span><span class="si">}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">to_sym</span></div><div class='line' id='LC31'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="ow">not</span> <span class="nb">id</span><span class="o">.</span><span class="n">nil?</span></div><div class='line' id='LC32'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">value</span> <span class="o">=</span> <span class="n">cls</span><span class="o">.</span><span class="n">name_for</span> <span class="nb">id</span></div><div class='line' id='LC33'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">nil?</span></div><div class='line' id='LC34'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1"># This is reached in case many processes use the DB and some other process</span></div><div class='line' id='LC35'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1"># inserted a new value that we were not aware of, but who&#39;s ID was inserted</span></div><div class='line' id='LC36'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1"># into this object.</span></div><div class='line' id='LC37'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">lookup_obj</span> <span class="o">=</span> <span class="n">cls</span><span class="o">.</span><span class="n">find_by_id</span> <span class="nb">id</span></div><div class='line' id='LC38'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="ow">not</span> <span class="n">lookup_obj</span><span class="o">.</span><span class="n">nil?</span></div><div class='line' id='LC39'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">cls</span><span class="o">.</span><span class="n">name_for</span> <span class="nb">id</span><span class="p">,</span> <span class="n">lookup_obj</span><span class="o">.</span><span class="n">name</span></div><div class='line' id='LC40'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">cls</span><span class="o">.</span><span class="n">id_for</span> <span class="n">lookup_obj</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="nb">id</span>             </div><div class='line' id='LC41'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC42'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC43'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC44'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">value</span></div><div class='line' id='LC45'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC46'><br/></div><div class='line' id='LC47'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#...</span></div><div class='line' id='LC48'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC49'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1129101/9a4992ed95a4ca837daec1dc4c967f2175a54d04/gistfile1.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1129101#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a>
            <a href="https://gist.github.com/1129101">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>The important thing to note here is how we employ ActiveRecord&#8217;s read_attribute and write_attribute. The data in your ActiveRecord is maintained in a hash called attributes where the names of fields (in the DB) are saved along with their values. A classic setter method like `car.car_type = &#8220;Compact&#8221;` would set an attribute entry in the hash with :car_type =&gt; &#8220;Compact&#8221;, which will later cause SELECT or INSERT statements to try and access the in existing column car_type. Our approach is to intercept every time the &#8216;type&#8217; attribute is being written (with a String), and replace that String with a numerical ID (meanwhile creating the corresponding CarType entry if necessary).</p>
<p>Finally, prefill the caches from the DB when this class loads. This is optional but as the list of types is likely to be rather small, a real-time expanding cache is just wasting some user time and could be better done ahead.</p>
<div id="gist-1129105" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">def</span> <span class="nf">lookup</span><span class="p">(</span><span class="n">as_name</span><span class="p">)</span></div><div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">#...</span></div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">all_vals</span> <span class="o">=</span> <span class="n">cls</span><span class="o">.</span><span class="n">all</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">cls</span><span class="o">.</span><span class="n">class_variable_set</span><span class="p">(</span><span class="ss">:@@rcaches</span><span class="p">,</span> <span class="n">all_vals</span><span class="o">.</span><span class="n">inject</span><span class="p">({})</span> <span class="k">do</span> <span class="o">|</span><span class="n">r</span><span class="p">,</span> <span class="n">obj</span><span class="o">|</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">r</span><span class="o">[</span><span class="n">obj</span><span class="o">.</span><span class="n">name</span><span class="o">]</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="n">id</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">r</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span><span class="p">)</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">cls</span><span class="o">.</span><span class="n">class_variable_set</span><span class="p">(</span><span class="ss">:@@caches</span><span class="p">,</span> <span class="n">all_vals</span><span class="o">.</span><span class="n">inject</span><span class="p">(</span><span class="o">[]</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">r</span><span class="p">,</span> <span class="n">obj</span><span class="o">|</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">r</span><span class="o">[</span><span class="n">obj</span><span class="o">.</span><span class="n">id</span><span class="o">]</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="n">name</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">r</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span><span class="p">)</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1129105/9ec22b3b37c6e7e0bb4b0102d496f7639282b341/gistfile1.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1129105#file_gistfile1.rb" style="float:right;margin-right:10px;color:#666">gistfile1.rb</a>
            <a href="https://gist.github.com/1129105">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>That&#8217;s it. If you don&#8217;t like the caching this becomes even easier &#8211; remove all of the references to @@rcaches and @@caches and you simply saved yourself the trouble of manually maintaining CarType objects.</p>
<p>The only remaining thing is to define your migrations for creating the actual database tables. After all, that&#8217;s something you only want to do once and not every time this class loads, so this isn&#8217;t the place for it. However, it&#8217;s easy enough to create your own scaffolds so that a command like</p>
<p><code>rails generate migration create_car_type_lookup_for_car<br />
</code></p>
<p>will automatically create the migration. This is the required migration</p>
<div id="gist-1129113" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">class</span> <span class="nc">CreateCarTypeLookupForCar</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Migration</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">up</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">create_table</span> <span class="ss">:car_types</span> <span class="k">do</span> <span class="o">|</span><span class="n">t</span><span class="o">|</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">t</span><span class="o">.</span><span class="n">string</span> <span class="ss">:name</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">t</span><span class="o">.</span><span class="n">timestamps</span> <span class="c1">#Btw you can remove these, I don&#39;t much like them in type tables anyway</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC7'><br/></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">remove_column</span> <span class="ss">:cars</span><span class="p">,</span> <span class="ss">:type</span> <span class="c1">#Let&#39;s assume you have one of those now…</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">add_column</span> <span class="ss">:cars</span><span class="p">,</span> <span class="ss">:type</span><span class="p">,</span> <span class="ss">:integer</span> <span class="c1">#Maybe put not_null constraints here.</span></div><div class='line' id='LC10'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC11'><br/></div><div class='line' id='LC12'>&nbsp;&nbsp;<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">down</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">drop_table</span> <span class="ss">:car_types</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">remove_column</span> <span class="ss">:cars</span><span class="p">,</span> <span class="ss">:type</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">add_column</span> <span class="ss">:cars</span><span class="p">,</span> <span class="ss">:type</span><span class="p">,</span> <span class="ss">:string</span></div><div class='line' id='LC16'>&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC17'><span class="k">end</span></div></pre></div>
          </div>

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

<p>I&#8217;ll let you work out the details for actually migrating the data yourself &#8211; this post has already ran long enough. I urge you to read more in the gem&#8217;s source code <a href="https://github.com/Nimster/RailsLookup/blob/master/lib/active_record/lookup.rb">here</a>. There are some tricks I&#8217;ve omitted to make rails be able to support calls like Car.find_by_car_type_and_color &#8220;Compact&#8221;, :blue (when the actual SQL query should be asking about car_type_id = 1), and some more options for setting the lookup itself, handling Car.where(type: &#8220;Compact&#8221;) or multiple classes using a single lookup.</p>
<p>I hope this helped you and saved a lot of time and frustration. I&#8217;d like to thank Aviv for hosting me here. If you don&#8217;t already, read the rest of his blog, you&#8217;re sure to learn something useful! Follow me on twitter:<a href="http://twitter.com/nimrodpriell"> @nimrodpriell</a>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F08%2F09%2Fguest-post-lookup-tables-with-ruby-on-rails%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.codelord.net%2F2011%2F08%2F09%2Fguest-post-lookup-tables-with-ruby-on-rails%2F&amp;source=avivby&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6107bfac7c92ddff62b393d1e8b7abbe&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://www.codelord.net/2011/08/09/guest-post-lookup-tables-with-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

