<?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>Virtuous Code &#187; Uncategorized</title>
	<atom:link href="http://devblog.avdi.org/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://devblog.avdi.org</link>
	<description>&#34;The three virtues of a programmer: laziness, impatience, and hubris&#34; -- Larry Wall</description>
	<lastBuildDate>Sun, 19 May 2013 17:37:58 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Seeking a used MacBook for my mom</title>
		<link>http://devblog.avdi.org/2012/06/11/seeking-a-used-macbook-for-my-mom/</link>
		<comments>http://devblog.avdi.org/2012/06/11/seeking-a-used-macbook-for-my-mom/#comments</comments>
		<pubDate>Mon, 11 Jun 2012 13:00:36 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://devblog.avdi.org/?p=2459</guid>
		<description><![CDATA[My mom has been nursing along an iBook G4 for many years, but it is finally showing signs of giving up the ghost. She could really use a &#8220;new&#8221; (to her) MacBook. A little about my mom: she&#8217;s now in &#8230; <a href="http://devblog.avdi.org/2012/06/11/seeking-a-used-macbook-for-my-mom/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>My mom has been nursing along an <a href="http://en.wikipedia.org/wiki/IBook#iBook_G4_.28.22Snow.22.29">iBook G4</a> for many years, but it is finally showing signs of giving up the ghost. She could really use a &#8220;new&#8221; (to her) MacBook.</p>
<p>A little about my mom: she&#8217;s now in her fourth year &#8220;in exile&#8221;, living in New Jersey acting as a full-time caregiver for my grandparents (now just one grandparent). Her computer is pretty much her sole link to the wider world; whether it&#8217;s communicating with friends and family, staying way ahead of me (still!) in finding awesome new music, or, occasionally, <a href="http://cryptoromicon.posterous.com/">writing poignantly about caregiving and other topics</a>.</p>
<p>As you might imagine, hers is not a high-income line of work. Or any-income, really. So:</p>
<p>If someone out there happens to have an older model (but still functional) MacBook lying around collecting dust, and you&#8217;re willing to part with it for cheap or free, please get in touch. Thanks!</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2012/06/11/seeking-a-used-macbook-for-my-mom/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Should I rename my gem?</title>
		<link>http://devblog.avdi.org/2012/01/09/should-i-rename-my-gem/</link>
		<comments>http://devblog.avdi.org/2012/01/09/should-i-rename-my-gem/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 14:00:49 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1966</guid>
		<description><![CDATA[The Ruby community has some diversity challenges. I don&#8217;t think the Ruby community is any more biased than other tech communities; if anything, I think Rubyists are more apt to make a big deal over offensive content which would be considered business-as-usual &#8230; <a href="http://devblog.avdi.org/2012/01/09/should-i-rename-my-gem/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>The Ruby community has <a href="http://confreaks.net/videos/692-rubyconf2011-must-it-always-be-about-sex">some diversity challenges</a>. I don&#8217;t think the Ruby community is any <em>more</em> biased than other tech communities; if anything, I think Rubyists are <a href="http://blog.nicksieger.com/articles/2009/04/30/stand-and-be-counted">more apt to make a big deal</a> over offensive content which would be considered business-as-usual in much of the traditionally white-male-dominated tech industry. Which, ironically, may make us seem like a hotbed of scandal.</p>
<p>As a community we also like our colorful gem names. A little while back someone wrote a blog post about some of the more <a href="http://unethicalblogger.com/2011/11/13/ten-poorly-chosen-gem-names.html">questionable naming choices</a>. Which got me thinking about one of my own gems.</p>
<p>The gem in question is <a href="https://github.com/avdi/hookr">HookR</a>. It&#8217;s a library I wrote a few years ago for adding event hooks to arbitrary classes and objects.</p>
<p>The name amused me at the time. Actually, let&#8217;s be honest, the name <em>still </em>amuses me. But I&#8217;m also concerned it could be offensive. Not in an overt, groping-bottoms-at-a-conference kind of way, but in that insidious way that monocultures tend to be subtly threatening to outsiders without even realizing it.</p>
<p>As I personally read it, it is not gender-offensive since &#8220;hooker&#8221; is a gender-neutral term. However, it is potentially offensive to sex workers. And anyway, <a href="http://avdi.org/devblog/2009/04/30/rehabilitating-the-professional-rock-sta/">as I&#8217;ve noted before</a>, ultimately I&#8217;m not the one who gets to decide which of my statements are offensive.</p>
<p>So my question for you: is HookR an offensive name? I realize it&#8217;s an unconventional, non-enterprisey name; that much I&#8217;m OK with. But is it offensive? Is it amusing, or is it off-putting?</p>
<p>And if you do find it problematic: <strong>can you suggest a better name?</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2012/01/09/should-i-rename-my-gem/feed/</wfw:commentRss>
		<slash:comments>59</slash:comments>
		</item>
		<item>
		<title>Systems Programming in the Cloud</title>
		<link>http://devblog.avdi.org/2011/12/28/systems-programming-in-the-cloud/</link>
		<comments>http://devblog.avdi.org/2011/12/28/systems-programming-in-the-cloud/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 21:13:37 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1946</guid>
		<description><![CDATA[Tim Bray has an article up about static versus dynamic languages, and why he finds the static ones less annoying for Android programming than for web programming. It&#8217;s a good article. Something I&#8217;ve noticed over the past few years of &#8230; <a href="http://devblog.avdi.org/2011/12/28/systems-programming-in-the-cloud/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.tbray.org/ongoing/When/201x/2011/12/27/Type-Systems">Tim Bray has an article up about static versus dynamic languages</a>, and why he finds the static ones less annoying for Android programming than for web programming. It&#8217;s a good article.</p>
<p>Something I&#8217;ve noticed over the past few years of web programming is how it&#8217;s slowly becoming more like the systems/realtime/embedded programming I once did. Not exactly like it, but similar.</p>
<p>In the early days the difference was stark: as Tim points out, the stereotypical web app is an input/output machine. Requests go in, responses go out. Everything you do in a web app occurs somewhere in between receiving a lump of data and pushing out another lump of data. You don&#8217;t have to coordinate multiple threads; the app server does that for you. You don&#8217;t have to worry about race conditions; database transactions take care of that for you. It&#8217;s a black box: data goes in one end, different data goes out the other.</p>
<p>The big difference Tim sees between web programming and device programming is the number of APIs you typically have to deal with:</p>
<blockquote>
<ol style="margin-right: 40px; color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 21px; background-color: #ffffff; font-size: medium;" start="4">
<li style="margin-bottom: 0.5em; margin-top: 0.5em; margin-right: 0px; margin-left: 0px; font-family: ff-tisa-web-pro, serif;">Touch-screen in­ter­ac­tions.</li>
<li style="margin-bottom: 0.5em; margin-top: 0.5em; margin-right: 0px; margin-left: 0px; font-family: ff-tisa-web-pro, serif;">Tele­phony.</li>
<li style="margin-bottom: 0.5em; margin-top: 0.5em; margin-right: 0px; margin-left: 0px; font-family: ff-tisa-web-pro, serif;">More radio in­ter­faces, po­ten­tially: WiFi, NFC, and Blue­Tooth.</li>
<li style="margin-bottom: 0.5em; margin-top: 0.5em; margin-right: 0px; margin-left: 0px; font-family: ff-tisa-web-pro, serif;">A GPS and com­pass and maybe al­time­ter.</li>
<li style="margin-bottom: 0.5em; margin-top: 0.5em; margin-right: 0px; margin-left: 0px; font-family: ff-tisa-web-pro, serif;">Audio gear, in­clud­ing speak­ers and a mi­cro­phone.</li>
<li style="margin-bottom: 0.5em; margin-top: 0.5em; margin-right: 0px; margin-left: 0px; font-family: ff-tisa-web-pro, serif;">A cam­era, with a sen­sor and lots of con­trols.</li>
<li style="margin-bottom: 0.5em; margin-top: 0.5em; margin-right: 0px; margin-left: 0px; font-family: ff-tisa-web-pro, serif;">An ac­celerom­e­ter.</li>
<li style="margin-bottom: 0.5em; margin-top: 0.5em; margin-right: 0px; margin-left: 0px; font-family: ff-tisa-web-pro, serif;">Last but not least, a <a style="text-decoration: none; color: #aa0000;" href="http://developer.android.com/reference/android/os/Vibrator.html">vi­bra­tor</a>.</li>
</ol>
</blockquote>
<p>The thing is, web programming is starting to look more and more like this, as web programs become nodes in ever more complex constellations of services.</p>
<ol>
<li><span style="font-size: small;">Semi-smart clients which are asynchronously pulling data, or expecting you to push data, via Websockets and other technologies.</span></li>
<li><span style="font-size: small;">Multiple data stores (e.g. Postgresql and Redis) which may become inconsistent if you&#8217;re not careful.</span></li>
<li><span style="font-size: small;">A service for sending and receiving email.</span></li>
<li><span style="font-size: small;">A service for sending and receiving SMS messages, IMs, or voice calls.</span></li>
<li><span style="font-size: small;">Integration with a half-dozen social networks</span></li>
<li><span style="font-size: small;">Dedicated work queues for long-running operations</span></li>
</ol>
<p>And much like the many data busses embedded programs have to coordinate (RS-232! USB! Ethernet! <a style="line-height: 24px;" href="http://en.wikipedia.org/wiki/MIL-STD-1553">1553</a>!), often each of these external  services requires a slightly different kind of impedance-matching code in order to talk to it.</p>
<p>What&#8217;s especially reminiscent of  systems programming is that <em>any one of these services can fail</em>. In the primordial web app, a failure of the hardware hosting the app, or the database backing the app, is Not Your Problem. The request either works; or it has a software bug (which is your problem); or the platform fails (which is some poor overworked sysadmin&#8217;s problem). But when your app depends on a half a dozen services, any of which could crash, or get really slow, or go just plain wonky at any time, you have to start thinking about failure modes and exception safety and sanity checking and periodic self-tests.</p>
<p>I&#8217;m not sure if this new &#8220;cloud systems programming&#8221; will prompt a resurgence of interests in static languages. But I think it is causing a lot of programmers to rethink how web programs are designed. And a lot of the new thought is eerily familiar. For instance, a lot of web programmers appear to be rediscovering that <a href="http://en.wikipedia.org/wiki/Remote_procedure_call">RPC</a> is a terribly <a href="http://www.joelonsoftware.com/articles/LeakyAbstractions.html">leaky abstraction</a> whether done via UNIX domain sockets or HTTP, and why systems that exchange fire-and-forget messages are <a href="https://docs.google.com/viewer?url=http%3A%2F%2Fwww.cs.wustl.edu%2F~schmidt%2FPDF%2FC%2B%2B-report-col15.pdf">almost always preferable</a>.</p>
<p>On the whole, I&#8217;m excited about the challenges of heavily interconnected web applications. Yes, it brings with it a lot of the headaches I thought I&#8217;d left behind in the systems programming world. But these are interesting problems to solve. And there are few better feelings as a programmer than looking at a system happily humming away, knowing that inside there is an intricate dance going, dozens of inputs being handled and coordinated and dispatched, all according to your careful choreography.</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/12/28/systems-programming-in-the-cloud/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Starting Points for Pushing Async Notifications to Browsers</title>
		<link>http://devblog.avdi.org/2011/10/24/starting-points-for-pushing-async-notifications-to-browsers/</link>
		<comments>http://devblog.avdi.org/2011/10/24/starting-points-for-pushing-async-notifications-to-browsers/#comments</comments>
		<pubDate>Mon, 24 Oct 2011 13:00:00 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[asychronous]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[notifications]]></category>
		<category><![CDATA[push]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[websockets]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1887</guid>
		<description><![CDATA[I asked on Twitter for some starting points on pushing asynchronous notifications to web browsers. Here are the results, summarized. <a href="http://devblog.avdi.org/2011/10/24/starting-points-for-pushing-async-notifications-to-browsers/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I haven&#8217;t had the opportunity yet to work with an app which required asynchronous updates to be pushed &#8220;live&#8221; to clients. Friday a pair-programming client asked me about the subject, so I put the question out on Twitter. Here are the results, summarized.</p>
<p>Like I said I&#8217;m not experienced with this stuff, so this is just a collection of notes, not a recommendation.</p>
<ul>
<li>Lots of people pointed me to <a href="http://faye.jcoglan.com/">Faye</a>. From the home page:<br />
<blockquote><p>Faye is a publish-subscribe messaging system based on the Bayeux<br />
protocol. It provides message servers for Node.js and Ruby, and<br />
clients for use in Node and Ruby programs and in all major web<br />
browsers.</p></blockquote>
</li>
<li><a href="http://pusher.com/">Pusher</a> is a service I had already heard of, and it comes highly recommended from many sources. I know Larry Marburger uses it on <a href="http://getcloudapp.com/">CloudApp</a> and has nothing but good things to say about it.</li>
<li>Lots of mentions of <a href="https://github.com/maccman/juggernaut">Juggernaut</a>. From the website:<br />
<blockquote><p>Juggernaut gives you a realtime connection between your servers and<br />
client browsers. You can literally push data to clients using your<br />
web application, which lets you do awesome things like multiplayer<br />
gaming, chat, group collaboration and more.</p></blockquote>
</li>
<li>Several people mentioned <a href="http://www.pubnub.com/">PubNub</a>, which appears at first glance to be a similar service to Pusher.</li>
<li>In addition, lots of people replied with various combinations of lower-level tools and technologies, including: <a href="http://socket.io/">Socket.io</a>, <a href="http://postrank-labs.github.com/goliath/">Goliath</a>, <a href="http://dev.w3.org/html5/websockets/">WebSockets</a>, and <a href="http://rubyeventmachine.com/">EventMachine</a>.</li>
<li>EDIT: A couple people have also pointed out that T<a href="http://torquebox.org/2x/builds/html-docs/websockets.html">orqueBox provides built-in WebSockets</a> support.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/10/24/starting-points-for-pushing-async-notifications-to-browsers/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>SBPP #2: Smalltalk Patterns in Ruby</title>
		<link>http://devblog.avdi.org/2011/09/22/sbpp-2-smalltalk-patterns-in-ruby/</link>
		<comments>http://devblog.avdi.org/2011/09/22/sbpp-2-smalltalk-patterns-in-ruby/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 15:35:14 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Smalltalk Best Practice Patterns]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[smalltalk]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1696</guid>
		<description><![CDATA[Smalltalk Best Practice Patterns continues from the introduction with a brief explanation of patterns. Some notable quotes: About leveraging commonality: &#8220;large-scale software re-use has not proven to be the answer&#8221;. A lot of the mid-90s OO PR centered around the &#8230; <a href="http://devblog.avdi.org/2011/09/22/sbpp-2-smalltalk-patterns-in-ruby/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.amazon.com/Smalltalk-Best-Practice-Patterns-Kent/dp/013476904X%3FSubscriptionId%3DAKIAIRXKO4LLU2ACVMRQ%26tag%3Dthlafa-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D013476904X">Smalltalk Best Practice Patterns</a> continues from the introduction with a brief explanation of patterns. Some notable quotes:</p>
<ul>
<li>About leveraging commonality: &#8220;large-scale software re-use has not proven to be the answer&#8221;. A lot of the mid-90s OO PR centered around the idea that we&#8217;d all build our apps out of reusable off-the-shelf objects. As Beck notes, this didn&#8217;t really pan out. With rare exceptions, in-process software re-use still takes the form it always did: it happens at the &#8220;library&#8221; level of granularity, not at the object level. Patterns have been a much more successful way to re-use ideas.</li>
<li>&#8220;By carrying along their justification, patterns avoid the problem of most &#8220;style guides&#8221; that simply prescribe solutions without discussing why or when the solution is appropriate&#8221;.  Ironically, I often hear the criticism that patterns are &#8220;prescriptive, one-size-fits-all solutions&#8221;. When I hear this it makes me wonder if the person saying it has read a patterns book lately. Central to the form is a careful discussion of when the pattern makes sense, and when it doesn&#8217;t.</li>
</ul>
<p>Once I got into the meat of the book I decided that, since I&#8217;m reading it for the <a href="http://rubyrogues.com/">Ruby Rogues</a> book club, I should probably take a stab at translating the patterns to Ruby. You are welcome to follow my progress on GitHub:  <a href="https://github.com/avdi/sbpprb">https://github.com/avdi/sbpprb</a>. Also, feel free to fork and submit pull requests for alternate translations. There is definitely room for interpretation on some of these.</p>
<ul>
<li>On <strong>Composed Method,</strong> this bit is key: &#8221;keep all operations in a method at the same level of abstraction&#8221;. I hate it when I find a system that has been broken up into small methods&#8212;except that the small methods still combine high-level calls with fiddly, low-level code. Code like this has all the disadvantages of small methods (harder to follow the logic) with none of the advantages (only having to introduce a change in one place).</li>
<li>There are a number of construction &amp; coercion patterns early in the book. One thought that sprung out to me in reading these is that I don&#8217;t spend enough time thinking about writing alternatives to &#8220;.new&#8221; in Ruby code. More often, I just write a fancy &#8220;#initialize&#8221; which can handle various combinations of arguments. But there&#8217;s a good argument to be made in many classes for avoiding .new and instead defining more specific forms, e.g. Point.new_from_coords, Point.new_from_polar.</li>
<li>That last point is relevant to Rails code. A lot of the specialized factory methods I see for testing (&#8220;Factory.create(:admin_user)&#8221;) really ought to have analogs on the original model (User.new_admin).</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/09/22/sbpp-2-smalltalk-patterns-in-ruby/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>SBPP #1: Introduction</title>
		<link>http://devblog.avdi.org/2011/09/20/sbpp-1-introduction/</link>
		<comments>http://devblog.avdi.org/2011/09/20/sbpp-1-introduction/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 13:00:11 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Smalltalk Best Practice Patterns]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[smalltalk]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1693</guid>
		<description><![CDATA[The Ruby Rogues are reading Smalltalk Best Practice Patterns for next month&#8217;s book club, so I finally got around to ordering a copy. It&#8217;s high time, considering that in my experience it&#8217;s one of the most consistently recommended programming books &#8230; <a href="http://devblog.avdi.org/2011/09/20/sbpp-1-introduction/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>The <a href="http://rubyrogues.com/">Ruby Rogues</a> are reading <a href="http://www.amazon.com/Smalltalk-Best-Practice-Patterns-Kent/dp/013476904X%3FSubscriptionId%3DAKIAIRXKO4LLU2ACVMRQ%26tag%3Dthlafa-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D013476904X">Smalltalk Best Practice Patterns</a> for next month&#8217;s book club, so I finally got around to ordering a copy. It&#8217;s high time, considering that in my experience it&#8217;s one of the most consistently recommended programming books in print.</p>
<p>Some notes and quotes from the introduction:</p>
<ul>
<li>Defining patterns: &#8220;a pattern is a decision an expert makes over and over&#8221;.</li>
<li>Patterns in the small: &#8220;I&#8217;m constantly amazed at how even a little help cleaning up small problems reveals the source and solution of much bigger problems&#8221;.</li>
<li>&#8220;It is easy to get numbed to pain and frustration, or treat it as if is part of the territory&#8221;&#8212;this dovetails with a realization I had recently: my &#8220;Confident Code&#8221; talk, at its core, isn&#8217;t about clean code; it&#8217;s about <em>joy</em>. Programming in a conducive programming language should be pleasant. Fun. Joyful, even. Antipatterns steal joy because they add weight to every step. It&#8217;s worthwhile to periodically remember the joy of that first &#8220;a-ha!&#8221; moment in Ruby (or Smalltalk, or whatever), and figure out if and why we aren&#8217;t feeling that way anymore.</li>
<li>&#8220;The very act of deciding what corners to cut slows down development. Using these patterns lets you program flat out, applying patterns as fast as your fingers will go, and get results as quickly as possible&#8221;. Beck goes on to say of adopting these patterns &#8220;whole hog&#8221;: &#8220;&#8230;I spent a couple of frustrating weeks programming at less than full speed. After that, I memorized enough patterns to get back up to my old productivity, but the code I was producing was cleaner than before. After a couple more weeks, I no longer had to look up any patterns, and my productivity shot up while my code kept getting cleaner and cleaner.&#8221;</li>
</ul>
<p>This last quote nicely sums up an observation I&#8217;ve made over the years. A lot of programmers, when evaluating a new discipline, note (correctly) that adopting it will slow them down in the short term. They then extrapolate from this short-term slowdown that it will <em>always </em>slow them down, and is therefore a waste of time.</p>
<p>Maybe it&#8217;s just good &#8216;ole hacker hubris: the assumption that we can fully assimilate any new knowledge in a matter of hours, and if not, it&#8217;s not worth learning. In any case, it&#8217;s a flawed mental model. New disciplines, when practiced diligently, eventually become automatic.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/09/20/sbpp-1-introduction/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>What do you want to know about OOP and Rails?</title>
		<link>http://devblog.avdi.org/2011/09/12/what-do-you-want-to-know-about-oop-and-rails/</link>
		<comments>http://devblog.avdi.org/2011/09/12/what-do-you-want-to-know-about-oop-and-rails/#comments</comments>
		<pubDate>Mon, 12 Sep 2011 15:58:45 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1674</guid>
		<description><![CDATA[For a long time I&#8217;ve had the idea in my head of doing a Rails app-building walkthrough that emphasizes classic Object Oriented Programming techniques. For instance, building out domain models as regular ole&#8217; objects, and then adding persistence in as &#8230; <a href="http://devblog.avdi.org/2011/09/12/what-do-you-want-to-know-about-oop-and-rails/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>For a long time I&#8217;ve had the idea in my head of doing a Rails app-building walkthrough that emphasizes classic Object Oriented Programming techniques. For instance, building out domain models as regular ole&#8217; objects, and then adding persistence in as an implementation detail later on.</p>
<p>Over the weekend I started writing it. I thought it was just going to be a sort of maxi-article, but I&#8217;m at 37 pages and I&#8217;m only 2/3 done at best. So far I&#8217;ve covered stuff like adding ActiveModel bits as-needed, Dependency Injection, and the Presenter pattern, but I&#8217;m sure there&#8217;s stuff I&#8217;ve missed. So I thought that while I&#8217;m in the process of brain-dumping all of this stuff I might as well open up the floor.</p>
<p>SO! What would you like to know about OOP on Rails?</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/09/12/what-do-you-want-to-know-about-oop-and-rails/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Making a Mockery of TDD</title>
		<link>http://devblog.avdi.org/2011/09/06/making-a-mockery-of-tdd/</link>
		<comments>http://devblog.avdi.org/2011/09/06/making-a-mockery-of-tdd/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 12:30:40 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[bdd]]></category>
		<category><![CDATA[Behavior Driven Development]]></category>
		<category><![CDATA[Code smell]]></category>
		<category><![CDATA[law of demeter]]></category>
		<category><![CDATA[mock-objects]]></category>
		<category><![CDATA[stub objects]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[test doubles]]></category>
		<category><![CDATA[Test-driven development]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[Unit Tests]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/?p=1644</guid>
		<description><![CDATA[I made this gnomic remark on Twitter the other day: To be a successful mockist, you must dislike mocks. A lot of people re-tweeted it, so I guess I&#8217;m not completely alone in thinking this way. I should back up &#8230; <a href="http://devblog.avdi.org/2011/09/06/making-a-mockery-of-tdd/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I made this gnomic remark on Twitter the other day:</p>
<p><strong>To be a successful mockist, you must dislike mocks.</strong></p>
<p>A lot of people re-tweeted it, so I guess I&#8217;m not completely alone in thinking this way.</p>
<p>I should back up a bit. A &#8220;mock object&#8221;, or &#8220;mock&#8221;, is a specific kind of test double. It is an object used in a Unit Test which stands in for another object, and carries certain expectations about how what methods will be called, and how they will be called. If the expectations are not met, the test fails. By contrast, other test doubles, such as <em>stubs objects</em>, make no assertions about which methods will be called. This article is specifically about mock objects and mocked methods, which make an assertion about when, how many times, and with what arguments certain collaborator methods will be called.</p>
<p>The term &#8220;Mockist&#8221; refers to those programmers who use mock objects in their unit tests. There is another camp of programmers, called &#8220;Classicist&#8221; by Martin Fowler, who eschew mock objects entirely in their tests.</p>
<p>Actually, if you haven&#8217;t read <a href="http://martinfowler.com/articles/mocksArentStubs.html">Fowler&#8217;s article on the &#8220;mockist&#8221;/&#8221;classicist&#8221; divide</a>, go read it and then come back. There&#8217;s really no point in reading this post any further unless you have that as background. Fowler&#8217;s article is an excellent breakdown of the origin of the two camps, as well as a pretty objective evaluation of the pros and cons of both approaches to writing unit tests. Seriously, <a href="http://martinfowler.com/articles/mocksArentStubs.html">go read it right now</a>.</p>
<p>I&#8217;m a Mockist. I write tests that make assertions about object interactions, not just about static outcomes. I&#8217;ve been doing it for a while, and I&#8217;m pretty happy with the results.</p>
<p>However, it&#8217;s a technique that&#8217;s very easy misuse. Applied poorly, it can lead to testing suites which are so brittle they have to be either extensively rewritten or thrown out entirely when it comes time to change functionality or re-architect the code.</p>
<h3><strong>Mock Objects are a Test Smell</strong></h3>
<p>When I realize that I&#8217;m using a mock where I shouldn&#8217;t be, it&#8217;s often because I haven&#8217;t spent enough time on my test tooling, and as a result I don&#8217;t have a good way to make assertions about method output.</p>
<p>For instance, the other day I was building a Presenter for some Rails code. The presenter held references to both a domain model object (an ActiveRecord instance) and the Rails &#8220;template&#8221; object which makes various HTML-building methods available. The presenter&#8217;s job was to take model data and format it for display.</p>
<p>One of the first tests I wrote went something like this:</p>
<script src="https://gist.github.com/1195772.js?file=badmock.rb"></script><noscript><pre><code class="language-ruby ruby">it &quot;should generate a button&quot; do
  template.should_receive(:button_to).with(&quot;Vote&quot;).
    and_return(&quot;THE_HTML&quot;)
  subject.render_controls.should be == &quot;THE_HTML&quot;
end</code></pre></noscript>
<p>This test asserts that the presenter will call the button_to helper to generate some HTML.</p>
<p>I&#8217;ve been making an effort to write isolated tests which can be run without loading the full Rails infrastructure. This test completely isolates the presenter functionality from that of its collaborators. It doesn&#8217;t require any actual HTML to be generated, it just asserts that the presenter must use the button_to method and return the result.</p>
<p>The test felt <em>wrong </em>as soon as I wrote it. It was clearly brittle. I could look ahead and imagine, as the requirements for the HTML became more complex, how the mock object would have to grow more and more mock methods in order to keep up. The tests would become, in effect, an exact replica of the method implementation.</p>
<p>I decided to change up my spec setup a bit in order to pass in a template object which included the actual Rails tag helpers. Then I included the Capybara spec matchers for making assertions about HTML. In the end, the spec looked like this:</p>
<script src="https://gist.github.com/1195772.js?file=have_button.rb"></script><noscript><pre><code class="language-ruby ruby">it &quot;should render a vote button&quot; do
  subject.render_controls.should have_button('Vote')
end
</code></pre></noscript>
<p>The test is slightly less isolated now, but for a class which is all about generating strings, I think this style of test more suitable. Note that what I didn&#8217;t do was graduate the tests to the level of an integration or acceptance test. Instead, I added the minimum coupling necessary to get rid of the suspect mock object.</p>
<p>In my experience, well-isolated tests lead to neatly decoupled code. Not to mention that they run really fast. Rather than tie my presenter tests to the entire Rails stack, I let the mock object pain guide me to the one area where a little relaxation in my isolation discipline would lead to a big gain in productivity.</p>
<h3>Mock Objects are a Code Smell</h3>
<p>In the preceding case, the mock object was a test smell. But mock objects are more often smelly because they are telling you something about the system under test.</p>
<p>A <a href="http://c2.com/xp/CodeSmell.html">Code Smell</a> is defined as &#8220;<em>a hint that something has gone wrong somewhere in your code&#8221;</em>. A hint, not a certainty. Whenever I use a mock object to assert that a certain method call must be made, a little voice in my head says &#8220;should I really be using a mock object here?&#8221;. When a test has more than one or two mocked method calls, that little voice gets a lot bigger.</p>
<p>In my experience, multiple mocked methods often indicate that either a) the method being tested is trying to do too much; or b) the method being tested has high structural coupling. As I wrote in <a href="http://avdi.org/devblog/2011/04/07/rspec-is-for-the-literate/">another testing article</a>, mocks are like the hydrogen peroxide of programming. They &#8220;fizz up&#8221; when they encounter highly-coupled code. Show me a test with a lot of mocked method calls, and I&#8217;ll show you a class under test which violates the <a href="http://avdi.org/devblog/2011/07/05/demeter-its-not-just-a-good-idea-its-the-law/">law of Demeter</a>. And which is, consequently, a liability to future code changes.</p>
<p>Mocks act as a canary in coal mine: they are an early warning system that your code is beginning to depart from the path of small methods, each having a single responsibility, and each interacting with a very small set of collaborators.</p>
<h3>Mock objects are for Design</h3>
<p>Which brings me to my next point about using mock objects: mock objects are all about design. They were developed hand-in-hand with the &#8220;Behavior Driven Development&#8221; movement, which sought to re-emphasise the design component of TDD. Here are the inventors of mock objects, talking about them in the intro to an <a href="http://static.mockobjects.com/files/mockrolesnotobjects.pdf">OOPSLA 2004 paper on using mocks</a>:</p>
<blockquote><p>Mock Objects is an extension to Test-Driven Development that supports good Object-Oriented design by guiding the discovery of a coherent system of types within a code base. It turns out to be less interesting as a technique for isolating tests from third-party libraries than is widely thought.</p></blockquote>
<p>Guiding design isn&#8217;t just a side-benefit of using mocks; it&#8217;s the <em>primary reason to use them</em>.</p>
<p>Which means that if you aren&#8217;t using tests to drive your design, there&#8217;s little point to using mock objects.  I suspect this is the root of a lot of the the arguments over whether to use mocks or not; if your primary reason for writing unit tests is verification and avoiding regressions, mock objects aren&#8217;t going to buy you much. And people talking about how useful they are aren&#8217;t going to make a lot of sense.</p>
<p>Mock objects also make more sense in an <em>outside-in</em> model of test-driven development. They enable developers to ferret out the needed interfaces of objects that don&#8217;t exist yet. Many if not most of the mocks I write are mocks of classes and methods I have yet to write. The mocks I write while TDDing one layer of the design gives me the clues I need to work out the necessary responsibilities of the next layer down.</p>
<p>(By the way, that OOPSLA paper is full of good advice on how to use mock objects without shooting yourself in the foot. <a href="http://static.mockobjects.com/files/mockrolesnotobjects.pdf">The whole thing</a> is worth reading)</p>
<h3>Mock objects are for Commands</h3>
<p>This is a distinction that is just starting to become clear to me. You may be familiar with notion of  &#8221;<a href="http://martinfowler.com/bliki/CommandQuerySeparation.html">command/query separation</a>&#8220;. This is when you make an effort to divide all methods into either <em>command</em> or <em>query</em> methods. Command methods cause something to change, either internally or externally to the receiver, and return no value. Conversely, query methods change nothing, (i.e. they have no side-effects), and are used solely for their return values.</p>
<p>As a general rule, I think mock objects are mainly useful when describing command methods. Their use is suspect for testing query methods. As a corollary to this observation, mocked methods with defined return values are often (though not always) a warning sign. I find most of my test doubles fall into one of two categories: stubs with no behavior, just a return value; and mocks that expect a certain method call, but define no return value (no &#8216;and_return()&#8217;, in RSpec terms).</p>
<p>This distinction has the side effect of encouraging you, as a user of mock objects, towards a design that has a strong delineation between queries and commands. This is widely regarded in OO circles as a Good Thing.</p>
<p><span style="font-size: 15px; font-weight: bold;">Conclusion</span></p>
<p>This has been a brain dump of some of my current thinking on mock objects. As such, it&#8217;s probably not as clear or well organized as it could be. To sum up: mock objects are helpful, but they are as often useful for drawing attention to problematic tests and code as they are for specifying object interactions. Mock objects are only a meaningful exercise when tests are being used to drive design. And finally, mock objects tend to make the most sense when specifying pure command methods.</p>
<p>I hope you find some of these observations helpful in your own TDD practice.</p>
<div class="zemanta-pixie" style="margin-top: 10px; height: 15px;"><a class="zemanta-pixie-a" title="Enhanced by Zemanta" href="http://www.zemanta.com/"><img class="zemanta-pixie-img" style="border: none; float: right;" src="http://img.zemanta.com/zemified_e.png?x-id=9b52b287-2e6f-4f38-8e81-bb7d24014416" alt="Enhanced by Zemanta" /></a></div>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/09/06/making-a-mockery-of-tdd/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Using CapsLock to Trigger Ubuntu Unity</title>
		<link>http://devblog.avdi.org/2011/06/05/using-capslock-to-trigger-ubuntu-unity/</link>
		<comments>http://devblog.avdi.org/2011/06/05/using-capslock-to-trigger-ubuntu-unity/#comments</comments>
		<pubDate>Sun, 05 Jun 2011 17:30:15 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://virtuouscode.com/?p=1275</guid>
		<description><![CDATA[]]></description>
				<content:encoded><![CDATA[<p><script type='text/javascript' src='http://content.bitsontherun.com/players/oF1smCDn-uGtfOrbJ.js'></script></p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/06/05/using-capslock-to-trigger-ubuntu-unity/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Linkdump #2</title>
		<link>http://devblog.avdi.org/2011/02/02/linkdump-2/</link>
		<comments>http://devblog.avdi.org/2011/02/02/linkdump-2/#comments</comments>
		<pubDate>Wed, 02 Feb 2011 15:35:58 +0000</pubDate>
		<dc:creator>Avdi Grimm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://avdi.org/devblog/2011/02/02/linkdump-2/</guid>
		<description><![CDATA[Designing for scalability &#124; Merbist Terrific post on the elements that go into a scalable design. tags: development design ruby rails scalability api Every single class, method, function you write is an API that you and others will use. Remember &#8230; <a href="http://devblog.avdi.org/2011/02/02/linkdump-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<ul class="diigo-linkroll">
<li>
<p class="diigo-link"><a href="http://merbist.com/2011/01/31/designing-for-scalability/comment-page-1/#comment-1963">Designing for scalability | Merbist</a></p>
<p class="diigo-description">Terrific post on the elements that go into a scalable design.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/design">design</a>             <a href="http://www.diigo.com/user/avdigrimm/ruby">ruby</a>             <a href="http://www.diigo.com/user/avdigrimm/rails">rails</a>             <a href="http://www.diigo.com/user/avdigrimm/scalability">scalability</a>             <a href="http://www.diigo.com/user/avdigrimm/api">api</a></p>
<ul class="diigo-annotations">
<li>
<div class="diigoContent">
<div class="diigoContentInner">Every single class, method, function you write is an API that you and others will use. Remember that every time you write code, you are the implementer of a design, and therefore you are a designer.</div>
</p></div>
</li>
</ul>
</li>
<li>
<p class="diigo-link"><a href="http://timeless.judofyr.net/on-camping-vs-sinatra">On Camping vs Sinatra &mdash; Timeless</a></p>
<p class="diigo-description">Not only does Mr. Holm make a convincing case for taking another look at Camping, but the article itself is a rather clever bit of Ruby code. Very well played indeed.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/ruby">ruby</a>             <a href="http://www.diigo.com/user/avdigrimm/sinatra">sinatra</a>             <a href="http://www.diigo.com/user/avdigrimm/camping">camping</a>             <a href="http://www.diigo.com/user/avdigrimm/development">development</a></p>
<ul class="diigo-annotations">
<li>
<div class="diigoContent">
<div class="diigoContentInner">Please don&rsquo;t mistake me, this is not <strong><em>SIX (UNIMPRESSIVE) REASONS CAMPING IS BETTER THAN SINATRA</em></strong> or even <strong><em>SIX (UNIMPRESSIVE) REASONS YOU SHOULD DROP EVERYTHING YOU HAVE IN YOUR HAND RIGHT NOW AND START USING CAMPING</em></strong>. All I&rsquo;m saying is that Camping gets so many things <em>right</em>. Not necessarily in very few lines of code or very fast, but nonetheless: I look at Camping code and nod to myself: &ldquo;Yeah, this is probably the <em>correct</em> way to do it&rdquo;.</div>
</p></div>
</li>
</ul>
</li>
<li>
<p class="diigo-link"><a href="http://railstips.org/blog/archives/2011/01/27/data-modeling-in-performant-systems/?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+railstips+%28Rails+Tips%29">Data Modeling in Performant Systems</a></p>
<p class="diigo-description">I&#8217;m probably missing something but by my count this is the second time John has reinvented DataMapper.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/ruby">ruby</a>             <a href="http://www.diigo.com/user/avdigrimm/database">database</a>             <a href="http://www.diigo.com/user/avdigrimm/data">data</a></p>
<ul class="diigo-annotations">
<li>
<div class="diigoContent">
<div class="diigoContentInner">
<ul>
<p>What all does Toy::Store come with out of the box? So glad you asked.</p>
</ul>
<ul>
<li><strong>Attributes</strong> &ndash; attribute :name, String (or some other type) Can be virtual which works just like attr_accessor but all the power of dirty tracking, serialization, etc. Also, can be abbreviated which means :first_name could be the method you use, but in the data store the attribute is :fn. Save those bytes! Allows for default values and defaults can be procs.</li>
<li><strong>Typecasting</strong> &ndash; Same type system as MongoMapper. One day they will share the exact same type system in its own gem, for now duplicated.</li>
<li><strong>Callbacks</strong> &ndash; all the usual suspects.</li>
<li><strong>Dirty Tracking</strong> &ndash; save, create, update, destroy</li>
<li><strong>Mass assignment security</strong> &ndash; attr_accessible and attr_protected</li>
<li><strong>Proper cloning</strong></li>
<li><strong>Lists</strong> &ndash; arrays of ids. If user has many games, user would have list :games which stores in game_ids key on user and works just like an association.</li>
<li><strong>Embedded Lists</strong> &ndash; array of hashes. More consistent than MongoMapper, which will soon reap the benefits of the work on Toy Store embedded lists.</li>
<li><strong>References</strong> &ndash; think belongs_to by a different (better?) name. Post model could reference :creator, User to add creator_id key and relate creator to post.</li>
<li><strong>Identity Map</strong> &ndash; On by default. Should be thread-safe.</li>
<li><strong>Read/write through caching</strong> &ndash; If you specific a cache adapter (say memcached), ToyStore will write to memcached first and read from memcached first, populating the cache if it was not present.</li>
<li><strong>Indexing</strong> &ndash; Need to do lookups by email? index :email and whenever a user is saved the user data is written to one key and the email is written as another key with a value of the user id.</li>
<li><strong>Logging</strong></li>
<li><strong>Serialization</strong> (<span class="caps">XML</span> and <span class="caps">JSON</span>)</li>
<li><strong>Validations</strong></li>
<li><strong>Primary key factories</strong></li>
</ul></div>
</div>
</li>
</ul>
</li>
</ul>
<li>
<p class="diigo-link"><a href="http://netbeans.org/community/news/show/1507.html">NetBeans Community News</a></p>
<p class="diigo-description">Boy, Oracle&#8217;s just batting 1000 these days.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/ruby">ruby</a>             <a href="http://www.diigo.com/user/avdigrimm/oracle">oracle</a>             <a href="http://www.diigo.com/user/avdigrimm/java">java</a>             <a href="http://www.diigo.com/user/avdigrimm/netbeans">netbeans</a>             <a href="http://www.diigo.com/user/avdigrimm/development">development</a></p>
<ul class="diigo-annotations">
<li>
<div class="diigoContent">
<div class="diigoContentInner">After thorough consideration, we have taken the difficult step to discontinue support for Ruby on Rails in the NetBeans IDE.</div>
</p></div>
</li>
</ul>
</li>
<li>
<p class="diigo-link"><a href="https://github.com/michaeldv/awesome_print">michaeldv/awesome_print &#8211; GitHub</a></p>
<p class="diigo-description">Ruby object pretty-printer.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/ruby">ruby</a>             <a href="http://www.diigo.com/user/avdigrimm/console">console</a>             <a href="http://www.diigo.com/user/avdigrimm/irb">irb</a>             <a href="http://www.diigo.com/user/avdigrimm/development">development</a></p>
</li>
<li>
<p class="diigo-link"><a href="http://www.drdobbs.com/architecture-and-design/229000996;jsessionid=44PPL3XDNDZMJQE1GHPSKHWATMY32JVN?pgno=2">Dr Dobbs &#8211; Certified ScrumMaster Examined</a></p>
<p class="diigo-description">Scott Ambler tears into Scrum Master certifications.</p>
<p class="diigo-tags"><span>tags:</span>                        <a href="http://www.diigo.com/user/avdigrimm/agile">agile</a>             <a href="http://www.diigo.com/user/avdigrimm/development">development</a>             <a href="http://www.diigo.com/user/avdigrimm/scrum">scrum</a></p>
<ul class="diigo-annotations">
<li>
<div class="diigoContent">
<div class="diigoContentInner">I&rsquo;ve said it before and I&rsquo;ll say it again &mdash; The Scrum community, and to a lesser extent the agile community in general, has embarrassed itself by tolerating the CSM scheme. Enough is enough. We can do better, and until we do so, our integrity debt continues to grow.</div>
</p></div>
</li>
</ul>
</li>
<p class="diigo-ps">Posted from <a href="http://www.diigo.com">Diigo</a>. The rest of my favorite links are <a href="http://www.diigo.com/user/avdigrimm">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://devblog.avdi.org/2011/02/02/linkdump-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
