<?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>Theodicius</title>
	<atom:link href="http://www.theodicius.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.theodicius.net</link>
	<description>Good. Evil. Bratwurst.</description>
	<lastBuildDate>Sat, 29 Dec 2012 22:21:29 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>My 15 Minutes</title>
		<link>http://www.theodicius.net/archives/2012/12/29/my-15-minutes/</link>
		<comments>http://www.theodicius.net/archives/2012/12/29/my-15-minutes/#comments</comments>
		<pubDate>Sat, 29 Dec 2012 22:21:29 +0000</pubDate>
		<dc:creator>arlen</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.theodicius.net/?p=552</guid>
		<description><![CDATA[So, my guest shot on Ruby Rogues is now in the can. I didn&#8217;t do as well as I would have liked. Was it nerves, or the 100-degree fever I was running at the time? More than likely it was that I simply prepared for the wrong discussion. It&#8217;s nobody&#8217;s fault but my own; it&#8217;s [...]]]></description>
				<content:encoded><![CDATA[<p>So, my guest shot on <a href="http://rubyrogues.com">Ruby Rogues</a> is now in the can. I didn&#8217;t do as well as I would have liked. Was it nerves, or the 100-degree fever I was running at the time? More than likely it was that I simply prepared for the wrong discussion.</p>
<p>It&#8217;s nobody&#8217;s fault but my own; it&#8217;s a wide topic and the narrow bit I wanted to talk about soon was left behind as wider topics aired, and the discussion ranged farther afield than I had prepared data for. Mea Culpa. I did a bad job of preparing myself to guest. It happens. It will be neither the first nor the last mistake I make. (At least I hope it&#8217;s not my last; the day I make my last mistake will be the day I die.) You learn from it and move on.<br />
<span id="more-552"></span><br />
As this whole thing started with <a href="http://www.theodicius.net/archives/2012/10/13/on-chess-and-software-development/">me shooting my mouth off,</a> I&#8217;ll bring it back here, in a format I&#8217;m comfortable with and with a head not so encumbered with medication.</p>
<p>There&#8217;s a problem in our industry that we all have horror stories about, but we seem to be treating it as if it&#8217;s incurable. And I find that puzzling. Most developers I know got into the field because they loved solving problems. And here&#8217;s a problem. Yet we&#8217;re acting as if it weren&#8217;t possible to solve it?</p>
<p>I can&#8217;t accept that. And that&#8217;s where I was coming from. We have loads of people who come into our field on their own. They start learning on their own. They code, and they repeat the mistakes that have been made (and solved) decades ago. And there&#8217;s a very real and very strong faction in the industry that claims this is As It Should Be.</p>
<p>Bollocks. That is a large steaming pile of male bovine excrement. That is nothing more than the return of the &#8220;priesthood&#8221; mentality I fought to get away from in the 70&#8242;s and 80&#8242;s, the idea that programming is a form of magic, and you must endure your initiation rituals through the Hazings of Non-Scalability and Tight Coupling (et al.) before you are worthy to enter into the Holy Hall Of Patterns. It isn&#8217;t worthy of us.</p>
<p>I might have sounded a bit flippant there, but I was serious. If we know something is a problem, and we know ways of thinking that can avoid it, and we hold that information back because the developer in training hasn&#8217;t &#8220;felt the pain&#8221; yet, aren&#8217;t we doing a form of hazing &#8212; intentionally making someone suffer before deigning to let them join our ranks? The road to advancement is hard enough, there&#8217;s no need to artificially increase the difficulty.</p>
<p>First, we need to put to a final bloody death the damaging notion that one &#8220;cannot begin to understand&#8221;  a concept until one has &#8220;personally experienced the pain&#8221; of doing without it. We all have learned far more from the vicarious experience of others than from our own. If I started up a table saw in front of you, I daresay the vast majority of you who did not stick your hand in the blade had never done so in the past. Yet you still learned not to. How about electricity? I suspect far more of you would work very hard to avoid being in a house without electricity for a week of a Wisconsin winter than actually have experienced it. You know it&#8217;s something to avoid, even though you haven&#8217;t personally experienced it.</p>
<p>No other field of human endeavor seems to suffer from this sort of hubris, that we start as tabula rasa and may only write what we directly experience. A bricklayer doesn&#8217;t demand his apprentices lay brick badly before showing them the right way to do it. A plumber teaches her apprentice the right way to do it first, and then checks their work to ensure they did it the way she taught them.</p>
<p>So if other fields don&#8217;t work this way, obviously the problem isn&#8217;t either incurable nor inevitable. It&#8217;s cheap and easy to say programmers all have this or that personality quirk; I just don&#8217;t think it&#8217;s either valid or useful. I&#8217;ve spent 45 years hearing the same drivel spouted about science fiction fans, and I know first hand it isn&#8217;t true there, either. Pull the other one.</p>
<p>So how do other fields allow self-starters and self-learners to &#8220;get up to speed&#8221; in their fields? By preserving, not ignoring, the past. Craftsmen through the ages looked at the work of those that went before them, saw what they did good, and what they didn&#8217;t. And passed those judgements on. And we don&#8217;t.</p>
<p>I joked the primary function of a junior developer is to write bad code. That isn&#8217;t to say the senior developer never writes bad code, but rather that along the road from junior to senior you (hopefully) learn to write <strong>less</strong> bad code.</p>
<p>It would not surprise me if it were true that every system of any significance ever written contains bad code. But what would absolutely astonish me would be if no system of any significance ever written contains good code. There are plenty of examples, I am sure, of cute ideas coded clearly and used well.</p>
<p>Where we (I include myself in this) have failed is we haven&#8217;t called them out. In every other field of literature there are known established examples of excellence that the neophyte can study to learn how to practice their craft better. Writers get not only books about writing, but they get reading lists of great examples of How It Is Done. We leave it up to the beginners to make their choices about what code to read; how can we claim to be surprised by what comes of that?</p>
<p>It&#8217;s the same in chess. We have a saying in chess education: &#8220;Study The Classics.&#8221; Not only are there treatises on the game, or specific phases of it. There are game collections. Beyond that, there are acknowledged masterpieces. You could show a top player today a position from a significant game of a century ago, and they could quote the rest of the game to you, and probably show you two or three similar examples.</p>
<p>But in the world of software development, we have treatises that can be considered &#8220;classics&#8221; (often with names like Robert Martin, Kent Beck, Martin Fowler or Michael Feathers attached) but we haven&#8217;t compiled (you should excuse the pun) the accompanying library of classic code. Where is our &#8220;reader&#8217;s library&#8221; to go with the &#8220;teaching library?&#8221;</p>
<p>I fear that until such a library gets widely disseminated, we&#8217;re doomed to forever repeat the mistakes of the past.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theodicius.net/archives/2012/12/29/my-15-minutes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why I Like Mongrels</title>
		<link>http://www.theodicius.net/archives/2012/11/19/mongrels/</link>
		<comments>http://www.theodicius.net/archives/2012/11/19/mongrels/#comments</comments>
		<pubDate>Mon, 19 Nov 2012 22:02:06 +0000</pubDate>
		<dc:creator>arlen</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.theodicius.net/?p=541</guid>
		<description><![CDATA[Given the recent BritRuby brew-up and the associated wailing and gnashing of teeth, I think it&#8217;s appropriate to put my own thoughts forward on this topic. While I&#8217;ve not organized a technical conference (yet) I&#8217;ve been the sole organizer of chess events catering to areas spanning a single city up to a full hemisphere, and [...]]]></description>
				<content:encoded><![CDATA[<p>Given the recent <a href="http://2013.britruby.com">BritRuby</a> brew-up and the associated wailing and gnashing of teeth, I think it&#8217;s appropriate to put my own thoughts forward on this topic. While I&#8217;ve not organized a technical conference (yet) I&#8217;ve been the sole organizer of chess events catering to areas spanning a single city up to a full hemisphere, and been part of groups organizing literary conferences, so perhaps I have a little to contribute to the public post-mortem currently going on.</p>
<p>Let me start out with a simple fact: I&#8217;m a dog-lover, and I prefer mongrels. Pure-bred dogs (and my first dog was a pure Collie, so I&#8217;m speaking from some experience) come with issues. They can be nervous, even neurotic. Quick to anger (or hide). Prone to various diseases and birth defects.</p>
<p>Most of these issues don&#8217;t show up in mongrels. The mongrels I&#8217;ve owned were stable, loving and useful pets. They weren&#8217;t nervy, rarely got sick. The hardiness comes from the genes of one breed canceling out the weaknesses in the genes of another. (It&#8217;s like metallurgy. You want the iron to be stronger, more useful, you mix in some other elements. Alloys are the mongrels of metallurgy.)</p>
<p>So it goes when it comes to conferences. The wider the experience and cultural base of the presenters, in general the more they have to offer that I haven&#8217;t yet seen or learned. Yum.<br />
<span id="more-541"></span><br />
Don&#8217;t start building that strawman, yet. I don&#8217;t believe in diluting the quality of an event just in order to achieve diversity. But I also refuse to accept that a decline in quality is a necessary result of trying to achieve diversity. In fact, just the opposite. All my experience as an organizer points to a properly organized diverse event being of higher quality than a monocultural one.</p>
<p>Let&#8217;s take the ruby world in particular, since that&#8217;s the concrete example on the microscope slide currently.</p>
<p>BritRuby started with 15 invited and 5 &#8220;open&#8221; slots for presenters, then filled those invited slots with 15 white males. Now, if I were picking my 15 favorite ruby presenters, I can&#8217;t imagine leaving off Sandi Metz (<a href="http://www.confreaks.com/videos/1115-gogaruco2012-go-ahead-make-a-mess">&#8220;Go Ahead, Make a Mess&#8221;</a>) or Katrina Owen (<a href="http://www.confreaks.com/videos/1071-cascadiaruby2012-therapeutic-refactoring">&#8220;Therapeutic Refactoring&#8221;</a>) at the very least (I&#8217;ve never made such a list, but they&#8217;d easily make my top ten). I wouldn&#8217;t end up with such a homogenous list without several people turning me down. I have no idea if that happened here, but available evidence (albeit hearsay) suggests not. And that&#8217;s unfortunate.</p>
<p>Why is something like diversity an issue? Can&#8217;t we just focus on the presentations, and leave the presenters out of it? Well, yes, but the numbers alone suggest such a list is unlikely to come out of a process that actually is blind to presenters, and experiential data is even more insistent on that point. (This <a href="http://www.princeton.edu/pr/pwb/01/0212/7b.shtml">Princeton article</a>, for example, shows that when there is nothing except the music to concentrate on, more women are judged the superior performer than when any unconscious gender biases are allowed to influence the process.)</p>
<p>To be fair, I do not for one millisecond believe the BritRuby organizers to be evil, or even moderately chauvinistic, based on this list. I think more likely this is just one more example of the type of unconscious bias shown in that Princeton article: all of us are unconsciously biased towards selecting those in the pool more like us than others. In other words, I &#8220;accuse&#8221; the Brit Ruby organizers not of being ravening sexist misogynistic pigs, but merely of being human (and no less human than I, if it comes to that).</p>
<p>To me, diversity in a conference is a lot like tests for my code. I don&#8217;t write tests because other people want me to. I don&#8217;t write tests simply to have tests. I don&#8217;t have a specific number of tests in mind when I start writing, nor do I have a target number of tests per lines of code that I am expected to meet.</p>
<p>I write tests to make sure all paths through my code are exercised, and help me maintain that code in the face of changing requirements. My tests help me bring new developers into a project by helping them understand what the code is meant to do, and help non-developers understand what the code is doing, because the tests are easier to understand than the code.</p>
<p>Because of this, in order to write the tests I need to look at my coding task through other&#8217;s eyes, forgetting for the moment what I know about implementations and what I expect to do. I wasn&#8217;t always very good at this (in fact I used to stink quite badly at it, to be honest) and I still commit howlers even after all my focus on tests.</p>
<p>I rely on other people to see what I don&#8217;t. They have a different perspective on the code, so they see different things. After all, it&#8217;s not easy to look at code (or other things) from someone else&#8217;s viewpoint. Unless, of course, you *are* someone else.</p>
<p>And that&#8217;s the point. The more different from me someone is, the more likely they are to think of something I&#8217;ve missed, and I&#8217;ve learned the hard way that by listening to them I improve my ability to think of those things myself.</p>
<p>We all know &#8220;Linus&#8217;s Law&#8221; (&#8220;With enough eyes, all bugs are shallow&#8221;) and know its utility. But I&#8217;ve discovered that there&#8217;s a quality factor to that as well &#8212; that the more the eyes are like mine, the more likely they are to overlook the same things I do. I&#8217;d much rather have one pair that can see what mine don&#8217;t than a hundred pairs that see what I see.</p>
<p>We all suffer from unconscious biases, we all have blind spots that will bite us unless we put up controls for it. A useful one when organizing is to make the program item proposals anonymous, putting up a wall between me and my people biases. A second is to review my list of pre-selected speakers, and ask myself if there&#8217;s a valid reason it isn&#8217;t more diverse. (There may be one, though if the reason is because all my diverse invitations were turned down, I&#8217;d call that an &#8220;organizer smell&#8221; and start looking for a bug in either myself or my approach.)</p>
<p>Make no mistake about this, I&#8217;m not encouraging diversity simply for the sake of diversity. Like code quality in TDD, making everyone feel included is a byproduct, not the goal. I&#8217;ve a much more selfish agenda than that. Conferences with the same old guys giving the same old talks are boring. Hearing from minds different from mine, minds built from radically different experiences, strengthens my own, expands it, makes it capable of imagining bigger and better things.</p>
<p>Makes it into more of a tool I can build good stuff with.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theodicius.net/archives/2012/11/19/mongrels/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Patterns of Understanding</title>
		<link>http://www.theodicius.net/archives/2012/11/10/patterns-of-understanding/</link>
		<comments>http://www.theodicius.net/archives/2012/11/10/patterns-of-understanding/#comments</comments>
		<pubDate>Sat, 10 Nov 2012 20:41:56 +0000</pubDate>
		<dc:creator>arlen</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://www.theodicius.net/?p=535</guid>
		<description><![CDATA[I wrote a little while ago about the advisability of teaching software patterns to beginning developers as well as experienced ones. But it occurs to me there&#8217;s reason for doing it that I may not have covered completely. I’m going to take as my starting point Donald Knuth’s idea that the main task in software [...]]]></description>
				<content:encoded><![CDATA[<p>I wrote a <a href="http://www.theodicius.net/archives/2012/10/13/on-chess-and-s…re-development/ ‎">little while ago</a> about the advisability of teaching software patterns to beginning developers as well as experienced ones. But it occurs to me there&#8217;s  reason for doing it that I may not have covered completely.</p>
<p>I’m going to take as my starting point Donald Knuth’s idea that the main task in software development is to explain to other developers what we want the computer to do, that the primary audience of source code is a human, not a machine. That seems obvious enough to not need much supporting evidence. Nobody lives forever, no one stays in the same job forever; everybody gets replaced, either voluntarily or involuntarily.</p>
<p>While the syntax of the language makes this communication possible, we still need a common conceptual base to make it efficient. Even in English it’s easy to come away from a single sentence with multiple meanings; development languages, with their near-total focus on what over why, can be even more adept at hiding meaning.<br />
<span id="more-535"></span><br />
Noted psychologist Adrian deGroot performed a number of experiments with the minds of chess players (you just knew I was going to work chess into this, somehow, didn&#8217;t you?) but the one that is most relevant to this involves testing memory and understanding of chess positions.</p>
<p>He gave players of varying playing strength a few seconds to look at a &#8220;normal&#8221; chess position, meaning one that quite easily could arise during actual play, even if it hadn’t. He then asked the players to reconstruct the position from memory on an empty chessboard. The better the player, he found, the more accurately they could reconstruct the position.</p>
<p>Then deGroot repeated the experiment using random diagrams, with pieces in improbable (even impossible) positions. Interestingly, he found good players were no better than anyone else at recalling those “nonsensical” positions.</p>
<p>There&#8217;s a reason for this that extends beyond chess. The brain simply isn&#8217;t good at remembering lots of little details. It&#8217;s as if the brain only has so many short-term “slots” to hold things, no matter their size. So it takes what it sees and &#8220;chunks&#8221; it into larger groupings that make sense to it. In this way, a grouping of chess pieces that commonly occurs in a game can be remembered as a single unit.</p>
<p>But we&#8217;re talking about software, not chess. Or are we? Think about a batch of unfamiliar code in front of you, that you&#8217;ve been brought in to revise and extend. If both you and the developer(s) who originally created the code have learned the same patterns, you can take many lines of this code and group them mentally under that pattern, keeping them in your mind efficiently while continuing to read more code.</p>
<p>If you and the original developer(s) of the codebase you&#8217;re working on did not have this common “pattern language” to call upon, you would still end up grouping lines of code into “chunks” in order to comprehend it, but you would additionally have to create your own “chunking algorithm” to do it. “Reinventing the wheel” like this is not only inefficient, it runs counter to today’s more pragmatic development principles.</p>
<p>And because you&#8217;ve been using a common pattern language, you not only group many lines of the code into a single “slot” in your memory under the name of a pattern you already understand, the odds are you and the original developer(s) had the same chunks in mind. You can build your mental model of the code more quickly and reliably, and your model will more closely resemble the original ideas behind the existing code.</p>
<p>This means even if you’re a new developer, you’d be more productive with a new codebase faster knowing the patterns than if you hadn’t learned the patterns in the first place.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theodicius.net/archives/2012/11/10/patterns-of-understanding/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On Chess and Software Development</title>
		<link>http://www.theodicius.net/archives/2012/10/13/on-chess-and-software-development/</link>
		<comments>http://www.theodicius.net/archives/2012/10/13/on-chess-and-software-development/#comments</comments>
		<pubDate>Sat, 13 Oct 2012 20:03:10 +0000</pubDate>
		<dc:creator>arlen</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.theodicius.net/?p=521</guid>
		<description><![CDATA[Or, In Defense Of Software Patterns. I was listening to Ruby Rogues podcast episode #56 when the discussion turned to software patterns, and my teeth started grinding. It wasn&#8217;t so much about what was said (though there were enough of those moments, to be sure) as about what was implied or left unsaid. With one [...]]]></description>
				<content:encoded><![CDATA[<p>Or, In Defense Of Software Patterns.</p>
<p>I was listening to <a href="http://rubyrogues.com/056-rr-david-heinemeier-hansson/">Ruby Rogues podcast episode #56</a> when the discussion turned to software patterns, and my teeth started grinding.</p>
<p>It wasn&#8217;t so much about what was said (though there were enough of those moments, to be sure) as about what was implied or left unsaid. With one exception (to come later) I&#8217;m going to leave names out of this, simply because I want the discussion to center on the ideas, not the personalities. Listen to the podcast, and you&#8217;ll be clear enough about who said what, if the who of it means that much to you. I&#8217;ll just say the guest and the rogues are all not short of accomplishments and as a group contain very good developers.</p>
<p>The implication that came out of it, and that was only halfheartedly challenged, was that software patterns weren&#8217;t useful things to teach beginning developers. The statement that made the show notes was &#8220;You need to feel the pain and understand the pattern before you begin to understand when and why to use it and when to deviate.&#8221; While the statement itself is defensible, it&#8217;s really irrelevant to the value of software patterns for either experienced or nascent developers. My own first reaction was, &#8220;So?, What&#8217;s your point?&#8221;<span id="more-521"></span></p>
<p>I have two problems with the discussion that ensued (for complete context, listen to the podcast). The first is with the implicit assumption in that statement, left completely unchallenged in the podcast, that you can&#8217;t understand something until you experience it first hand. This is patently absurd. I don&#8217;t have to fall off a cliff, or stick my finger in a light socket, before I can begin to understand it would be bad for me to do it. There is plenty of secondhand experience I can draw upon to inform my actions. (I used this technique with my kids frequently during their childhood, &#8220;I&#8217;ve already made that mistake, and this is what happened. It wasn&#8217;t pleasant. You go find your own mistakes to make.&#8221;)</p>
<p>I could possibly let that statement pass unchallenged if we replaced the concept of &#8220;begin to understand&#8221; with something like &#8220;intimately understand&#8221; but even then, I wouldn&#8217;t positively support it. We&#8217;ve proven as a species we can learn from other people&#8217;s mistakes often enough that it&#8217;s not a newsworthy event when we do.</p>
<p>Software patterns (including the <a href="http://c2.com/cgi/wiki?LawOfDemeter">Law of Demeter</a>, which one voice seemed to hate so much it bordered on obsession) are shorthand for techniques commonly found useful in the field. As such, they are generalizations, meaning while they don&#8217;t have universal utility (few generalizations do) they are more often useful than not. Yet (I&#8217;m not clear why, except that possibly the speaker had seen bad code excused by the coder claiming to be following a pattern) the concept of patterns as something known by beginners was consistently trashed.</p>
<p>One of the rogues (James Edward Gray II, who gets named because the mention is positive, not negative) brought in the subject of chess, which is the most apt analogy to the concept. His point was arbitrarily rejected, but (without even asking for his permission) I&#8217;m going to expand upon it here, because he was ultimately correct.</p>
<p>Beginning chess players are taught various &#8220;rules&#8221; or principles. They are &#8220;chess patterns,&#8221; so to speak. One widely known one is &#8220;Rooks belong behind passed pawns.&#8221; This pattern was preached by (among others) Siegbert Tarrasch in his instruction book <strong>The Game Of Chess</strong>. An amateur, after watching a game which Tarrasch won by placing his rook in front of, not behind, a passed pawn, accused Tarrasch of teaching incorrect principles. Tarrasch replied, &#8220;Very well, then. Rooks belong behind passed pawns. Except when they don&#8217;t.&#8221;</p>
<p>In the chess world, John Watson and Jacob Aagaard carried on a multi-book discussion of the idea of chess principles and their exceptions. It&#8217;s not surprising that Aagaard, a grandmaster whose non-chess specialty is cognitive semiotics, took the &#8220;pro&#8221; position on patterns, against the American IM. As human beings, we learn by recognizing patterns in the world, then by refining that pattern recognition as we process the exceptions. The refinements come as we add to our knowledge base, but before we can recognize the exceptions to the patterns, we first have to know the patterns.</p>
<p>Every rule we have for significant human action has exceptions. So what? That somehow invalidates the rule? Not every software pattern is applicable in every circumstance. The Titanic sank. What should we do, ban ocean liners?</p>
<p>The 1st World Correspondence chess champion, CJS Purdy wrote: &#8220;There are chess players who do not know the principles, and are weak. There are those who know the principles, and are less weak. And there are those who know how weak the principles are, and are strong.&#8221;</p>
<p>In chess, the top players got there by following the principles, following the chess patterns, unless there was a reason not to. There in the position was the information necessary to judge whether the principle does or does not apply. Their &#8220;default state&#8221; is that it applies. That fact is itself the only excuse for the principle&#8217;s existence &#8212; were it not appropriate more often than not no one would care about it.</p>
<p>That&#8217;s the way it is with software patterns. I can&#8217;t let the idea that people should not follow patterns more often than they follow them stand unchallenged, as happened in the podcast, because I think that is a dangerously stupid idea.</p>
<p>In our haste to kick over the ceremonial idols of our past (and, as a veteran of SDM/70, I can confirm that plenty of them <em>needed</em> kicking over) we have become entirely too eager to throw away everything, rushing straight through iconoclasm into antinomianism. Baby. Bathwater.</p>
<p>We&#8217;ve but to look around us to see the effects of that. Uncle Bob talks about how much knowledge we&#8217;ve ignored in his presentation from Ruby Midwest, <a href="http://confreaks.com/videos/759-rubymidwest2011-keynote-architecture-the-lost-years">Architecture, The Lost Years</a>. More directly to the point, at MagRails Aaron Patterson talks about how he speeded up Rails routing in <a href="http://confreaks.com/videos/782-magrails2011-pattern-matching">Pattern Matching</a>. The biggest point to take away from that presentation is that he did it not by ignoring the patterns and knowledge of the past, but by <em>using</em> them. (I really don&#8217;t think that can be emphasized enough. A better, faster, way was already known, years ago. I don&#8217;t want to belittle his achievement, the algorithm still had to be investigated and implemented. But that it took this many years for someone to apply this algorithm is, I think, indicative of how far we&#8217;ve gone in ignoring knowledge gained in the past.)</p>
<p>The idea that you have to make the mistakes yourself in order to advance (&#8220;You need to feel the pain and understand the pattern before you begin to understand when and why to use it and when to deviate&#8221;) is poisonous to the idea of any sort of science. We advance the state of the science (or craft, or trade, or art, call it what you like) of software development not by forcing everyone to recapitulate mistakes of the past, but by focusing our efforts on everyone learning from them.</p>
<p>Does that mean that new (and even experienced) developers will not abuse a given software pattern? Of course not. They absolutely will. But when they do, they (and we, by extension) will learn even more about the advisability and applicability of that pattern. And we will all advance (not just the person who &#8220;experienced the pain;&#8221; all of us). Tomorrow&#8217;s developers will see more details of software development than we do because they&#8217;re standing on our shoulders. If we force them to eat the same dirt we did, it may make us feel better about our own past, but it really won&#8217;t help them progress beyond us.</p>
<p>The implementation details of this aren&#8217;t easy; nothing worthwhile ever is. The final stop is the code, obviously, but before the code comes the idea, and that&#8217;s the territory for software patterns, just as the place for chess principles is in the realm of thought, not move. Sometimes that rook belongs somewhere else; sometimes that pattern doesn&#8217;t apply. But in neither case can you consider whether it applies until you know the principle, the pattern.</p>
<p>It means bad code <strong>will</strong> be written. But that&#8217;s a universal constant, not a consequence of software patterns. And bad code written in support of even a good pattern should not stand. But was the bad code the result of a good developer following a bad pattern (perhaps an anti-pattern) or is it the result of misapplying a pattern or badly implementing an appropriate pattern? Only in the first case do we question the value of knowing the pattern; in the second case we question ourselves, add to our own knowledge store (and, hopefully, pass the knowledge on to others).</p>
<p>In software development as in chess, a knowledge of the basic patterns of the endeavor is invaluable to our advancement in the field. It is the way in which we &#8220;stand on the shoulders of giants,&#8221; to borrow Newton&#8217;s words. It&#8217;s the way we become more productive than those who went before.</p>
<p>Software development patterns allow us to make new mistakes, rather than recapitulate past ones. And while repeating old mistakes will merely lead to our own improvement, making new ones will improve everyone.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theodicius.net/archives/2012/10/13/on-chess-and-software-development/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>What I Did To The Jasmine Phantom</title>
		<link>http://www.theodicius.net/archives/2012/09/25/what-i-did-to-the-jasmine-phantom/</link>
		<comments>http://www.theodicius.net/archives/2012/09/25/what-i-did-to-the-jasmine-phantom/#comments</comments>
		<pubDate>Tue, 25 Sep 2012 17:14:49 +0000</pubDate>
		<dc:creator>arlen</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://www.theodicius.net/?p=507</guid>
		<description><![CDATA[Being a continuation of the saga began in Jasmine And The Headless Webkit. OK, after the last installment I had a working in-browser test runner (standalone Jasmine) and a working command-line test runner (phantom-jasmine). But they were different files, meaning if anything significant changed, I was going to have to duplicate the changes in two [...]]]></description>
				<content:encoded><![CDATA[<p>Being a continuation of the saga began in <a href="http://www.theodicius.net/archives/2012/09/10/the-story-of-jasmine-and-the-headless-webkit/" title="Jasmine And The Headless Webkit">Jasmine And The Headless Webkit</a>.</p>
<p>OK, after the last installment I had a working in-browser test runner (standalone Jasmine) and a working command-line test runner (phantom-jasmine). But they were different files, meaning if anything significant changed, I was going to have to duplicate the changes in two different testing files. This, while workable short-term, is not an acceptable solution.</p>
<p>So I dug in to the files.<br />
<span id="more-507"></span><br />
Upon examination, the browser runner that came with standalone Jasmine included the exact same jasmine files that the command-line runner that came with phantom-jasmine included, so I could dispense with those. But the reporters were different.</p>
<p>The standalone Jasmine used the HTMLReporter from jasmine-html.js, but that reporter wouldn&#8217;t cut it from the command line. And phantom-jasmine used a custom-written ConsoleReporter that wasn&#8217;t included at all in standalone Jasmine.</p>
<p>So I had some reconciliation to do. I revised the testing script in my testrunner file (I used the standalone Jasmine specrunner.html as my base file, because it already included most of what I wanted it to be) and revised the test script in it to be:</p>
<pre>
  var console_reporter = new jasmine.ConsoleReporter()
  var htmlReporter = new jasmine.HtmlReporter();
  var jasmineEnv = jasmine.getEnv();
  jasmineEnv.specFilter = function(spec) {
	return htmlReporter.specFilter(spec);
  };
  jasmineEnv.addReporter(htmlReporter);
  jasmineEnv.addReporter(console_reporter);
      var currentWindowOnload = window.onload;

      window.onload = function() {
        if (currentWindowOnload) {
          currentWindowOnload();
        }
        execJasmine();
      };

      function execJasmine() {
        jasmineEnv.execute();
      }
</pre>
<p>Originally, phantom-jasmine used the TrivialReporter, but that&#8217;s marked as deprecated currently, with the HTMLReporter suggested as the replacement for it, making this easy, because the specrunner file already used it.</p>
<p>Then I moved the ConsoleReporter javascript file into a &#8220;vendor&#8221; directory in my jasmine directory and added a &lt;script> tag to point at its new location. Voila! The tests now ran from either source. A single file ran the same tests either from the command-line or the browser.</p>
<p>I mentioned I&#8217;d been using the command-line to run the tests for a while, and while I had been developing with it I noticed the reporting from it wasn&#8217;t what I&#8217;d like it to be. So I dug into more of the code.</p>
<p>Everything I needed to change was in the method &#8220;reportSuiteResults.&#8221; Originally it read:</p>
<pre>
  proto.reportSuiteResults = function(suite) {
    if (!suite.parentSuite) { return; }
    var results = suite.results();
    var failed = results.totalCount - results.passedCount;
    var color = (failed > 0)? "red" : "green";
    this.log(suite.description + ": " + results.passedCount + " of " + results.totalCount + " passed.", color);
  };
</pre>
<p>Note this completely skips reporting on the top level of describe blocks, so while you may know a little of what you&#8217;re testing, you don&#8217;t know the full context. Plus, if you had a series of tests that were at the top describe level, the results weren&#8217;t reported by this code. Not Good.</p>
<p>So I revised the code to be this:</p>
<pre>
  proto.reportSuiteResults = function(suite) {
    var results = suite.results();
    var failed = results.totalCount - results.passedCount;
    var color = (failed > 0)? "red" : "green";
    var mySuite = suite;
    var description = suite.description;
    while (mySuite.parentSuite) {
        mySuite = mySuite.parentSuite;
        description = mySuite.description + " " + description;
    }
    if (!suite.parentSuite) {
        this.log("-- " + description + " spec subtotals: " +
            results.passedCount + " of " + results.totalCount + " passed.",
            color);
    } else {
        this.log(description + ": " + results.passedCount + " of " +
            results.totalCount + " passed.", color);
    }
  };
</pre>
<p>This starts out pretty much the same as the original code. But it captures the describe blocks at every level, including the top, and concatenates them into one long sentence. It then creates either a subtotal line for an outer describe block or a results line for the inner describe block. This change helps me more easily find which tests ran fine and which ones didn&#8217;t.</p>
<p>I&#8217;m not sure this is the exact thing I&#8217;m looking for in this reporter, yet, but it&#8217;ll do for now. And hopefully I&#8217;ve given you some ideas for customizing the Jasmine reporters yourself. Let me know if you find some interesting things to do in them.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theodicius.net/archives/2012/09/25/what-i-did-to-the-jasmine-phantom/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The story of Jasmine and the Headless Webkit</title>
		<link>http://www.theodicius.net/archives/2012/09/10/the-story-of-jasmine-and-the-headless-webkit/</link>
		<comments>http://www.theodicius.net/archives/2012/09/10/the-story-of-jasmine-and-the-headless-webkit/#comments</comments>
		<pubDate>Mon, 10 Sep 2012 20:10:05 +0000</pubDate>
		<dc:creator>arlen</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web Design]]></category>

		<guid isPermaLink="false">http://www.theodicius.net/?p=495</guid>
		<description><![CDATA[No, I&#8217;m not hitting Halloween early. There&#8217;s nothing about pumpkins involved here. I&#8217;m talking about testing your javascript. I&#8217;m talking sane development practice, not ghost stories. I&#8217;d been using jsTestDriver for a while, but got tired of the way it would take off and go navel-gazing without warning, so I looked for something else and [...]]]></description>
				<content:encoded><![CDATA[<p>No, I&#8217;m not hitting Halloween early. There&#8217;s nothing about pumpkins involved here. I&#8217;m talking about testing your javascript.</p>
<p>I&#8217;m talking sane development practice, not ghost stories.</p>
<p>I&#8217;d been using jsTestDriver for a while, but got tired of the way it would take off and go navel-gazing without warning, so I looked for something else and found <a href="http://pivotal.github.com/jasmine/">Jasmine</a>. This was working well for me (I was using the standalone version of Jasmine, which required me to refresh the browser whenever I wanted to test in it) but I missed the convenience of kicking off the tests automagically, from a command line.</p>
<p>Then I found the Phantom.<br />
<span id="more-495"></span><br />
<a href="http://phantomjs.org/index.html">PhantomJS</a> is a project that creates a webkit-based browser in headless form, quite useful for running things that don&#8217;t require a UI, such as tests. And, best of all, it installs easily under OS/X, providing you use <a href="http://mxcl.github.com/homebrew/">homebrew</a> on your mac. (Installation instructions for OS/X and other systems <a href="http://phantomjs.org/download.html">can be found here</a>.)</p>
<p>For me, it was as simple as:<br />
<code><br />
brew update<br />
brew install phantomjs<br />
</code></p>
<p>And phantom was installed.</p>
<p>Then I turned to <a href="https://github.com/jcarver989/phantom-jasmine">phantom-jasmine</a> to hook the Phantom up with jasmine 1.2 and I was ready to roll. It was a simple matter of cloning the phantom-jasmine repo down unto my system, then popping the TestRunner.html file in place and pointing its internals at the locations I&#8217;d placed the code.</p>
<p>Invoking the tests from within my development directory turned out to be a trifle tricky, but nothing extremely complex:<br />
<code><br />
phantomjs ../phantom-jasmine/lib/run_jasmine_test.coffee TestRunner.html<br />
</code></p>
<p>To break this down, &#8220;phantomjs&#8221; is what I installed with homebrew, the &#8220;../phantom-jasmine/lib/run_jasmine_test.coffee&#8221; parameter is from the phantom-jasmine readme (strictly cargo-culted, er, copy/pasted from the readme, it is the coffeescript that actually loads and runs the specified page) while the TestRunner.html file is the page to be used to run the tests. It was placed in my project root so this command line was run as if from there.</p>
<p>For a more concrete example, have a look at my <a href="https://github.com/Paladin/Marshall">Marshall project</a>. I didn&#8217;t include TestRunner in the repo (perhaps I should have) because it relied on the configuration of my dev system, specifically the location of the phantom-jasmine project, but I&#8217;ll reproduce it here for your benefit:<br />
<code><br />
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"<br />
  "http://www.w3.org/TR/html4/loose.dtd"><br />
&lt;html><br />
&lt;head><br />
  &lt;title>Jasmine Test Runner&lt;/title><br />
  &lt;link rel="stylesheet" type="text/css" href="../phantom-jasmine/vendor/jasmine-1.2.0/jasmine.css"><br />
  &lt;script type="text/javascript" src="../phantom-jasmine/vendor/jasmine-1.2.0/jasmine.js">&lt;/script><br />
  &lt;script type="text/javascript" src="../phantom-jasmine/vendor/jasmine-1.2.0/jasmine-html.js">&lt;/script></p>
<p>  &lt;script type="text/javascript" src="../phantom-jasmine/lib/console-runner.js">&lt;/script></p>
<p>  &lt;!-- SOURCE FILES --><br />
	&lt;script src="js/src/Board.js">&lt;/script><br />
	&lt;script src="js/src/Game.js">&lt;/script><br />
	&lt;script src="js/src/MoveTree.js">&lt;/script><br />
	&lt;script src="js/src/NAG.js">&lt;/script><br />
	&lt;script src="js/src/Pgn.js">&lt;/script><br />
	&lt;script src="js/src/Piece.js">&lt;/script><br />
	&lt;script src="js/src/VBoard.js">&lt;/script></p>
<p>  &lt;!-- TEST FILES --><br />
  &lt;script src="test/board.spec.js">&lt;/script><br />
  &lt;script src="test/game.spec.js">&lt;/script><br />
  &lt;script src="test/MoveTree.spec.js">&lt;/script><br />
  &lt;script src="test/Pgn.spec.js">&lt;/script><br />
  &lt;script src="test/Piece.spec.js">&lt;/script><br />
  &lt;script src="test/VBoard.spec.js">&lt;/script><br />
&lt;/head><br />
&lt;body><br />
&lt;div>&lt;div id="game1">&lt;/div>&lt;div id="game1_board">&lt;/div>&lt;/div></p>
<p>&lt;script type="text/javascript"><br />
  var console_reporter = new jasmine.ConsoleReporter()<br />
  jasmine.getEnv().addReporter(new jasmine.TrivialReporter());<br />
  jasmine.getEnv().addReporter(console_reporter);<br />
  jasmine.getEnv().execute();<br />
&lt;/script></p>
<p>&lt;/body><br />
&lt;/html><br />
</code></p>
<p>You&#8217;ll note the phantom-jasmine directory is located alongside the marshall project files in my dev directory on my dev machine. This isn&#8217;t necessary, just my custom.</p>
<p>Every other reference is based around the TestRunner being in the project root.</p>
<p>I&#8217;ll leave as an exercise for the reader the right way to integrate the command-line test execution into your chosen IDE.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theodicius.net/archives/2012/09/10/the-story-of-jasmine-and-the-headless-webkit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Anatomy of a Surprise</title>
		<link>http://www.theodicius.net/archives/2012/09/04/anatomy-of-a-surprise/</link>
		<comments>http://www.theodicius.net/archives/2012/09/04/anatomy-of-a-surprise/#comments</comments>
		<pubDate>Tue, 04 Sep 2012 19:48:47 +0000</pubDate>
		<dc:creator>arlen</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.theodicius.net/?p=489</guid>
		<description><![CDATA[So, here I was, working WorldCon (Chicon7) as usual when this nugget gets dropped on me. &#8220;Ron Donachie is here and wants to help. Where can you use him?&#8221; This is interesting. Ron Donachie played Ser Rodrik Cassel on Game Of Thrones, the hot HBO series from the series of books by George R. R. [...]]]></description>
				<content:encoded><![CDATA[<p>So, here I was, working WorldCon (Chicon7) as usual when this nugget gets dropped on me. &#8220;Ron Donachie is here and wants to help. Where can you use him?&#8221;</p>
<p>This is interesting. Ron Donachie played Ser Rodrik Cassel on Game Of Thrones, the hot HBO series from the series of books by George R. R. Martin. as well as the heroic Steward from &#8220;Tooth and Claw&#8221;, the episode of Doctor Who that gave birth to Torchwood. He&#8217;s definitely got the cred for WorldCon.</p>
<p>But, as our Programming Head observed, there isn&#8217;t always a good place to fit an actor in. (WorldCon, I should explain for those of you unfamiliar with that land, is a gathering focused on the literary works of science fiction and fantasy. Media properties are welcome, and there are program items for fans to discuss them, but largely WorldCon is a place where Author, not Actor, nor even Director/Producer, is King.)<br />
<span id="more-489"></span><br />
So I scanned the list of upcoming items looking for a fit. The Doctor Who discussions center around the Moffat/Smith years, alas. Then I see a panel devoted to discussing Season 1 &#038; 2 of Game of Thrones. We talk about it, but it already has the full complement of panelists so we&#8217;d have to throw somebody off to make room for him, and it&#8217;s in one of our &#8220;normal&#8221; programming rooms, meaning we might overflow it terribly once we announce his addition to it.</p>
<p>Then I see the list of panelists and Lee (yes, <a href="http://www.theodicius.net/archives/2012/09/04/the-meaning-of-words/" title="The Meaning Of Words">that</a> Lee) is one and I can&#8217;t let this slip by. I know she&#8217;s on wheels and parks at the end of the panel table, so there will be an empty chair even if the full group is there. And I <em>know</em> she&#8217;s a big fan of the series.</p>
<p>&#8220;How about we don&#8217;t announce it? We&#8217;ll just have him show up unannounced and join in. A special treat from him for the hard-core fans?&#8221; The eyes light up around the table and it&#8217;s agreed. If Ron Donachie can possibly make the time, he&#8217;ll be there.</p>
<p>I can hardly contain myself. Aside from this being my suggestion, you have to worry when sending a Name into a fan discussion. Names can be intimidating, even unintentionally, and can change the entire dynamic of the panel. And, back to the personal level, I owe Lee and disrupting her discussion is not In My Plans.</p>
<p>So I waited outside the door to see the results of my meddling. Yes he could make the time, and yes it worked out splendidly. Ron Donachie&#8217;s participation was met with rave reviews from panelists and audience alike. For your part in this, Mr Donachie, accept my thanks and IOU.</p>
<p>And for you, Lee: It took me two years, but I finally got you back!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theodicius.net/archives/2012/09/04/anatomy-of-a-surprise/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Meaning Of Words</title>
		<link>http://www.theodicius.net/archives/2012/09/04/the-meaning-of-words/</link>
		<comments>http://www.theodicius.net/archives/2012/09/04/the-meaning-of-words/#comments</comments>
		<pubDate>Tue, 04 Sep 2012 18:56:56 +0000</pubDate>
		<dc:creator>arlen</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.theodicius.net/?p=479</guid>
		<description><![CDATA[Sometimes, words mean much more than we might think to the person we speak them to. And last far longer. This one&#8217;s for you, Lee. It was nearing the end of the arrival day at a large convention some years back. The identity of the convention is irrelevant to my point, so I&#8217;ll neither name [...]]]></description>
				<content:encoded><![CDATA[<p>Sometimes, words mean much more than we might think to the person we speak them to. And last far longer. This one&#8217;s for you, Lee.</p>
<p>It was nearing the end of the arrival day at a large convention some years back. The identity of the convention is irrelevant to my point, so I&#8217;ll neither name it nor explain it.</p>
<p>This thing had started going pear-shaped before I ever got to the office. I didn&#8217;t know how I was going to manage things, if I even could. I&#8217;d been making a few changes here and there, but nothing seemed to help. I was on the point of just giving up.<br />
<span id="more-479"></span><br />
Then this feisty lady wheeled up to my desk (OK, table). We had not been kind to her at all, and she had some (valid) points to make about this. At the end of it all, she drew herself up, looked me in the eye and said:</p>
<p>&#8220;I know you. You&#8217;re better than this.&#8221;</p>
<p>I&#8217;m sorry Lee. You had more to say after that point, but try as I might, I don&#8217;t recall what it was. I&#8217;m not sure I ever really heard it. I was stuck on that line.</p>
<p>One of the least attractive features of the truth is the way that nasty little stinger in its tail generally finds the most sensitive spot to dig in and deliver its payload. This was no exception.</p>
<p>I sat there, well and truly stung, still processing those words as I watched her wheel away. I couldn&#8217;t say anything; she was right, hang it. I <em>was</em> better than this. Those four little words got farther under my saddle better than any burr. A couple of the people working for me noticed the change, and settled in beside me for the ride.</p>
<p>I won&#8217;t say <em>I</em> made that pear-shaped monstrosity work, because <em>I</em> certainly didn&#8217;t. <em>We</em> did. It was a team effort all the way; I merely stood up on my hind legs and played my role. By the end, we were getting compliments about how smooth it was going and how much better it was than the speaker thought (or was afraid) it would.</p>
<p>But the story doesn&#8217;t end here, nor is it simply about the one convention. There have been times since then, at conventions and elsewhere, when I&#8217;ve been backed into a corner and tempted to just &#8220;phone it in.&#8221; But whenever that moment has come, I hear the wheels roll up, and those four words, all ground up in gravel, drop into my inner ear: &#8220;You&#8217;re better than this!&#8221;</p>
<p>I thanked her for it after the convention, but I never really had the chance to thank her properly, until recently.</p>
<p>But <strong>that&#8217;s</strong> another story.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theodicius.net/archives/2012/09/04/the-meaning-of-words/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Choose Your Own Coding Adventure?</title>
		<link>http://www.theodicius.net/archives/2011/11/14/choose-your-own-coding-adventure/</link>
		<comments>http://www.theodicius.net/archives/2011/11/14/choose-your-own-coding-adventure/#comments</comments>
		<pubDate>Mon, 14 Nov 2011 18:01:53 +0000</pubDate>
		<dc:creator>arlen</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.theodicius.net/?p=472</guid>
		<description><![CDATA[You remember the Choose Your Own Adventure series? You&#8217;d read a paragraph or two, then be presented with a question, the answer determining which of several pages you&#8217;d turn to in order to continue the story. I may be giving too much credit to Mike Stackpole, Rick Loomis and the rest of the crew at [...]]]></description>
				<content:encoded><![CDATA[<p>You remember the Choose Your Own Adventure series? You&#8217;d read a paragraph or two, then be presented with a question, the answer determining which of several pages you&#8217;d turn to in order to continue the story.</p>
<p>I may be giving too much credit to Mike Stackpole, Rick Loomis and the rest of the crew at Flying Buffalo for inventing the genre, but I give them credit for coming up with an interesting way of bringing interactivity to paper.</p>
<p>Creative as it was, the resulting stories were difficult to read.<span id="more-472"></span> I had to stop every few sentences to turn pages, and jumping around through the book like a peripatetic kangaroo kept me from getting involved in the story itself, kept me all too aware of the medium rather than the message.</p>
<p>Yet how many of us today follow this noble, but failed, experiment when writing our code?</p>
<p>We begin writing our methods with the best of intentions. We lay out the opening scene (the arguments) and launch into the gripping tale of what is happening to them.</p>
<p>Yet only a few lines into the story, we stop. We interrupt the narrative flow in order to make a decision and send the reader off to somewhere else, with no regard for what is happening in the main storyline.</p>
<p>It might be something simple. We might break the reader’s concentration with something like:</p>
<p><code>id = params[:id].nil? ? 1 : params[:id]<br />
Model.find(id)</code></p>
<p>Not only that, but if you wanted to be sure you weren&#8217;t getting slipped something troubling, you&#8217;d also have to check to see if what you were handed as the id actually is a numeric, and if not, handle that separately. It may be a small thing, but it distracts the reader (and ourselves) from the main point of the adventure, which is what we’re about to do with that id.</p>
<p>But we have to be sure there’s something both safe and useful in that id before we use it, I hear you say? Of course we do. It&#8217;s just there’s a better, more reader-friendly, way to word that. A way that will do less to distract our reader from our main plot.</p>
<p>If we use the fetch() method instead of simply [] to get the value, we can specify a default to use if the index is unset. This means we&#8217;ll get a real value back, no matter what, and won&#8217;t have to test for Nil and do any conditional branching to handle it as a special case.</p>
<p>Adding the .to_i method at the end of that (something we couldn&#8217;t do so long as the possibility of getting a Nil remained) will make the received value safer to use, by returning zero (a number) if the id value is anything but a number, which means the find method will always have a parameter it can work with, so we can drop it directly into the find:</p>
<p><code>Model.find(params.fetch(:id, 1).to_i)</code></p>
<p>This single line pulls from the model by id, supplies a default value of 1 if the id has not been given, and makes sure the given id is in fact a number, returning a zero if it isn&#8217;t.</p>
<p>By doing this we&#8217;ve handled the problems of Nil and non-numeric input at the same time, so we can guarantee the model will get a type of input it can use; failure in finding the zero id (the result of trying a non-numeric id) can be handled exactly the same as any failure to find an id not present in the database.</p>
<p>Look at your own code, this time realizing you&#8217;re telling the story of what happens to the data it encounters. Remember, the code you write today will be read tomorrow, either by yourself or someone else. Use good storytelling techniques to make that easier.</p>
<p>Tell the story of your code clearly, keeping digressions like error handling out if the main narrative flow as much as possible. Keep the main purpose of the code in a smooth unified narrative flow, so as not to confuse your reader. Your reader (who might also be yourself at some future date) will thank you for it.</p>
<p>And so will your code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theodicius.net/archives/2011/11/14/choose-your-own-coding-adventure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby 1.9 and Nginx on FreeBSD</title>
		<link>http://www.theodicius.net/archives/2011/11/01/ruby-1-9-and-nginx-on-freebsd/</link>
		<comments>http://www.theodicius.net/archives/2011/11/01/ruby-1-9-and-nginx-on-freebsd/#comments</comments>
		<pubDate>Wed, 02 Nov 2011 01:10:54 +0000</pubDate>
		<dc:creator>arlen</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.theodicius.net/?p=466</guid>
		<description><![CDATA[Noticed some, um, interesting, gotchas when setting up ruby 1.9 and the nginx web server on FreeBSD. The issue with the ruby install is subtle, and doesn&#8217;t really show up until long after you have installed it. The issue is it points the gem repository to the wrong place. It points the gem repository to [...]]]></description>
				<content:encoded><![CDATA[<p>Noticed some, um, interesting, gotchas when setting up ruby 1.9 and the nginx web server on FreeBSD.</p>
<p>The issue with the ruby install is subtle, and doesn&#8217;t really show up until long after you have installed it. The issue is it points the gem repository to the wrong place. It points the gem repository to /usr/local/lib/ruby/gems/1.8 which is where the 1.8 gems should reside, not the 1.9 gems.<span id="more-466"></span></p>
<p>The ruby 1.9 gems should reside at /usr/local/lib/ruby/gems/1.9. And the default install doesn&#8217;t set that up. A sure way to make that happen is to put:</p>
<p><code>RUBY_DEFAULT_VER=1.9</code></p>
<p>in the /etc/make.conf file. It&#8217;s possible that adding the &#8220;-E RUBY_DEFAULT_VER=1.9&#8243; flag on the make command will do the same thing, but I found the make.conf change worked, so I stopped at that point.</p>
<p>Make that change before you install ruby19 from the ports:</p>
<p><code>cd /usr/ports/lang/ruby19<br />
make install clean</code></p>
<p>After that, the gems will install in the right location and everything will be work the way it&#8217;s supposed.</p>
<h3>Nginx</h3>
<p>The regular ports install for Nginx, on the other hand, is defective from the get-go. While the ruby issue is a subtle one that may not even pose a problem in some circumstances, the ningx issue will prevent the server from responding to any control scripts.</p>
<p>The issue here is the default configuration script points the .pid file to the wrong location. In the default nginx.conf file installed by the ports system is the line:</p>
<p><code>pid        logs/nginx.pid;</code></p>
<p>This means the control scripts will not be able to find the nginx.pid file in order to send it signals. Instead the line needs to read:</p>
<p><code>pid        /var/run/nginx.pid;</code></p>
<p>This will locate the nginx.pid file where the control scripts can find it, and everything will work.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theodicius.net/archives/2011/11/01/ruby-1-9-and-nginx-on-freebsd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
