Just A Summary : Tag typo, everything about typo http://www.bofh.org.uk/articles/tag/typo.rss en-us 40 Piers Cawley Practices Punditry Other things which aren't fun <p>Last year, you would have been forgiven for thinking that Typo was pretty much dead in the water as an ongoing project. <a href="http://www.typosphere.org/">Typosphere</a> was a placeholder, changes were few and far between, the app was a bloated monster. So, people switched, in droves, to <a href="http://www.mephistoblog.com/">Mephisto</a> the new, (and excellent) kid on the block. Heck, even <a href="http://blog.leetsoft.com/">Tobi</a>, the original author of Typo, has switched.</p> <p>Mephisto&#8217;s a great piece of software, and I&#8217;m as sure as I can be (without taking a closer look) that its underpinning code is cleaner than typo&#8217;s. When you&#8217;re developing on a rapidly moving platform like Ruby on Rails, there could be said to be a second mover advantage &#8211; the later you start, the more likely Rails is to already do what you want, and the less likely you are to zag where Rails later zigs.</p> <p>However, <a href="http://www.technoweenie.com/">Rick</a> and <a href="http://alternateidea.com/">Justin</a> have other projects and demands on their time, and once something is Good Enough, it&#8217;s hard to summon up the motivation to make it better until you find something that <em>you</em> want your application to do.</p> <p>So now, as Typo comes out of hibernation, it seems that Rick and Justin have been getting it in the neck because their project is &#8216;<a href="http://www.mephistoblog.com/2007/3/22/is-mephisto-dead">stalled</a>&#8217;. Okay, so I admit, I did smile ruefully to myself when I read that.</p> <p>Then I read the comments. Wow. Some people have some serious entitlement issues.</p> <p>It&#8217;s been said before, it&#8217;ll be said again I&#8217;m sure: if you don&#8217;t like something about an open source project, &#8220;Patches welcome!&#8221;. If your patches are repeatedly rejected: it&#8217;s open source, fork off. If a project is moribund: offer to help.</p> <p>Complaints just put people&#8217;s backs up.</p> <p>I think it&#8217;s great that there&#8217;s choices available if you want a blog built Rails. Different perspectives on a problem space are important &#8211; if nothing else, everyone gets to steal from each other, everyone&#8217;s apps get better and everybody wins.</p> Mon, 07 May 2007 14:29:00 -0500 urn:uuid:a9679735-8b8f-4d7e-ad37-201d643b178e pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/05/07/other-things-which-arent-fun#comments Ruby Typo mephistoblog typo entitlement http://www.bofh.org.uk/articles/2007/05/07/other-things-which-arent-fun A sketch of declarative ActiveRecord Migrations <p>Writing migrations can get pretty tedious when you&#8217;re being scrupulous about writing both the up and the down side of the migration. Okay, so the <a href="http://macromates.com/">Textmate</a> ninjas amongst you can use scarily clever snippets to populate the <code>down</code> migration while you write the <code>up</code> method, but I can&#8217;t be the only Mac user who still prefers Emacs. And not everyone gets to run on Macs either.</p> <p>So, inspired by something Jamis Buck wrote about <a href="http://weblog.jamisbuck.org/2006/11/13/designing-a-dsl">designing a <span class="caps">DSL</span></a>, I&#8217;ve been sketching out a <span class="caps">DSL</span> for describing the easy parts of a migration in declarative style. None of this is implemented yet, but I&#8217;m pretty sure that it&#8217;s relatively simple to implement for a decent Ruby metaprogrammer. I&#8217;m brain dumping it here so I can come back to it later, or, you never know, someone might have implemented it by the time I revisit&#8230;</p> <h3>The sketch</h3> <div class="typocode"><pre><code class="typocode_default ">class AdjustContentTable &lt; ActiveRecord::Migration class Content &lt; ActiveRecord::Base include ActiveRecord::Migration::Delta delta do +(:extended, :text) -(:excerpt, :text) +index :text_filter_id end end end callbacks_for(:up) do before_any_changes Content.before_changes { ... } Content.before_additions {...} Content.after_additions {...} Content.before_removals {...} Content.after_removals {...} Content.after_changes {...} after_any_changes end callbacks_for(:down) do ... end end</code></pre></div> <h3>Implementation Pointers</h3> <p>By making <code>delta</code> do its work in a block, it&#8217;s possible to <code>instance_eval</code> the block using a <code>Delta</code> object that has appropriate implementations of <code>+</code> and <code>-</code>.</p> Then <code>callbacks_for[:up]</code> puts its block into, say <code>@callbacks[:up]</code> and the block is yielded to to set up the callbacks by the default implementation of <code>up</code>. The default <code>up</code> probably looks something like: <div class="typocode"><pre><code class="typocode_default "> def self.up @callbacks[:up].call apply_all_deltas end</code></pre></div> Of course the fun bit is the implementation of <code>apply_all_deltas</code> &#8211; the per class <code>apply_delta</code> is reasonably simple: <div class="typocode"><pre><code class="typocode_default "> def self.apply_delta(direction) callback(:before_changes) apply_additions(direction) apply_removals(direction) callback(:after_changes) end def self.apply_additions(direction) if has_additions?(direction) callback(:before_additions) eval additions_for(direction).to_ruby callback(:after_additions) end end ...</code></pre></div> <p>Thinking about it, <code>apply_all_deltas</code> is going to take a certain amount of grovelling about in the namespace to work out what classes need to have their deltas applied, but even with just per class delta declarations, this should be a useful thing to implement.</p> <h3>Braindump ends</h3> <p>Sorry this doesn&#8217;t come with a handy dandy Rails plugin with it all implemented; your contributions in this area would be very gratefully received.</p> Fri, 24 Nov 2006 06:18:00 -0600 urn:uuid:e2dc28b9-7fac-4696-b12a-d1c3e72c21b4 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2006/11/24/a-sketch-of-declarative-activerecord-migrations#comments Ruby Typo typo rubyonrails dsl lazyweb http://www.bofh.org.uk/articles/2006/11/24/a-sketch-of-declarative-activerecord-migrations Getting back to Typo <p>I&#8217;ve been taking an accidental sabbatical from Typo. It started during conference season, then there was a bunch of housekeeping and general home type stuff that needed doing, so I&#8217;ve been away from the codeface for a while (and I <em>still</em> haven&#8217;t turned my EuroFOO talk into a podcast, or finished scanning and uploading all the EuroOSCON photos&#8230;)</p> <p>However, I am back and coding, and a new typo feature just made it to the top of my todo list: This morning, in a fit of over enthusiasm, I managed to zap the 36 most recent comments on this blog. And, for bonus points, I didn&#8217;t have a backup.</p> <p>So, now I have a backup regime in place. And the next feature I add to Typo is going to be a confirmation box when you attempt to delete any feedback that hasn&#8217;t been marked as spam.</p> <p>Recent changes added to the typo trunk add CachedModel support, which dramatically reduces our query count per page, which is no bad thing either; I have other ideas for getting that count down too.</p> <p>So, until the <a href="http://typosphere.org/trac">Typo Trac</a> is back up, watch this space, I shall try and post here whenever there&#8217;s any significant changes on the trunk.</p> <h3>Updates</h3> <h4>Google cache is my friend!</h4> <p>Miles Barr reminded me in the comments that, as well as hanging on to all those embarrassing infelicities, Google&#8217;s search cache also remembers good things like comments that you foolishly delete.</p> <p>Sadly, it didn&#8217;t remember everything, but it did remember everything, but it did remember a lot, so various articles have their commenty mojo working once more.</p> <p>Did I really just say &#8216;commenty mojo working&#8217;? It seems I did. Ah well, it&#8217;s 6.20am and I&#8217;ve been awake since 4, I think I&#8217;ll let myself off with a caution.</p> <h4>Oops I did it again</h4> <p>But my backups just saved my arse. Now I really should get on with making sure I don&#8217;t do it again.</p> Sun, 29 Oct 2006 07:19:00 -0600 urn:uuid:913d4df2-924c-481e-b150-549687e54975 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2006/10/29/getting-back-to-typo#comments Ruby Typo typoupdate typo http://www.bofh.org.uk/articles/2006/10/29/getting-back-to-typo Other viewpoints, and why they are important <p>Many thanks to Paul Ingles who has just written a <a href="http://www.oobaloo.co.uk/articles/2006/08/15/writing-a-typo-sidebar-test-first-in-rails">fantastic article</a> about writing a Typo sidebar in a test driven way.</p> <p>For too long we&#8217;ve been assuming that Typo sidebars are, in fact, detestable (&#8220;If it&#8217;s not testable, it&#8217;s detestable&#8221; &#8211; someone at the Sydney XP group, by way of <a href="http://www.martinfowler.com/bliki/Detestable.html">Martin Fowler</a>). Paul neatly demonstrates that sidebars are perfectly testable, we just haven&#8217;t been testing them. Bad us.</p> <p>So, I&#8217;m rolling back the changes in my current sidebar rejig and starting again by writing some tests for a few of the core sidebars, and then I can start my refactoring without quite so much of The Fear.</p> <p>So, once again, thanks Paul. It&#8217;s really great to occasionally see the curious outsider&#8217;s view of what we&#8217;re working on &#8211; it makes us question our assumptions and often shows us better ways.</p> Wed, 16 Aug 2006 02:50:00 -0500 urn:uuid:f2098926-bad2-4a90-8f89-2ea12d300044 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2006/08/16/other-viewpoints-and-why-they-are-important#comments The Practice of Programming Ruby Typo testdriven TDD ruby typo sidebar http://www.bofh.org.uk/trackbacks?article_id=other-viewpoints-and-why-they-are-important&day=16&month=08&year=2006 http://www.bofh.org.uk/articles/2006/08/16/other-viewpoints-and-why-they-are-important Scratching an Itch <p>Some time ago, around the time of the <a href="http://typogarden.org">Typo themes contest</a>, someone, I think it may have been <a href="http://scottstuff.net/">Scott Laird</a>, wrote a nifty little <a href="http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0001OR&#38;topic_id=1">sparklines</a> textfilter.</p> <p>It&#8217;s a really cunning piece of code, the problem is that, to make it work, Scott had to make some dramatic changes to the way textfilters work which, in turn, meant we had to change the way we got at the htmlized versions of our content. Before sparklines, you could do <code>content.body_html</code> in your view and it would just work, generating the html as required. After the change you had to do <code>content.html(@controller, :body)</code>, which I&#8217;m sure you&#8217;ll agree is rather gruesome. So we wrapped it up in a helper method, letting you do: <code>article_html(@article, :body)</code>, which is only slightly less gruesome.</p> <p>At a stroke, we managed to break almost all of the themes entered in the contest, the eventual winner included. Ho hum.</p> <p>To be honest, screwing up the winning theme&#8217;s almost beside the point, I&#8217;ve disliked the new interface for getting at html content ever since we introduced it, but I&#8217;ve liked cunning textfilters more, so we&#8217;ve bitten the bullet and accepted the fact that Typo 4.0 will have a different theme <span class="caps">API</span> from the last release.</p> <p>Well&#8230; I say accepted. I&#8217;ve been looking for a way out of it in a desultory fashion ever since we introduced it. And today I cracked it. I knew &#8211; despite a few howls of protest &#8211; that introducing a Blog class was the right thing to do even if we never take the step to full multiblog capabiliity. Today, it paid off&#8230;</p> <p>It turns out that the blog object and its class is the ideal place to hang both static and dynamic context information. The static context includes the usual blog wide settings (and eventually things like the sidebar configuration).</p> <p>Dynamic context is currently just the active controller. I had been toying with having the controller set a <code>$current_controller</code> global, but that becomes a massive pain in the bum once you start rendering components. However, if you tell the blog about the current controller it can keep a stack of them. Every time you render a component, the blog pushes the component&#8217;s controller onto the stack and pops it off again once the sub request has completed.</p> <p>So: the blog knows about the current controller; the content knows about the blog, which means that we can write:</p> <div class="typocode"><pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">Content</span> <span class="keyword">def </span><span class="method">body_html</span> <span class="ident">html</span><span class="punct">(</span><span class="ident">blog</span><span class="punct">.</span><span class="ident">controller</span><span class="punct">,</span> <span class="symbol">:body</span><span class="punct">)</span> <span class="keyword">end</span> <span class="keyword">end</span></code></pre></div> <p>And all your views can use the same <span class="caps">API</span> as they did back in the days of Typo 2.</p> <p>The real <code>body_html</code> is more sophisticated, of course, and in the absence of a controller it falls back on the cached value.</p> <p>I am a happy camper this morning.</p> <p><span class="caps">BTW</span>. If you&#8217;ve still got problems porting an old theme, it&#8217;s probably because your theme renders sidebars &#8216;wrong&#8217;. Check in your <code>themes/&lt;theme&gt;/layouts/default.rhtml</code> and look for the line that looks like</p> <div class="typocode"><pre><code class="typocode_default ">&lt;%= render_component(:controller =&gt; 'sidebars/sidebar', :action =&gt; 'display_plugins') %&gt;</code></pre></div> <p>and replace it with:</p> <div class="typocode"><pre><code class="typocode_default ">&lt;%= render_sidebars %&gt;</code></pre></div> <p>The other big change in the way themes are rendered (and again, its&#8217; sidebar related) is in the <code>&lt;head&gt;</code> section of the layout. Here&#8217;s what the default theme header looks like nowadays:</p> <div class="typocode"><pre><code class="typocode_default ">&lt;head&gt; &lt;title&gt;&lt;%=h page_title %&gt;&lt;/title&gt; &lt;%= page_header %&gt; &lt;%= stylesheet_link_tag &quot;/stylesheets/theme/azure&quot;, :media =&gt; 'all' %&gt; &lt;%= stylesheet_link_tag &quot;/stylesheets/user-styles&quot;, :media =&gt; 'all' %&gt; &lt;%= stylesheet_link_tag &quot;/stylesheets/theme/print&quot;, :media =&gt; 'print' %&gt; &lt;/head&gt;</code></pre></div> <p>You should change yours to look similar (you pretty much <em>must</em> include that <code>&lt;%= page_header %&gt;</code> part.</p> <p>I hope this helps.</p> Sun, 09 Apr 2006 03:29:00 -0500 urn:uuid:9fb34df0-9771-44b8-a408-4119819f4d3b pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2006/04/09/scratching-an-itch#comments The Practice of Programming Typo typo ruby http://www.bofh.org.uk/trackbacks?article_id=scratching-an-itch&day=09&month=04&year=2006 http://www.bofh.org.uk/articles/2006/04/09/scratching-an-itch And... relax... <p>Rails 1.1 got released on Sunday.</p> <p>Lots of hosting services upgraded.</p> <p><a href="http://typosphere.org/trac">Typo</a>, both the &#8216;stable but old&#8217; and the bleading edge versions, didn&#8217;t get on with Rails 1.1. For quite spectacular values of &#8216;not getting on&#8217;. So, we ran around like headless chickens for a bit, gradually refining the incantations needed to get your existing typo installation working again &#8211; <code>rake freeze_edge VERSION=3303</code> does the trick if you&#8217;re still having problems &#8211; and then <a href="http://scottstuff.net/">Scott</a>, <a href="http://kevin.sb.org/">Kevin</a> and I spent the best part of a day nailing down the issues.</p> <p>It turns out that there was rather a lot of &#8216;cargo cult&#8217; code in older versions of Typo. Cargo cult code is code that isn&#8217;t there because it works, but because it reassures the programmer into thinking it will work. Rails 1.0 was far more forgiving of our cargo cult (excessive use of <code>require_dependency</code>, an undocumented method that doesn&#8217;t quite do what we thought it did) than 1.1.</p> <p>So, with that done, and a few more bugs squashed and we&#8217;re almost ready for a release (future distributions will come with rails baked into the tarball &#8211; but not if you get it from the repository), both of 2.6.0 with a frozen rails distribution and of the forthcoming 4.0.0. As I write their are two issues outstanding on the <a href="http://www.typosphere.org/trac/query?status=new&#38;status=assigned&#38;status=reopened&#38;milestone=4.0">4.0.0 milestone</a>, the trickiest of which is Scott&#8217;s plan to make typo installation substantially less user hostile. However, if you&#8217;re happy to deal with the slightly tricksy installation, there&#8217;s never really been a better time to jump onto the Trunk. <a href="http://www.typosphere.org/trac/wiki/DownloadCurrent">Grab</a> a copy and start blogging. You know you want to.</p> Fri, 31 Mar 2006 14:38:00 -0600 urn:uuid:de4fbd4f-1b98-432d-90b4-999146ef84cb pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2006/03/31/and-relax#comments The Practice of Programming Ruby Typo cargocult rails 1 typo 4 http://www.bofh.org.uk/trackbacks?article_id=and-relax&day=31&month=03&year=2006 http://www.bofh.org.uk/articles/2006/03/31/and-relax If you test it, I will patch <p>I&#8217;ve been working on <a href="http://www.typosphere.org/">Typo</a> this weekend, mostly going through <a href="http://www.typosphere.org/trac/report/1">open tickets</a> and deciding whether to apply patches.</p> <p>There&#8217;s plenty of potentially good patches in the queue, but too many of them give me The Fear.</p> <p>They don&#8217;t have tests!</p> <p>I&#8217;m the first to admit that I&#8217;ve added untested code to my projects (and I&#8217;ve been bitten by it too), but I&#8217;m more sanguine about that risk because, when it goes wrong, I can often rack my brains and pull back some memory of what my intent was. Knowing my intent helps me write meaningful tests and fix the issue. However, I can&#8217;t remember the intent of <em>your</em> code. The only thing I have to go on is what you wrote. If you&#8217;ve written tests, I can tell what you expect your code to do, which is far more important than being able to divine what your code actually does. Given a choice between code without tests and tests without code, I&#8217;ll take the tests every time.</p> <p>So, if you&#8217;ve got a typo patch on the trac and you want it to get accepted, you <em>must</em> write tests for it. If you&#8217;re implementing something that&#8217;s supposed to be conforming to a standard, then please reference those standards in your tests.</p> Sun, 12 Mar 2006 13:17:00 -0600 urn:uuid:6024f5e6-e2e2-425f-b904-ebdd70ae9a52 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2006/03/12/if-you-test-it-i-will-patch#comments The Practice of Programming Ruby Typo ruby TDD testdrivendevelopment typo http://www.bofh.org.uk/trackbacks?article_id=if-you-test-it-i-will-patch&day=12&month=03&year=2006 http://www.bofh.org.uk/articles/2006/03/12/if-you-test-it-i-will-patch Out of box experience <p>Have you ever bought hardware from Apple?</p> <p>Lovely wasn&#8217;t it?</p> <p>I don&#8217;t mean the kit was necessarily lovely&#8212;Apple have build their fair share of clunkers in the past. I&#8217;m talking about the experience of getting your iPod, PowerBook, PowerMac or whatever out of its box for the first time. It&#8217;s obvious that Apple have spent a good deal of time on making that out of box experience as satisfying as possible. A box that you will probably only use once seems to have had as much care lavished on it as the thing it contains.</p> <p>Maybe Sony have got better at this sort of thing, but I remember when I bought a MiniDisc player a few years ago. Where my iPod came in a great looking box that opened in a satisfying way which made it easy to get at the goodies it contained, the MiniDisc came in just another box and was awkward to get at to boot.</p> <p>I felt, and still feel, good about my iPod. I haven&#8217;t a clue where my MiniDisc Recorder has got to.</p> <p>So, why is this post in the Typo category?</p> <p>Well&#8230;</p> <p>Typo&#8217;s out of box experience sucks. From the point of view of someone who just wants to get their blogging engine up and running, it&#8217;s about as friendly as a cut snake.</p> <p>I know this because, in the last few days I have spent hours on the #typo <span class="caps">IRC</span> channel, walking folks through a set of simple steps to get to a working typo installation. Well, I thought they were simple&#8212;apparently they aren&#8217;t. Which is why it&#8217;s great to talk to real users even if it can be dispiriting sometimes.</p> <p>So, we need to work to improve typo&#8217;s out of box experience. Here&#8217;s my current plan:</p> <ol> <li>The user unpacks the typo distribution outside the html tree somewhere.</li> <li>At a shell prompt, she types <code>rake configure</code></li> <li>A webrick server kicks off and the user is prompted to point their browser at http://localhost/3000 or some such &#8216;private&#8217; url.</li> <li>Typo walks her through a straightforward sequence of steps which configure the real typo installation.</li> <li>At the end of the process, assuming it&#8217;s possible, the user will have appropriate symbolic links set up, a database.yml that makes sense and (ideally) a running blog engine.</li> </ol> <p>Now all that remains is to implement it.</p> Fri, 09 Dec 2005 16:38:00 -0600 urn:uuid:99348774-e9ca-4036-991f-bfd4ccdc7023 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2005/12/09/out-of-box-experience#comments The Practice of Programming Typo typo installation http://www.bofh.org.uk/trackbacks?article_id=out-of-box-experience&day=09&month=12&year=2005 http://www.bofh.org.uk/articles/2005/12/09/out-of-box-experience Calling all Typo theme hackers <p>As I write, <a href="http://www.typogarden.org/">Typo Themes Contest</a> is in that nervous interlude that comes between the last day for entries and the judges&#8217; announcement of fabulous prizes (I haven&#8217;t totted up the value of the prize fund, but there&#8217;s a Powerbook and an iBook for first and second place) for the winners.</p> <p>So, if you&#8217;re one of the entrants busily chewing your fingernails down to the quick as you anxiously await the news of your shiny new powerbook, I have a request:</p> <p>Please take the time to write a post mortem of your experience of writing your theme. What was good? What wasn&#8217;t? What really pissed you off about Typo? What documentation did you wish was available?</p> <p>When you&#8217;ve written it, post it somewhere and either comment or send a trackback ping to this message. I promise that I&#8217;ll read every such postmortem I hear about. Feedback on this stuff is important to making sure that Typo theme engine is easy to use and well documented in the future&#8212;I&#8217;m a coder not a designer; what&#8217;s intuitive to me isn&#8217;t necessarily intuitive to you and vice versa. And where interfaces are concerned, user expectation usually trumps developer expectation.</p> Thu, 08 Dec 2005 04:51:00 -0600 urn:uuid:2bb05fd1-ba09-464e-80a4-25e6a8ef95dc pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2005/12/08/calling-all-typo-theme-hackers#comments Typo typothemes typo postmortem http://www.bofh.org.uk/trackbacks?article_id=calling-all-typo-theme-hackers&day=08&month=12&year=2005 http://www.bofh.org.uk/articles/2005/12/08/calling-all-typo-theme-hackers Bwah hah ha ha! <p>This evening, I acquired a commit bit for the <a href="http://typo.leetsoft.com/">Typo</a> project. I&#8217;ve been chucking the occasional big patch and ideas at <a href="http://scottstuff.net/">Scott Laird</a>, the most active of the current maintainers, but he&#8217;s been busy doing all sorts of stuff, and he just started working at <a href="http://www.google.com/">Google</a> (go Scott!) so he doesn&#8217;t have quite as much copious free time as before.</p> <p>So, this evening I asked for, and received, my very own commit bit. Which means I can make changes to Typo without needing to funnel them through a maintainer&#8212;I&#8217;m now part of the funnel.</p> <p>Of course, responsible programming means I&#8217;ll still run big changes by Scott and the other maintainers, but it&#8217;s also useful to be able to make the kind of small changes that sometimes need to be made without it blocking on a busy man.</p> <p>Wish me luck.</p> Mon, 05 Dec 2005 22:11:00 -0600 urn:uuid:705d0394-b7bf-499a-9c10-5f88a8fea1ca pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2005/12/05/bwah-hah-ha-ha#comments Typo typo programming ruby rails gloating http://www.bofh.org.uk/trackbacks?article_id=bwah-hah-ha-ha&day=05&month=12&year=2005 http://www.bofh.org.uk/articles/2005/12/05/bwah-hah-ha-ha Testing Your Assumptions <p>One of the joys of writing applications using Ruby on Rails is the way the framework is constantly evolving better ways of doing stuff. It&#8217;s one of the dangers too.</p> <p>Each release of Rails brings new and groovy features to the table, so it&#8217;s nice to stay close to the edge. However, when you do that, a change in the framework can bring your whole app crashing down because a key assumption you made turns out not to be true any more.</p> <p>This is especially common when the assumed behaviour is undocumented, or a surprising consequence of behaviour that <em>is</em> documented.</p> <p>When this happens, your test suite can have failures everywhere; it&#8217;s hard to work out precisely what the underlying problem is.</p> <p>So, what to do?</p> <p>Easy. Write tests that express your assumptions. It&#8217;s always good to make assumptions explicit. It&#8217;s better still to make them executable. Whenever you use something that&#8217;s a little bit surprising or hard to find in the docs, or when you do something that works around a bug, write a test.</p> <p>Then, when the framework changes and tests are failing all over the place, test your assumptions. Hopefully there&#8217;ll be one or two failing tests there that point you to a solution to your problem. If there aren&#8217;t, then at least you know what&#8217;s <em>not</em> causing the problem. And, when you do find the underlying problem, you can add the new assumption to your tests for later.</p> <p>I&#8217;ve just been working on Typo and found (rather usefully as it happens) that, if you add counter caching to a model, the model that holds the cache field will call all its save/update hooks whenever the cache field is updated.</p> <p>Which is a little odd; it could be argued that simply adding what should be an &#8216;invisible&#8217; cache field to a model shouldn&#8217;t go changing its behaviour in this way. So, I&#8217;ve created an <code>assumptions_test.rb</code> file and written the behaviour up as a test. Now, if <a href="http://www.loudthinking.com/">David Heinemeier Hansson</a> decides that this is undesirable behaviour and changes it, we&#8217;ll be able to see what&#8217;s going on.</p> <p>The idea (as is so often the case) comes from Kent Beck. In this case, from <cite asin="0321146530">Test Driven Development</cite>. One more book by Beck that deserves to be on every programmer&#8217;s bookshelf.</p> Sun, 04 Dec 2005 09:37:00 -0600 urn:uuid:9d09cbd7-82de-4c78-92b6-5aa215038cba pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2005/12/04/testing-your-assumptions#comments The Practice of Programming Ruby Typo agilemethods ruby testing typo rubyonrails http://www.bofh.org.uk/trackbacks?article_id=testing-your-assumptions&day=04&month=12&year=2005 http://www.bofh.org.uk/articles/2005/12/04/testing-your-assumptions Testing Is Good <p>If you&#8217;ve hung out with extreme programmers, the Perl 6 crew, a large subsection of the Perl community, or, well, almost anyone who&#8217;s given it any thought, you&#8217;ll know that having a good test suite is essential.</p> <p>But how good is good enough?</p> <h3>Why am I asking?</h3> <p>Recently, Typo, the ruby based blogging engine that this site runs on, underwent a strutural change that involved replacing 4 different tables in the database with a single table, and migrating all articles, comments, trackbacks and pages into this new table.</p> <p>The migration was easy to write. Typo&#8217;s built on top of <a href="http://www.rubyonrails.com/">Rails</a>, and Rails has tools for doing database migrations. It&#8217;s hard to test a migration though, so the first &#8216;big&#8217; migration that moves articles into the new contents table just raises an exception saying &#8220;BACK <span class="caps">STUFF UP</span> before uncomment this line in the code and rerun the migration.&#8221;</p> <p>Making that backup is a really good idea because, if you&#8217;ve turned on spam protection, the next migration accidentally throws away all comments on sufficiently old articles.</p> <p>Oops.</p> <p>When a comment is saved, it first ensures that the article it&#8217;s attached to isn&#8217;t too old (more than 14 days old by default). If it is, the comment doesn&#8217;t get saved. This is fine when you <em>first</em> attach a comment to an article, but less fine when you&#8217;re, say, adding a guid field to the article or, as in the case of the migration, moving the comment from one database table to another.</p> <p>So, I&#8217;m adding a test or two to the test suite to ensure that we can modify comments on old articles. Once I&#8217;ve got that passing, we can be reasonably confident that, next time we do a migration that targets comments, we can be confident that <em>all</em> the comments will get modified appropriately, which can&#8217;t be bad.</p> <h3>What have I learned?</h3> <p>Because the change was a refactoring which adds no new functionality to Typo, I hadn&#8217;t written any new tests, just made sure that all the existing ones were passing. But no test suite is complete (unless you are testing a &#8220;Hello, world&#8221; program I suppose), so the issue that causes us (and anyone else who migrated to edge typo with spam protection turned on) pain wasn&#8217;t caught by the tests.</p> <p>I don&#8217;t blame whoever wrote the tests in the first place for missing this particular case; there&#8217;ve been occasions when I&#8217;ve wanted to edit an old comment to correct a <span class="caps">URL</span> or something and have bounced off the spam protection, but it never occurred to me that this might be a problem for migrations until I saw the bug report.</p> <p>What I have been forcibly reminded of is that no test suite is complete. So, when a bug comes in, you turn it into a test and add it to the test suite, then you should never introduce the same bug again.</p> <p>Nothing new there of course. Surely everyone already knows this rule of testing. But there&#8217;s nothing quite like actually doing it again, and having a good deal of confidence that adding the test will save you from an entire class of problems in the future to help you internalize it.</p> <p>I think that, before I do much more work on Typo, I&#8217;ll be taking a closer look at what is and isn&#8217;t tested in its test suite.</p> Wed, 05 Oct 2005 04:01:00 -0500 urn:uuid:0e2c8b18-cfbd-47c0-87a6-42e0a5e4b165 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2005/10/05/testing-is-good#comments The Practice of Programming Typo testfirst ruby typo oops http://www.bofh.org.uk/trackbacks?article_id=testing-is-good&day=05&month=10&year=2005 http://www.bofh.org.uk/articles/2005/10/05/testing-is-good Thinking aloud about Typo <p>Unless you&#8217;re interested in the internals of the Typo blogging engine and a possible rejigging of it, don&#8217;t bother reading the rest of this.</p> <h3>Typo Content Models</h3> <p>I&#8217;ve been attempting to follow the <span class="caps">DRY</span> Principle and rejigging Typo so that there&#8217;s fewer places with similar code to handle the cached html associated with a content object. Also, I&#8217;ve been thinking of how to build a more intelligent cache sweeper&#8212;at the moment, if you change a single article, every page in the cache is removed, which isn&#8217;t ideal. To that end I wrote a <code>ContentModel</code> mixin that adds a new class method:</p> <div class="typocode"><pre><code class="typocode_ruby "><span class="keyword">class </span><span class="class">Article</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span> <span class="ident">include</span> <span class="constant">ContentModel</span> <span class="ident">content_fields</span> <span class="symbol">:body</span><span class="punct">,</span> <span class="symbol">:extended</span> <span class="punct">...</span></code></pre></div> <p>Declaring a <code>content_field</code> sets up a setter method that would notify any object observers that the content has changed and reset the associated <code>_html</code> attribute.</p> <p>Which is all very well, but I think the time might have come to make a <code>Content</code> superclass. The various typo content models already have quite a few fields in common, and even Article, the &#8216;biggest&#8217; of them doesn&#8217;t have too many unique fields, so using Single Table Inheritance a completely insane idea.</p> <h3>What does that buy us?</h3> <ul> <li>Conceptually, it buys us a neater model, albeit at the expense of a slightly scruffier table structure (Rails can&#8217;t do multi-table inheritance yet).</li> </ul> <ul> <li>A unified ID scheme for our content models means that any putative table mapping content objects to currently cached files is going to be substantially simpler.</li> </ul> <ul> <li>Threading. Add <code>parent_id</code> column to the table and, because of the uniform ID structure, a comment gets to have a parent that is either an Article, another Comment or (possibly) a Trackback.</li> </ul> <h3>How could it hurt?</h3> <ul> <li>The database table&#8217;s a bit scruffier.</li> </ul> <ul> <li>Writing the migrations could be fun.</li> </ul> <ul> <li>We&#8217;d have to make sure that the old <code>articles/read/id</code> URLs continued to work&#8212;Adding an <code>old_id</code> column is one way forward, but it strikes me that a better way to do it would be to extend the <code>articles</code> table until it had all the fields required then rename it appropriately and then copy all the other content objects into it.</li> </ul> <h3>Conclusions</h3> <p>Well, I think it&#8217;s worth doing. But it&#8217;s my idea, so I would say that wouldn&#8217;t I. If you&#8217;re a Typo person and you&#8217;re reading this, what do you think?</p> Fri, 23 Sep 2005 02:41:00 -0500 urn:uuid:e669dce23bbafe4b607f272467c18c83 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2005/09/23/thinking-aloud-about-typo#comments Typo typo programming ruby rails http://www.bofh.org.uk/trackbacks?article_id=thinking-aloud-about-typo&day=23&month=09&year=2005 http://www.bofh.org.uk/articles/2005/09/23/thinking-aloud-about-typo Version Control <p>The trouble with version control systems is that, if you&#8217;re not careful, it&#8217;s almost as bad as having no version control at all. I&#8217;m currently juggling about 4 active branches of typo: the local development branch, the production branch and a couple of branches that isolate some of the local changes so I can make clean patches for the typo developers.</p> <p>So far, I&#8217;ve managed to upload about 5 patches, and I&#8217;m <em>still</em> not sure if the patches that are up on the <a href="http://typo.leetsoft.com/">Typo tracker</a> are sane. And back porting the clean new system&#8217;s been a complete nightmare.</p> <p>Still, it could be worse. I could be still trying to understand the inner workings of Moveable Type.</p> Sun, 04 Sep 2005 17:52:00 -0500 urn:uuid:56ecd1a6dce6b3c5e370f982ceeea59f pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2005/09/04/version-control#comments Administrative Typo programming versioncontrol svk svn grumbling typo http://www.bofh.org.uk/trackbacks?article_id=version-control&day=04&month=09&year=2005 http://www.bofh.org.uk/articles/2005/09/04/version-control