Just A Summary : Category ruby, everything about ruby http://www.bofh.org.uk/articles/category/ruby.rss en-us 40 Piers Cawley Practices Punditry Get sophisticated <p>Ruby&#8217;s primitives (Strings, Hashes, Arrays, Numbers &#8211; anything that has a literal syntax) are fine things. But that doesn&#8217;t mean you should use them everywhere. You&#8217;re often much better off wrapping them up in your own Value Objects.</p> <p>Something I was working on at Railscamp this weekend threw up a great example of why it makes sense to replace primitives with more specific objects as soon as possible. <a href="http://tommorris.org/">Tom Morris</a> asked me to take a look at <a href="http://github.com/tommorris/rena">Rena</a>, an <span class="caps">RDF</span>/Semantic Web thingy.</p> <p>The <span class="caps">RDF</span> spec describes two types of literals: a plain literal, which is a string with an optional language attribute and a typed literal, which is a string and an encoding (so the string might represent an integer, float, or anything else that your schema feels like expressing).</p> <p>These literals can be output in one of (at least) two formats. We&#8217;ll start by looking at <code>Literal#to_trix</code> and see where that takes us:</p> <pre name="code" class="ruby"><code> def to_trix if @lang != nil &#38;&#38; @lang != "" out = "&lt;plainLiteral xml:lang=\"" + @lang + "\"&gt;" else out = "&lt;plainLiteral&gt;" end out += @contents out += "&lt;/plainLiteral&gt;" return out end </code></pre> <p>If we look over at <code>TypedLiteral#to_trix</code> we see a much more straightforward implementation:</p> <pre name="code" class="ruby"><code> def to_trix "&lt;typedLiteral datatype=\"#{@encoding}\"&gt;#{@contents}&lt;/typedLiteral&gt;" end </code></pre> <p>How do we eliminate that ugly conditional at the beginning of <code>Literal#to_trix</code>, and analogous conditionals in <code>Literal#to_n3</code> and <code>TypedLiteral#to_n3</code>?</p> <p>My first thought was that I wanted to be able to write something like:</p> <pre name="code" class="ruby"><code> def to_trix "&lt;plainLiteral#{@lang.to_trix}&gt;#{@contents}&lt;/plainLiteral&gt;" end </code></pre> <p>But I didn&#8217;t want every string in the world suddenly acquiring a <code>to_trix</code> method. So, the solution was to intoduce a <code>Literal::Language</code> class and coerce our language into it, so <code>Literal#initialize</code> became:</p> <pre name="code" class="ruby"><code> def initialize(contents, lang = nil) @contents = contents @lang = Language.coerce(lang) end </code></pre> <p>And Language would look something like:</p> <pre name="code" class="ruby"><code> def self.coerce(lang) if lang.is_a?(self) return lang end new(lang.to_s.downcase) end def initialize(lang) @value = lang end def to_trix if @value == '' '' else " xml:lang=\"#{@value}\"" end end </code></pre> <p>That ugly conditional&#8217;s still there though, so we introduced the Null Object pattern, and things started to look a good deal cleaner:</p> <pre name="code" class="ruby"><code> class Language class Null include Singleton def to_trix '' end end def self.coerce(lang) case lang when self return lang when nil, '' return Null.instance else return new(lang.to_s.downcase) end end ... def to_trix " xml:lang=\"#{@value}\"" end end </code></pre> <p>At this point, we&#8217;re still just pushing code around. If anything, we&#8217;ve got more lines of code now than when we started, but we&#8217;re starting to move behaviour nearer to the data it relates to, and our objects are starting to look like objects rather than data structures. So, we press on and make a <code>TypedLiteral::Encoding</code> class and, at this point things start to look interesting. TypedLiteral is starting to look almost exactly the same as Literal, but with an Encoding rather than a language.</p> <p>That strange leading space in <code>Language#to_trix</code> is starting bug me. Let&#8217;s rewrite like so:</p> <pre name="code" class="ruby"><code> class Literal class Language def format_as_trix(literal) "&lt;plainLiteral xml:lang=\"#{@value}\"&gt;#{literal}&lt;/plainLiteral&gt;" end class Null def format_as_trix(literal) "&lt;plainLiteral&gt;#{literal}&lt;/plainLiteral&gt;" end end end def to_trix @lang.format_as_trix(@contents) end end </code></pre> <p>If we make analogous change to <code>TypedLiteral</code> and <code>TypedLiteral::Encoding</code> it&#8217;s obvious that TypedLiteral and Literal were essentially the same class. Renaming <code>@lang</code> and <code>@encoding</code> to <code>@language_or_encoding</code> makes this blindingly obvious, so we&#8217;ll remove all of TypedLiteral&#8217;s methods except initialize. All that remains is to introduce <code>Literal.untyped</code> and <code>Literal.typed</code> factory methods to Literal, and make <code>Literal.new</code> into a private method and we can remove TypedLiteral in its entireity. So we change the specs to reflect the new <span class="caps">API</span> (wrong way round I know). Now we have a chunk of shorter, clearer code that will hopefully be easier to extend to cope with outputting literals in other formats.</p> <h3>Retrospective</h3> <p>I realise that patterns aren&#8217;t the goal of development, but by the end of the process we have a Strategy (Language/Encoding), a couple of Factory Methods (<code>Literal.typed</code>, <code>Literal.untyped</code>) and a couple of factoryish methods (<code>Language.coerce</code>, <code>Encoding.coerce</code>).</p> <p>The most important aspect of the change was the introduction of the two new value object classes. Once they were introduced, they became the obvious places in which to put the varying behaviour and eliminate the repeatition of conditional code from the <code>to_*</code> methods. If there were to be a third output style, I would look at introducing classes like <code>N3Stream</code>, <code>TrixStream</code> and <code>WhateverStream</code> and have a scheme like:</p> <pre name="code" class="ruby"><code> def to_n3 print_on( N3Stream.new ) end def print_on(stream) language_or_encoding.print_on(stream, value) end </code></pre> <p>but that&#8217;s almost certainly over complicating things right now.</p> <p>The other thing I like about this kind of refactoring is that it drives the code towards methods and classes which obey the single responsibility principle and, at the end of the process, not only do we have fewer lines of code in total, but the individual methods involved are <em>all</em> substantially shorter and closer to the left hand margin.</p> <p>I really should start doing this kind of thing more in my Rails practice &#8211; I keep being put off by the fact that the <code>composed_of</code> helper is so annoyingly not quite right and, rather than submitting a patch or making a plugin I go &#8220;Ah well&#8230; I can live with a string for a bit longer&#8230;&#8221; and I <em>know</em>. From hard won experience at that, that it&#8217;s going to come and bite me. It&#8217;s already bitten Rails recently when Ruby got a new <code>String#to_chars</code> which doesn&#8217;t work like the ActiveSupport version.</p> <h3>Notes</h3> <p>If you want to see the gory details of how the change got made, Tom has merged this weekends changes into the github repository. It didn&#8217;t happen in quite the order I&#8217;ve described it in this post, but neither is this post a complete fabrication.</p> <h3>Changes</h3> <p>Corrected a stupid typo in the first block of code. Ugly condition is actually <code>if @lang != nil &#38;&#38; @lang != ''</code></p> Wed, 20 Aug 2008 11:25:00 -0500 urn:uuid:109c717f-5ad5-469e-b3b9-f19b40e8648e pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2008/08/20/get-sophisticated#comments Ruby ruby practiceofprogramming patterns railscamp08 http://www.bofh.org.uk/articles/2008/08/20/get-sophisticated Baby's first screencast <p>If you follow the Ruby blogs, you will probably have seen a bunch of programmers attempting to do something akin to Haskell&#8217;s <code>maybe</code>, or the ObjectiveC style, message eating null.</p> <p>Generally, by about the 3rd time you&#8217;ve written</p> <div class="typocode"><pre><code class="typocode_default ">if foo.nil? ? nil : foo.bar ... end</code></pre></div> <p>you&#8217;re getting pretty tired of it. Especially when <code>foo</code> is a variable you&#8217;ve had to introduce solely to hold a value while you check that it&#8217;s not nil. The pain really kicks in when you really want to call <code>foo.bar.baz</code>. You can end up writing monstrosities like <code>(tmp = foo.nil? ? nil : foo.bar).nil? ? nil : tmp.baz</code> (actually, if you were to write that in production code, you probably have bigger problems). One option is to just define <code>NilClass#method_missing</code> to behave like its Objective C equivalent, but I&#8217;ve never quite had the nerve to find out how that might work. I wanted to write</p> <div class="typocode"><pre><code class="typocode_default ">if maybe { foo.bar.baz } ... end</code></pre></div> <p>and have nil behave like an Objective C nil for the duration of the block, but no longer. So I wrote it. Then I thought about how to present it. I wrote the thing test first using rspec and the whole thing just flowed, but writing up a test first development process for a blog entry is painful, so I&#8217;ve made a very rough (but blessedly short) screencast of the process instead.</p> <p><a href="http://www.archive.org/download/RubyMaybeRoughcut/Monad2.mov"><img src="http://www.bofh.org.uk/images/monadcast.jpg" alt="" /></a></p> <p>That&#8217;s a slightly reduced thumbnail, the movie is substantially more readable. The bottom pane of the window is the output of autotest rerunning the spec every time either the spec or the implementation changes. The top pane alternates between the specs and the implementation. Generally, every time I edit the specs, a test starts failing and every time I edit the implementation it starts passing again. In the (any) real coding run, there were of course false starts, but generally the specs kept me pretty straight.</p> <p>A word or two of warning: This is a completely unedited, silent, screen cast, there are typos, backtrackings and other embarrassments. I stopped recording once I&#8217;d got 4 tests passing, but this is far from release quality (it&#8217;s perfectly usable if you know its limitations, but it&#8217;s not entirely robust).</p> <p>Please let me know what you think of this. I&#8217;m aiming to make a more polished version, complete with voice over and it would be good to know which bits are confusing and need addressing in more detail in the voice over.</p> Fri, 14 Mar 2008 14:29:00 -0500 urn:uuid:4b5ad7c3-d601-487b-9554-2d140f18b1a8 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2008/03/14/babys-first-screencast#comments Ruby screencast maybe rspec TDD http://www.bofh.org.uk/articles/2008/03/14/babys-first-screencast I am not a rock star <p>I am not a <a href="http://www.google.com/search?q=ruby+OR+rails+rockstar">rock star</a>. I am a computer programmer. I think I&#8217;m quite a good one.</p> <p>You are not a rock star either.</p> <p>387,000 matches to that query. Can we all just&#8230; I don&#8217;t know&#8230; grow up please?</p> <p>Mutter&#8230; grumble&#8230; chunter&#8230; I&#8217;m 40 you know!</p> <h4>Updates</h4> <p>I have it on reliable authority that James O&#8217;Kelly is a Ruby on Rails Rockstar that would make a great addition to any team!</p> Sat, 23 Feb 2008 00:13:00 -0600 urn:uuid:016d1523-aac0-4783-a87d-06908e0de83e pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2008/02/23/i-am-not-a-rock-star#comments Musings Ruby oldfart http://www.bofh.org.uk/articles/2008/02/23/i-am-not-a-rock-star Typo 5 is out - and more on the future <p>Right, we&#8217;ve cut a Typo 5 gem and it&#8217;s on rubyforge and heading to various mirrors I hope. Frédéric&#8217;s writing the release notification which will be appearing on <a href="http://blog.typosphere.org/">Typosphere</a> Real Soon Now.</p> <p>It&#8217;s been a surprisingly tricky process &#8211; we&#8217;re now requiring Rails 2.0.2 because the workings of <code>view_paths</code> have changed in a way which means we can&#8217;t quite make themes with Rails 2.0 <em>and</em> 2.0.2 and working with the edge seems like the more sensible proposition. If you&#8217;re on the bleeding edge, you should find that you get the right Rails via svn:externals anyway.</p> <h3>Typo futures</h3> <p>Meanwhile, I&#8217;ve been playing with stet and I&#8217;ve come to the conclusion that, although there&#8217;s mileage to be had in a radically slimmed down approach to the way Typo works, I&#8217;m better off simply removing the misfeatures from Typo and building from there &#8211; there&#8217;s a surprising amount of <em>stuff</em> that needs to be done in a competent blogging engine that Typo gets right &#8211; starting again would be throwing the baby out with the bathwater I think.</p> <p>However, this does mean that if you&#8217;re following the Typo <span class="caps">SVN</span> trunk, you&#8217;ll be seeing a reduction in features in the short term. We&#8217;ll be copying the current trunk to a <code>5-0-stable</code> branch before we start with the featurectomies though, so if you&#8217;re just after bugfixes, you&#8217;ll be better off there.</p> <h4>Multiblogging</h4> <p>We&#8217;re aiming to have multiblogging in the next release, but we&#8217;re rethinking the <em>how</em> of it. Right now, the &#8216;Blog&#8217; object adds a bunch of complexity to code that would be much happier simply assuming that it has the database to itself. So we&#8217;re going to look at switching to a database per blog approach, that way our core code can pretty much forget about the complexities of multiblogging, and (at least initially) anyone who wants multiblogging can get there by monkeying with configuration files &#8211; of course, we intend to add a web based admin interface once things settle down and we know how things are going to work.</p> <h4>Caching</h4> <p>Caching is always a bugbear in any typo installation. Because we want to be installable on the widest possible range of hosts, we can&#8217;t rely on the presence of handy tools like &#8216;memcached&#8217;. Also, some of our users are operating under some fairly severe memory and process constraints, so it makes sense to have the webserve serve static files as much as possible. Meanwhile, tools like Evan Weaver&#8217;s <a href="http://blog.evanweaver.com/articles/2007/12/13/better-rails-caching/">Interlock</a> are pointing the way towards seriously effective fragment caching. I shall be looking into implementing something that conforms to the interlock interface, but which can use an arbitrary cache backing store for fragments <em>and</em> maintain a full page cache. It&#8217;ll be interesting to find out if this is doable&#8230;</p> <h4>Atom Publishing Protocol</h4> <p>ActionWebService is going to go away &#8211; it&#8217;s already in the <code>ousted</code> branch of the rails <span class="caps">SVN</span> repository, and including it in Typo to support the various different admin APIs is getting painful. So, we&#8217;re going to preempt it. We won&#8217;t be getting rid of the various <span class="caps">XMLRPC</span> APIs until the pain becomes too great, but we are going to be concentrating on implementing, and strongly favouring, the Atom Publishing Protocol.</p> <h4>Feeds for everything</h4> <p>In particular, we&#8217;ll be adding atom feeds for all sorts of administrative data as a means of enabling people to write external tools for, say, spam protection, comment moderation and notification tasks. Right now, there&#8217;s a great deal of computation happening on the server side every time someone, say, comments on a post &#8211; in the kind of resource limited environments some people are running Typo in, that&#8217;s too much work. Switching to a feed + <span class="caps">APP</span> approach should help enormously with resource utilization.</p> <h4>Speaking of resources&#8230;</h4> <p>Using the server to render article previews is&#8230; suboptimal. Expect to see a javascript based preview system akin to the one I use for comments here.</p> Sun, 30 Dec 2007 09:10:18 -0600 urn:uuid:72e74aa1-6450-438c-9757-81f8621b342c pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/12/30/typo-5-is-out-and-more-on-the-future#comments Ruby Typo http://www.bofh.org.uk/articles/2007/12/30/typo-5-is-out-and-more-on-the-future Rails 2.0 and the Future of Typo <p>So, if you&#8217;ve been watching the Typo tree, you&#8217;ll see there&#8217;s been a fair amount of activity on it since Rails 2.0 got released. There&#8217;s a new default theme replacing the rather creaky &#8216;azure&#8217;, and a fair amount of work on getting our code compatible with the current state of Rails. As we work on this, it becomes apparent that Typo&#8217;s code is getting horribly brittle. I have said before that there&#8217;s been several places where we&#8217;ve zigged before Rails zagged, and we&#8217;re paying the price for that. It doesn&#8217;t help that our test coverage is distinctly ropy either &#8211; and I&#8217;m probably guiltier than most for letting things get into that state.</p> <p>So, our goal is to get what we have cleaned up and working with Rails 2 before releasing Typo 5.0. Once that&#8217;s done, that line of code will go into maintenance mode &#8211; there are still plenty of bugs to fix and documentation to write, but I&#8217;m afraid that extending that base is becoming too much of a chore.</p> <p>Which is why I have a new path in my local svk repository, //stet. I&#8217;m using this for experimental development of a new, slimmed down blogging engine that will be, first and foremost, a capable Atom Publishing Protocol host. Things like spam processing will be removed from the core of the application, but we&#8217;ll provide a suite of webservice clients that will consume the &#8216;unmoderated feedback&#8217; webfeed and use <span class="caps">APP</span> to either approve or delete the feedback as appropriate.</p> <p>Theming (at least initially) will probably be confined to Javascript and <span class="caps">CSS</span> changes, and I&#8217;m even thinking of exposing the sidebars as Atom collections &#8211; certainly I expect that, in the first cut, sidebars will be static &#8211; if you want content that <em>looks</em> dynamic you&#8217;ll have to do it via javascript.</p> <p>My initial goal is to slim things down as far as I possibly can &#8211; I want to build a blogging engine that can cope with the tight memory constraints of shared hosting by off loading much of the heavy lifting to client boxes. After all, I have far more processing capability available to me on the laptop I&#8217;m typing this on than the slice of Site5&#8217;s hosting infrastructure that&#8217;s actually running the blog. By making things small and static, I also hope to wring good performance numbers out of the tool as well &#8211; expect aggressive page caching at the very least.</p> <p>Another important goal is easy migration of Typo databases. I expect to be writing models and controllers from the ground up, but converting the database should just be a matter of running a migration.</p> <h3>Experimental</h3> <p>Of course, stet&#8217;s currently <em>very</em> experimental &#8211; about the only thing that&#8217;s actually <em>written</em> so far are a couple of routing plugins which should help radically simplify our routes.rb (expect an article&#8217;s url to change from /articles/2007/12/16/rails-20-and-the-future-of-type to /article/2007/12/16/rails-20-and-the-future-of-typo, but with a redirect in place to cater for the old style urls). I may have grandish plans for the thing, but I could equally discover that I&#8217;m off up a blind alley, in which case you can expect me to return to the current typo codebase with a few more lessons learned.</p> <h4>ActiveResource?</h4> <p>I remain unconvinced by ActiveResource as a technology. I agree with the authors of <a href="http://www.amazon.co.uk/exec/obidos/ASIN/0596529260/justasummary-21">RESTful Webservices</a> &#8211; good webservices are joined up. They take full advantage of what could be described as the defining technology of the world wide web, the <span class="caps">URL</span> based hyperlink to knit resources together in a discoverable fashion. An ActiveResource based webservice may well be a good <span class="caps">HTTP</span> citizen, but it&#8217;s still not really &#8216;webby&#8217; enough for my taste. Which means the Atom Publishing Protocol will remain my friend for most of the things I hope to do with stet. It may be harder to write a good <span class="caps">APP</span> server, but I&#8217;m convinced that it&#8217;s a much better interface for clients, and you should always favour ease of use over ease of implementation. If nothing else, we&#8217;re aiming to have more users than developers. Many more.</p> Sun, 16 Dec 2007 10:35:00 -0600 urn:uuid:e685075e-992e-4813-b17d-3392fb9c1e91 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/12/16/rails-2-0-and-the-future-of-typo#comments Ruby Typo stet http://www.bofh.org.uk/articles/2007/12/16/rails-2-0-and-the-future-of-typo Comprehensible sorting in Ruby <p>Here&#8217;s a problem I first came across when I was about 13 and helping do the stock check at the family firm. The parts department kept all their various spare parts racks of parts bins. Each bin was &#8216;numbered&#8217; with an alphanumeric id. We had printouts of all the bin numbers along with their expected contents and we&#8217;d go along the racks counting the bins&#8217; contents and checking them off against the print out. What confused me at the time was the way the printouts were organized. Instead of the obvious ordering, &#8220;A1, A2, A3, ..., <span class="caps">A99</span>&#8221;, the lists were ordered like &#8220;A1, <span class="caps">A10</span>, A11, ..., A2, <span class="caps">A20</span>, A21, ...&#8221;. After a bit of thought I realised that the computer was sorting the numeric bits of the bin numbers as if they were just sequences of strange letters. A bit more thought made me realise why, post computerisation, people were starting to use bin numbers like &#8220;A01, <span class="caps">A02</span>, ...&#8221;. Computers were more important than people so, in order to make sorting things easier, just add spurious leading 0s to make the number field a fixed width and Robert&#8217;s your parent&#8217;s brother.</p> <p>27 years later and computers are still crap at sorting things in a sensible fashion. Back before Moore&#8217;s Law was really kicking in, I suppose it was excusable, but surely we&#8217;ve moved past that now.</p> <p>Over on the <a href="http://blog.labnotes.org/2007/12/13/rounded-corners-173-beautiful-code/">labnotes</a> blog, there&#8217;s an example of some ruby code that attempts to do &#8216;human&#8217; sorting:</p> <div class="typocode"><pre><code class="typocode_default ">module Enumerable def sensible_sort sort_by { |key| key.split(/(\d+)/).map { |v| v =~ /\d/ ? v.to_i : v } } end end</code></pre></div> <p>It&#8217;s okay, as far as it goes. It certainly solves the parts bin problem I outlined above, but it&#8217;s not ideal. For example, you might expect <code>['-1', '1', '1.02', '1.1'].sensible_sort</code> to leave the order unchanged, but what you actually get is &#8216;1, 1.02, 1.1, -1&#8217;. Not ideal. Let&#8217;s rewrite sensible sort as</p> <div class="typocode"><pre><code class="typocode_default ">module Enumerable def sensible_sort sort_by {|k| k.split(/([-+]?\d+(?:\.\d+)?(?:[-+]?[eE]\d+)?)/).map {|v| Float(v) rescue v}} end end</code></pre></div> <p>That ugly regular expression should match a far wider selection of string representations of numbers. Certainly our &#8216;bad&#8217; list is now sorted correctly.</p> <p>But what about &#8220;a-1&#8221;, &#8220;a-2&#8221;. Using the implementation above, they&#8217;d get sorted as &#8220;a-2, a-1&#8221;, which can&#8217;t be right, can it? Let&#8217;s extend it a bit more and make sure we only worry about the &#8217;+&#8217; and &#8217;-&#8217; if they&#8217;re at the beginning of a line or preceded by whitespace.</p> <div class="typocode"><pre><code class="typocode_default ">module Enumerable def sensible_sort sort_by {|k| k.to_s.split(/((?:(?:^|\s)[-+])?\d+(?:\.\d+)?(?:[eE]\d+)?)/ms).map {|v| Float(v) rescue v}} end end</code></pre></div> <p>And that works fine, until you find that &#8220;B&#8221; sorts before &#8220;a&#8221;. Let&#8217;s catch that as well:</p> <div class="typocode"><pre><code class="typocode_default ">module Enumerable def sensible_sort sort_by {|k| k.to_s.split(/((?:(?:^|\s)[-+])?\d+(?:\.\d+)?(?:[eE]\d+)?)/ms).map {|v| Float(v) rescue v.downcase}} end end</code></pre></div> <p>Yay!</p> <p>Oh, wait a minute, what about version numbers? How should we sort, say &#8220;perl 5.8.0&#8221; and &#8220;perl 5.10.0&#8221;? The 5.8.0 form should definitely come first&#8230; Hmm&#8230;</p> <p>How about</p> <div class="typocode"><pre><code class="typocode_default ">module Enumerable def sensible_sort sort_by {|k| k.to_s.split(/((?:(?:^|\s)[-+])?\d+(?:\.\d+?(?:[eE]\d+)?(?:$|(?![eE\.])))?)/ms).map {|v| Float(v) rescue v.downcase}} end end</code></pre></div> <h3>How far down does this thing go?</h3> <p>I just noticed that &#8221;.1&#8221; sorts after &#8220;1&#8221;. Time for another tweak&#8230;</p> <div class="typocode"><pre><code class="typocode_default ">module Enumerable def sensible_sort sort_by {|k| k.to_s.split(/((?:(?:^|\s)[-+])?(?:\.\d+|\d+(?:\.\d+?(?:[eE]\d+)?(?:$|(?![eE\.])))?))/ms).map {|v| Float(v) rescue v.downcase}} end end</code></pre></div> <p>but that doesn&#8217;t work with version numbers like &#8221;.8.2&#8221;, &#8221;.10.2&#8221;...</p> <h4>Time passes&#8230; Thorin sits down and sings about gold</h4> <p>I was planning on giving an extension of the regex that caught this issue as well, but I&#8217;m afraid I&#8217;ve stumped myself &#8211; I can&#8217;t do it with a single regular expression unless I can use a fixed width lookbehind assertion, but they&#8217;re only available in Perl. Of course, it&#8217;s still possible to fix it, but doing so will take more thought than I have available to me at this time on a Sunday morning. And all this is before we get onto making sure that &#8220;1/2&#8221; sorts between &#8220;0&#8221; and &#8220;1&#8221;. And phone numbers. After all, &#8220;01915551238&#8221; is &#8216;obviously&#8217; the same as &#8220;0191 555 1238&#8221; and &#8220;0191 555-1238&#8221;, so they should end up next to each other in the sorted list.</p> <p>It looks like this is a &#8216;three pipe problem&#8217; after all. I shall probably return to this&#8230;</p> Sun, 16 Dec 2007 03:00:51 -0600 urn:uuid:a309756d-03d1-403e-99f6-c183d4509932 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/12/16/comprehensible-sorting-in-ruby#comments The Practice of Programming Ruby http://www.bofh.org.uk/articles/2007/12/16/comprehensible-sorting-in-ruby Rails tip: Side effect filters <p>Some bugs are easy to overlook. One that has a habit of catching me out is a Rails filter that returns false occasionally when it&#8217;s being evaluated purely for its side effects. Here&#8217;s how I&#8217;ve started working round the issue:</p> <div class="typocode"><pre><code class="typocode_default ">def side_effect_filter return if some_conditions_not_met? ... ensure return true end</code></pre></div> <p>What happens here is that the ensure catches any return and returns true instead. The catch is that if something throws an uncaught exception anywhere, it too gets caught by the ensure and true is returned. Which may not be what you were looking for. Here&#8217;s how to fix that issue:</p> <div class="typocode"><pre><code class="typocode_default ">def side_effect_filter error = nil return if some_conditions_not_met? ... rescue Exception =&gt; error ensure raise error if error return true end</code></pre></div> <p>This catches the exception in a rescue and stashes it in the <code>error</code> variable, then the ensure checks to see if an exception was thrown and rethrows it, otherwise, it just returns true. Which is bulletproof, but ugly. Let&#8217;s wrap the ugliness up in a method:</p> <div class="typocode"><pre><code class="typocode_default ">def self.side_effect(method, &amp;block) def_method(method) do error = nil begin instance_eval(&amp;block) rescue LocalJumpError # catches an explicit return rescue Exception =&gt; error ensure raise error if error return true end end end side_effect :side_effect_filter do return if some_conditions_not_met? ... end</code></pre></div> <p>Again, not pretty inside, but all we actually <em>care</em> about anywhere else is that the interface is good and does what it&#8217;s supposed to do. Encapsulated ugliness has its own beauty. Especially if you get the interface right.</p> <h3>Homework</h3> <p>This should pluginize quite nicely, just install the method in ActionController::Base and ActiveRecord::Base and you have a very useful tool, but I&#8217;m still not sure that the method name is right, so I&#8217;m holding off on it. If someone were to come up with a bulletproof name and release a plugin, that would be wonderful though.</p> <h3>Updates</h3> <p>Fixed a scoping issue in the encapsulated version of the code. Replaced <code>yield</code> with <code>instance_eval(&#38;block)</code></p> Mon, 08 Oct 2007 07:13:00 -0500 urn:uuid:1dc6683f-9c71-4da4-9981-a9a10a941a77 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/10/08/rails-tip-side-effect-filters#comments Ruby lazyweb rubyonrails http://www.bofh.org.uk/articles/2007/10/08/rails-tip-side-effect-filters My head hurts <p>During <span class="caps">DHH</span>&#8217;s keynote at RailsConf Europe it was apparent that there&#8217;s a great deal to like in edge rails, so I thought I&#8217;d have a crack at getting Typo up on it.</p> <p>Ow.</p> <p>I&#8217;d expected the pain points to be related to routing, but it seems that the rails routing system is approaching the level of the Excel calculation engine &#8211; nobody dares touch it for fear of breaking things, so typo&#8217;s custom routes seemed to work quite happily. There were a few things that have been deprecated, pluginized or moved out of the set of modules that&#8217;s automatically included when you do a <code>rake rails:freeze:edge</code>, but they were pretty easy to sort &#8211; the deprecation messages are a good deal more informative now than they were last time went deprecation squashing. There&#8217;s a surprising amount of stuff that&#8217;s been removed <em>without</em> any deprecation warnings though, which isn&#8217;t very sporting. <span class="caps">DHH</span> said there would likely be a 1.2.4 release (possibly a day before 2.0) with a bunch more deprecation warnings covering everything that&#8217;s <em>actually</em> going away, so if you&#8217;re thinking of moving a maturish app to Rails 2.0 it might make sense to wait for 1.2.4, install that, squash warnings, and move on up to 2.0.</p> <p>The real pain comes from themes. Typo&#8217;s themes rely on Rails internals working in a particular way, but they don&#8217;t work like that any more. In theory, the internals appear to be more theme friendly, related to allowing plugins to include views. The problem is, that it&#8217;s possible to change Typo&#8217;s theme without restarting the server, and the new themish internals don&#8217;t expect anything to change until the server&#8217;s restarted.</p> <p>So, I&#8217;ve been playing with plugins. The most promising approach appears to be that of the <a href="http://julik.textdriven.com/svn/tools/rails_plugins/themer/README">themer plugin</a>, which gets pretty close to doing what we need, and does it in a way that seems like it should work with both 1.2.3 and Edge Rails. It does appear to be making some radically different assumptions about the structure of the themes directory, but the basic framework is good and I should be able to make things work by making our current them object conform to Themer::Base&#8217;s interface and duck type my way to the sunny uplands of Edge Rails compatibility.</p> <p>Which will be nice.</p> <p>I like the themer approach a lot. Instead of monkeying about in the guts of rails, it monkeys about in <em>front</em> of Rails. It overrides <code>render</code> so that you can pass it a theme/lookup object. If it sees a lookup object, it uses that to rewrite the rest of the render arguments into a form that will render the right thing using the standard implementation of render. In a work project I&#8217;ve taken a similar approach to handling polymorphic routes for things like:</p> <div class="typocode"><pre><code class="typocode_default ">map.resources :pictures do |pics| pics.resources.comments end map.resources :users do |users| users.resources.comments end</code></pre></div> <p>I ended up with a <code>to_params</code> method defined on my <code>Comment</code> model, and stuck an extended <code>url_for</code> in front of the default Rails version, which looks something like:</p> <div class="typocode"><pre><code class="typocode_default ">def url_for_with_to_params(*arguments) if arguments[0].respond_to?(:to_params) with_options(arguments.shift.to_params) do |mapper| mapper.url_for_without_to_params(*arguments) end else url_for_without_to_params(*arguments) end end alias_method_chain :url_for, :to_params</code></pre></div> <p>Which is <em>so</em> much neater than the last time I attacked this particular problem (see the <a href="http://www.bofh.org.uk/articles/2007/01/25/initial-release-of-acts_as_resource">acts_as_resource</a> plugin).</p> <p>One of the nice things about Rails is that, although it&#8217;s opinionated and somewhat liberal with the syntactic vinegar for things the core team don&#8217;t think is the Right Way, they&#8217;re pretty good at leaving the door open for people like me who have other opinions. Both the themer plugin and my as yet unpluginized extension of <code>url_for</code> work by using existing capabilities in new ways and, because those <em>capabilities</em> are documented we can expect them to continue to work over multiple versions of Rails. Plugins that achieve similar effects by monkeying with Rails&#8217;s <em>internal</em> interfaces are hostages to fortune. Internal interfaces are free to change at any time, even between point releases, so a plugin can be left high and dry with surprising rapidity. Just ask the Rails Engines folk.</p> Sun, 23 Sep 2007 14:09:24 -0500 urn:uuid:1b4540f5-d2b4-4fac-b930-465f41608ca1 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/09/23/my-head-hurts#comments The Practice of Programming Ruby Typo http://www.bofh.org.uk/articles/2007/09/23/my-head-hurts A tiny ruby niggle <p>You know what? I&#8217;m starting to miss compulsory semicolons as statement terminators in Ruby.</p> <p>&#8220;What?&#8221; I hear you say. &#8220;But not needing semicolons is one of Ruby&#8217;s cardinal virtues! Are you mad?&#8221;</p> <p>I don&#8217;t think so, but maybe you&#8217;ll disagree after I explain further.</p> <p>Here&#8217;s a piece of code that I might write if semicolons were the only way of terminating a statement:</p> <div class="typocode"><pre><code class="typocode_default ">Category.should_receive(:find_by_permalink) .with('foo') .and_return(mock_category);</code></pre></div> <p>Or how about a complex find query</p> <div class="typocode"><pre><code class="typocode_default ">def find_tags_for(tag_maker, order = 'count') klass = tag_maker.class find :all , :select =&gt; 'tags.*, count(tags.id) count' , :group =&gt; Tag.sql_grouping , :joins =&gt; &quot;LEFT JOIN taggings ON &quot; + &quot; tags.id = taggings.tag_id &quot; + &quot;LEFT JOIN bookmarks ON &quot; + &quot; bookmarks.id = taggings.taggable_id &quot; + &quot; AND taggings.taggable_type = 'Bookmark' &quot; + &quot;LEFT JOIN #{klass.table_name} ON &quot; + &quot; #{klass.table_name}.id = bookmarks.#{klass.to_s.underscore}_id&quot; , :conditions =&gt; conditions_for(tag_holder) , :order =&gt; (order == 'count') ? 'count(tags.id) desc, tags.name' : &quot;tags.name&quot; , :readonly =&gt; true ; end</code></pre></div> <p>I first came across the idea of the leading comma in Damian Conway&#8217;s excellent <a href="http://www.amazon.co.uk/exec/obidos/ASIN/0596001738/justasummary-21">Perl Best Practices</a>. The idea is that, by leading with the comma it&#8217;s very easy to add a new argument to an argument list or hash specification without having to remember to stick a comma on the end of the preceding line if it was at the end, and also, the leading comma makes it very plain that the line is a continuation of its predecessor in some way.</p> <p>To make the examples work in Ruby, you have to add a <code>\</code> to the end of each line that has a continuation, so the first example has to be written:</p> <div class="typocode"><pre><code class="typocode_default ">Category.should_receive(:find_by_permalink) \ .with('foo') \ .and_return(mock_category);</code></pre></div> <p>Lining up the <code>\</code>s helps to stop them disappearing, but it&#8217;s an awful faff.</p> <p>What tends to happen (in the rails source especially) is that ruby programmers simply don&#8217;t break their lines up. A quick search of the rails source finds plenty of lines more than 160 characters long.</p> <p>Of course, some will argue that it doesn&#8217;t matter, that the old 80 column limit is a silly hangover from the days of steam when the only way to interact with your code was through an 80 column, green phosphor terminal. They have a point. An arbitrary line limit <em>is</em> silly, and we should get over it, especially in source code. However, unless you&#8217;re going to go around with every window open to its maximum width, lines <em>will</em> wrap, and they won&#8217;t do it nicely, or respect the indentation conventions of your language. Long lines are murder in diffs too, finding the point of difference is so much easier when your eye doesn&#8217;t have to scan an epic line.</p> <p>It&#8217;s a shame there&#8217;s no way of forcing ruby&#8217;s parser to <em>require</em> semicolons as statement terminators for those programmers like me who think that the restriction that a statement <em>must</em> end with a semicolon is worth the freedom to break lines where we like without needing to escape every line break. It&#8217;s a shame too that popular tools like Textmate are so clumsy when it comes to dealing with line breaks. I would attempt to hold Emacs up as a paragon in this respect, but its Ruby mode tends to get a wee bit bemused once you start breaking lines, so that&#8217;s no good.</p> <h3>Domino theory</h3> <p>It&#8217;s amazing how far reaching seemingly simple language design decisions can be isn&#8217;t it? Just getting rid of the need to terminate statements with a semicolon has an enormous effect on they way code in ruby looks. I&#8217;m just not sure that they look <em>better</em>.</p> <p>Maybe Smalltalk got it really right &#8211; they chose to use the most valuable syntactic character of all, the space, to denote sending a message. That freed up the <code>.</code> for use as a statement (sentence?) terminator. Then that freed up <code>;</code> for use in one of Smalltalk&#8217;s most distinctive patterns &#8211; the cascade. Where a Rails programmer might write:</p> <div class="typocode"><pre><code class="typocode_default ">form_for(@comment) do |f| f.input(:author) f.input(:title) f.input(:body) end</code></pre></div> <p>A Smalltalk programmer might eliminate the need for a temporary variable by doing:</p> <div class="typocode"><pre><code class="typocode_default ">Comment&gt;&gt;printOn: html (html formFor: self) input: #author; input: #title; input: #body.</code></pre></div> <p>All those <code>input: ...</code> messages get sent to the result of <code>html formFor: self</code>. Once you get the hang of it, it&#8217;s a really sweet bit of syntax.</p> <p>Incidentally, there&#8217;s been some discussion on the squeak mailing lists of a companion to the cascade, which would use a <code>;;</code> as a sort of &#8216;pipe&#8217;. The idea is to be able to replace code like:</p> <div class="typocode"><pre><code class="typocode_default ">((self collect: [:each | each wordCount) inject: 0 into: [:total :each| total + each]) printOn: aStream.</code></pre></div> <p>with</p> <div class="typocode"><pre><code class="typocode_default ">self collect: [:each | wordCount] ;; inject: 0 into: [:total :each | total + each] ;; printOn: aStream.</code></pre></div> <p>(NB: Please ignore what those code snippets <em>do</em>, because that&#8217;s gruesome. Concentrate on how they do it).</p> <p>Nobody&#8217;s quite proposed going as far as Haskell does with its Monads, which can be thought of as a magical land where the meaning of the semicolon changes according to what sort of Monad you&#8217;re in. (In an IO monad for instance, the semicolon imposes an evaluation order. In some other monad, the semicolon could just as easily denote a backtracking point). Then again, there&#8217;s nothing to <em>stop</em> the dedicated Smalltalker implementing something Monadish &#8211; every Smalltalk class can specify how its methods should be compiled after all&#8230;</p> <h3>In conclusion&#8230;</h3> <p>I&#8217;m not sure I&#8217;ve got a real conclusion for all this. I&#8217;m mostly musing. However, I do think it&#8217;s useful to think carefully about restrictions and what they free us to do as programmers. Lispers will wax lyrical about the way that their language&#8217;s pared down syntax lets them do amazing things with macros. Smalltalkers will defend to the death the idea that the only way to do anything is to send messages to objects. Pythonistas love their syntactic whitespace. Haskellers love their static typing (admittedly, they have an incredibly flexible notation for expressing type that leaves most other programming languages standing).</p> <p>And any English speaker with ears will know that a poem like Dylan Thomas&#8217;s <cite>Do Not Go Gentle Into That Good Night</cite> gains much of its power from it&#8217;s form, the villanelle, one of the most restricted forms of poetry there is. Two lines repeating through the poem and a staggering number of rhymes to find:</p> <blockquote> <p>Do not go gentle into that good night, <br/> Old age should burn and rave at close of day; <br/> Rage, rage against the dying of the light. <br/> Though wise men at their end know dark is right, <br/> Because their words had forked no lightning they <br/> Do not go gentle into that good night.<br/><br/> Good men, the last wave by, crying how bright <br/> Their frail deeds might have danced in a green bay, <br/> Rage, rage against the dying of the light.<br/><br/> Wild men who caught and sang the sun in flight, <br/> And learn, too late, they grieved it on its way, <br/> Do not go gentle into that good night.<br/><br/> Grave men, near death, who see with blinding sight <br/> Blind eyes could blaze like meteors and be gay, <br/> Rage, rage against the dying of the light.<br/><br/> And you, my father, there on the sad height, <br/> Curse, bless me now with your fierce tears, I pray. <br/> Do not go gentle into that good night. <br/> Rage, rage against the dying of the light.</p> </blockquote> <p>If that&#8217;s not making a virtue of a restriction, I don&#8217;t know what is.</p> Sun, 09 Sep 2007 02:51:00 -0500 urn:uuid:ab7799e2-e7d9-4802-b65e-07cecf9c03a1 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/09/09/a-tiny-ruby-niggle#comments Musings The Practice of Programming Ruby constraints smalltalk haskell poetry http://www.bofh.org.uk/articles/2007/09/09/a-tiny-ruby-niggle Today's noun is: Reification <blockquote> <p>Reification: The mental conversion of a person or abstract concept into a thing. Also, depersonalization, esp. such as Marx thought was due to capitalist industrialization in which the worker is considered as the quantifiable labour factor in production or as a commodity. &#8211; <span class="caps">OED</span></p> </blockquote> <p>In the sense that the <span class="caps">OED</span> has it, I&#8217;m not what you could call a fan of reification. At work, we have a rule that anybody who starts talking about &#8216;resources&#8217; when they mean &#8216;people&#8217; gets a (verbal) slap.</p> <p>However, in OO circles (or maybe just in my head), reification is a good thing. It&#8217;s the process of taking something abstract and turning it into a &#8216;real&#8217; object. Usually, the word gets used for big things like turning an intractable method into an object as a step on the way to refactoring that method. I tend to use it in a slightly broader sense. For me, reification is the process of turning something (a method or a data structure usually) into a full blown object with its own behaviour.</p> <p>Back when I was working on Pixie (a cunning, but weird, object persistence tool written in Perl) we had a data structure which was used for keeping track of managed objects. It started life as a hash. Everything was fine at first, but over time we ended up with more and more code being repeated across the codebase that was concerned with manipulating the cache hash. So, we replaced the hash with a new object and pulled all the repeated code into methods on that object, which gave us cleaner code to extend, and a strong feeling that we should have turned the cache into an object much earlier in the game. (By leaving it so long, we had a lot more code to move about, some of it in fairly obscure places; tracking down the last bit took a while.)</p> <p>Data structures like hashes and arrays are really useful in languages that have them. The catch is, they have this habit of acquiring code. When this starts to happen, it&#8217;s time to reify &#8211; to replace the hash with a task specific object. In Ruby, it&#8217;s easy enough to inherit from <code>Hash</code>, but Hash comes with a pile of methods that probably aren&#8217;t relevant to your particular need. Generally it&#8217;s better to delegate. The first cut doesn&#8217;t have to be that complicated, just decorate the hash with a new class and initialize an instance of the class at the point where you had just made the hash.</p> <p>Once that&#8217;s done, you can go through your code and move the bits that treat the hash as a data structure onto your new class. As you gather all the common behaviour to the new class, you&#8217;ll start to see places where you can improve code quality by merging common behaviours, replacing complex conditionals with polymorphism (you&#8217;ll probably have to introduce a factory method if you do that) and pulling hash keys out into instance variables.</p> <h3>Stalled reification</h3> <p>Reifying your data structure isn&#8217;t an end in itself, it&#8217;s a step along the way as you refactor your code.</p> <p>There&#8217;s an example of a stalled reification to be found in ActionController::Routing::Resources. Consider the implementations of <code>map_resource</code> and <code>map_singleton_resource</code>, which are the worker methods used whenever you do a <code>map.resource</code> or <code>map.resources</code> in your <code>routes.rb</code>.</p> <pre><code>def map_resource(entities, options = {}, &#38;block) resource = Resource.new(entities, options) with_options :controller =&gt; resource.controller do |map| map_collection_actions(map, resource) map_default_collection_actions(map, resource) map_new_actions(map, resource) map_member_actions(map, resource) if block_given? with_options(:path_prefix =&gt; resource.nesting_path_prefix, &#38;block) end end end def map_singleton_resource(entities, options = {}, &#38;block) resource = SingletonResource.new(entities, options) with_options :controller =&gt; resource.controller do |map| map_collection_actions(map, resource) map_default_singleton_actions(map, resource) map_new_actions(map, resource) map_member_actions(map, resource) if block_given? with_options(:path_prefix =&gt; resource.nesting_path_prefix, &#38;block) end end end </code></pre> <p>There&#8217;s a lot of repetition there. The only differences are the classes of the resource object, name of the second function called in the <code>with_options</code> block. If we take a look at, <code>map_collection_actions</code> things start to look even fishier. Here&#8217;s <code>map_collection_actions</code>, for example:</p> <pre><code>def map_collection_actions(map, resource) resource.collection_methods.each do |method, actions| actions.each do |action| action_options = action_options_for(action, resource, method) map.named_route("#{resource.name_prefix}#{action}_#{resource.plural}", "#{resource.path};#{action}", action_options) map.named_route("formatted_#{resource.name_prefix}#{action}_#{resource.plural}", "#{resource.path}.:format;#{action}", action_options) end end end </code></pre> <p><code>resource.collection_methods.each</code>? Let&#8217;s see what happens if we the various <code>map_foo_actions</code> methods into methods on <code>ActionController::Resources::Resource</code>. While we&#8217;re about it, we can rename <code>map_default_collection_actions</code> to <code>map_default_actions</code> on Resource, and <code>map_default_singleton_actions</code> to <code>map_default_actions</code> on SingletonResource, which inherits from Resource. <code>map_collection_actions</code> becomes:</p> <pre><code>def map_collection_actions(map) collection_methods.each do |method, actions| actions.each do |action| map.with_options(action_options_for(action, method)) do |m| m.named_route("#{name_prefix}#{action}_#{plural}", "#{path};#{action}") m.named_route("formatted_#{name_prefix}#{action}_#{plural}, "#{path}.:format;#{action}") end end end end </code></pre> <p>(we move <code>action_options_for</code> onto resource as well, of course).</p> <p>Once we&#8217;ve moved the various mapping helpers onto the resource classes, we can revisit <code>map_resource</code> and <code>map_singleton_resource</code></p> <pre><code> def map_resource(entities, options={}, &#38;block) resource = Resource.new(entities, options) with_options(:controller =&gt; resource_controller) do |map| resource.map_collection_actions(map) resource.map_default_actions(map) resource.map_new_actions(map) resource.map_member_actions(map) end if block_given? with_options(:path_prefix =&gt; resource.nesting_path_prefix, &#38;block) end end def map_singleton_resource(entities, options={}, &#38;block) resource = SingletonResource.new(entities, options) with_options(:controller =&gt; resource.controller) do |map| resource.map_collection_actions(map) resource.map_default_actions(map) resource.map_new_actions(map) resource.map_member_actions(map) end if block_given? with_options(:path_prefix =&gt; resource.nesting_path_prefix, &#38;block) end end </code></pre> <p>And now, we no longer have two method bodies that look very similar, apart from the resource class, we have to methods that look <em>identical</em> apart from the resource class. So, if we pull out the common bits and put them onto Resource, like so:</p> <pre><code> class ActionController::Resources::Resource def install_routes_in(map, &#38;block) map.with_options(:controller =&gt; controller) do |m| map_collection_actions(m) map_default_actions(m) map_new_actions(m) map_member_actions(m) end if block_given? map.with_options(:path_prefix =&gt; nesting_path_prefix, &#38;block) end end end </code></pre> <p>Then <code>map_resource</code> and <code>map_singleton_resource</code> become</p> <pre><code> def map_resource(entities, options = {}, &#38;block) Resource.new(entities, options).install_routes_in(self) end def map_singleton_resource(entities, options = {}, &#38;block) SingletonResource.new(entities, options).install_routes_in(self) end </code></pre> <h3>Where&#8217;s the benefit?</h3> <p>Apart from making the <code>active_record/lib/resources.rb</code> a bit shorter (a laudable result in itself), where&#8217;s the benefit here?</p> <p>From my own experience of implementing <code>datestamped_resource</code>, a routing plugin that we use in Typo, it makes the life of anyone writing a resource like routing helper for Rails a great deal easier. With <code>datestamped_resource</code> I ended up subclassing ActionController::Resources::Resource, doing the refactoring I&#8217;ve outlined here, but leaving the original Rails methods where they were and just implementing the &#8216;moved&#8217; methods on DatestampedResource (well, not quite, <code>map_collection_actions</code> is pretty different from the default Resource implementation, but the other actions are pretty much the same.</p> <p>In another project I&#8217;m working on, I&#8217;m trying to retain meaningful urls with (potentially) deep resource nesting, and it&#8217;d be really handy to have an <code>inflected_resource</code> route helper. The problem with using a meaningful <code>to_param</code> on your models is, avoiding permalinks that share a name with your actions. You could set up validations so that, say, &#8216;new&#8217; is an illegal permalinks, but it&#8217;s clumsy.</p> <p>However, if you arrange things so that your URLs are inflected, you can always tell that a <span class="caps">URL</span> that begins <code>/resource/new</code> will be a particular resource, with the permalink &#8216;new&#8217;, and <code>/resources/new</code> will be the virtual new resource.</p> <p>If the resource system is factored as I outlined, this is almost trivial, you can introduce a InflectedResource subclass of Resource</p> <pre><code> class InflectedResource &lt; Resource def member_path @new_path ||= #{path_prefix}/#{singular}/:id end end </code></pre> <p>and you&#8217;re pretty much done. Admittedly, something like that (plus a small amount of copy and paste) would work with the current system, but then we&#8217;re looking at 3 substantially identical methods in ActionController::Resources and if it wasn&#8217;t time to refactor before, it&#8217;d definitely be time to refactor then.</p> <h3>Conclusions</h3> <p>Reification shouldn&#8217;t be something you do every day, but nor should it be something you do once a flood. Take a look at some of your projects and some of the places where you&#8217;re using hashes. Are those <em>really</em> hashes, or would they benefit from having some behaviour of their own? You can track down stalled reification by looking for anaemic classes; classes which have a lot of accessors but very little behaviour. Once you&#8217;ve found an anaemic class, look for all the places that instances of it get used. Try moving some of the client code into methods on your anaemic class. Do that a few times and you&#8217;ll end up with a real object.</p> <p>If you&#8217;re fussy about never putting <span class="caps">HTML</span> in your models, you could end up with a mediating builder/presenter object as well, but until you start wanting to render the same structured info in different formats, I&#8217;d suggest biting the bullet and living with <span class="caps">HTML</span> in the model as a lesser evil than structural code. Your mileage may vary.</p> Wed, 22 Aug 2007 18:22:00 -0500 urn:uuid:3eced011-aa22-4695-9c13-85f654d50792 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/08/22/reification#comments Musings The Practice of Programming Ruby 5nouns http://www.bofh.org.uk/articles/2007/08/22/reification A cunning (evil?) trick with Ruby <p>One of the handy tools that Ruby makes available to us Domain Specific Pidgin builders is <code>instance_eval</code>. With <code>instance_eval</code> you can take a block that was created in one context, with all its lovely closed over local variables, and evaluate it in the context of an instance of an arbitrary object. Which means that any references to instance variables and calls to methods are made as if your block were a 0 argument method of that class. It&#8217;s really potent, but at the same time, a little frustrating.</p> <p>Frustrating? Why frustrating?</p> <p>Well, it would be <strong>really</strong> cool if you could call `instance_eval` with a block that took some arguments. That way, you could inject some values into the block from still another scope. (Yes, it&#8217;s arcane, but in the places where it would be handy it would be <strong>really</strong> handy).</p> <p>I just worked out how to do it:</p> <div class="typocode"><pre><code class="typocode_default ">def my_instance_eval(*args, &amp;block) return instance_eval(*args,&amp;block) unless block_given? &amp;&amp; !block.arity.zero? self.class.send(:define_method, :__, &amp;block) returning(__(*args)) do self.class.send(:remove_method, :__) end end</code></pre></div> <p>There&#8217;s problems with that though, the most obvious one being that there&#8217;s no guarantee that <code>__</code> won&#8217;t already exist as a method or that our block won&#8217;t <em>call</em> <code>__</code>. Here&#8217;s a safer, if scarier option:</p> <div class="typocode"><pre><code class="typocode_default ">def my_instance_eval(*args, &amp;block) return instance_eval(*args,&amp;block) unless block_given? &amp;&amp; !block.arity.zero? old_method = (self.class.instance_method(:__) rescue nil) self.class.send(:define_method, :__, &amp;block) block_method = self.class.instance_method(:__) if old_method self.class.send(:define_method, :__, old_method) else self.class.send(:remove_method, :__) end block_method.bind(self).call(*args) end</code></pre></div> <p>This should work even in the face of being called with something along the lines of <code>object.my_instance_eval(10) {|v| v + __}</code>. Of course, there would be no point in calling like that. You&#8217;d only really need it when you want to do something like <code>object.my_instance_eval(10,&#38;a_block_param)</code>.</p> <p>In the project I&#8217;m currently working, where the need for this arose, I shall probably extract the body of <code>my_instance_eval</code> to <code>Proc#to_unbound_method</code>, that way, instead of hanging onto Block objects I can hang onto UnboundMethod objects and avoid repeatedly shuffling methods.</p> <h3>But&#8230; how does it work?</h3> <p>I hope the code&#8217;s reasonably obvious. However&#8230;</p> <p>The essence of it is that real methods get to take arguments, so what we need is some way of turning our block into a real method without altering the behaviour/interface of our object. Ruby does allow us create <code>UnboundMethod</code> objects which can be thought of as anonymous methods. To use them you have to bind them to a specific instance and then call them, which is the last thing we do in <code>my_instance_eval</code>. The intervening code is what turns our Proc into an <code>UnboundMethod</code>. First, we stash the old <code>__</code> method, or a <code>nil</code> if there wasn&#8217;t one. Then we define a new <code>__</code> using our block, and immediately use <code>instance_method</code> to get it back as an <code>UnboundMethod</code>. Then we either replace the old definition of <code>__</code> or simply remove the new one, restoring the original behaviour of our class. Then we bind our new anonymous method to <code>self</code> and call it with our arguments. Easy.</p> <h3>Exercises for the interested reader</h3> <ul> <li>What happens if our class has <code>method_removed</code> or <code>method_added</code> implemented? Can we &#8216;hide&#8217; from them? How?</li> <li>What does <code>Proc#to_unbound_method</code> look like? Does it need to take an argument?</li> </ul> Thu, 16 Aug 2007 01:28:00 -0500 urn:uuid:950b48b4-3db6-437f-9b09-cc84a0a8e4aa pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/08/16/a-cunning-evil-trick-with-ruby#comments Ruby http://www.bofh.org.uk/articles/2007/08/16/a-cunning-evil-trick-with-ruby Doing the fixture thing <p>Fixtures suck! Mocks rock! Don&#8217;t you <em>dare</em> let your tests touch the database!</p> <p>Well&#8230; yes&#8230; I suppose. Except, mocking can be a complete pain in the arse too (made slightly less of a pain in the arse if you use the null object options) &#8211; it&#8217;s awfully easy to end up with huge long setup methods that spend all their time faking out a mock object and about two lines testing what you need.</p> <p>I&#8217;m sure someone&#8217;ll be along to argue that this is evidence of lazy design on my part. Well, &#8220;Yah boo sucks!&#8221; to the lot of &#8216;em. Fixtures can be exceedingly useful.</p> <h3>Spooky action at a distance</h3> <p>The biggest problem I have with Rails&#8217; current implementation of fixtures is&#8230; oh, where to start&#8230; it&#8217;s probably the action at a distance aspect of them. Your test is here, but your fixture is defined some way over there, in a random collection of yaml files.</p> <p>Then there&#8217;s the problem of remembering <em>which</em> fixtures you need to have loaded for a particular test, and it all starts getting horrible very quickly.</p> <p><a href="http://errtheblog.com/post/7708">One way</a> of addressing this is to use fixture scenarios and fixture scenario builder, which works around the problem of remembering what to load and means you don&#8217;t have to write your fixtures in <span class="caps">YAML</span>. What it doesn&#8217;t work around is the action at a distance issue (but I&#8217;m betting it wouldn&#8217;t be too hard to repurpose the fixture scenario builder to let you declare the fixtures you need for a particular test/spec in the same place as you do the testing).</p> <p>At work though, we came up with another way of making it easy to build your fixtures right in the test file. Our current approach is still a little bit clunky, and it&#8217;s nowhere near the point where I can turn it into a library, but I think it&#8217;s worth discussing anyway.</p> <h3>Exemplars</h3> <p>The question to ask is, what do you use a fixture for? Most of the time, what a test needs is a mostly generic instance of your class which will pass the validations, and which has maybe a couple of attributes set to particular values.</p> <p>Let&#8217;s say you have a user class. As is common with such things, your user has a username, an email address and a password. As is so often the case, the usernames and email addresses must be unique, and the password must not be blank. Let&#8217;s say you&#8217;re working on a tagging system (isn&#8217;t everyone). Here&#8217;s the sort of specification you might write:</p> <div class="typocode"><pre><code class="typocode_default ">context &quot;A taggable object&quot; do setup do # makes a taggable object and a couple of users end it &quot;Should aggregate taggings&quot; do @first_user.tag(@taggable, &quot;tag&quot;) @second_user.tag(@taggable, &quot;tag&quot;) @taggable.save!; @taggable.reload @taggable.should have(1).tags end end</code></pre></div> <p>In this context, the only thing you need from those user objects is that they behave like @users, are distinct and valid. You could simply set up a couple of users your users.yml fixture, but the approach we took at work went something like this:</p> <div class="typocode"><pre><code class="typocode_default ">class User class &lt;&lt; self @@exemplar_count = 0 def exemplar(overrides = {}) @@exemplar_count += 1 with_options(:username =&gt; &quot;user#{@@exemplar_count}&quot;, :email =&gt; &quot;user#{@@exemplar_count}&quot;, :password =&gt; &quot;fredisabadpassword&quot;) do |maker| maker.new(overrides) end end def create_exemplar(overrides = {}) returning(exemplar(overrides)) {|user| user.save} end def create_exemplar!(overrides = {}) returning(exemplar(overrides)) {|user| user.save!} end end end</code></pre></div> <p>This lets us write setup code like:</p> <div class="typocode"><pre><code class="typocode_default ">setup do @first_user = User.create_exemplar! @second_user = User.create_exemplar! @taggable = ... end</code></pre></div> <p>In tests where you need an exemplar with a specific property, you can write <code>Model.exemplar(:tested_attribute =&gt; specific_value)</code> &#8211; the way the overrides work means you only have to describe the &#8216;interesting&#8217; bits and the obscuring dust involved in simply building a valid object is swept under the carpet.</p> <h3>Homework</h3> <ul> <li>If you&#8217;re familiar with the <a href="http://www.martinfowler.com/bliki/ObjectMother.html">Object Mother</a> pattern, this might seem a little familiar, with the wrinkle that, instead of having a factory class, we just push the exemplar builder directly onto the model class.</li> </ul> <ul> <li>If you start implementing exemplars yourself, you&#8217;ll probably spot a good deal of repetitive coding. I&#8217;ve not extracted a library yet because I&#8217;ve not quite come up with an interface that I like. Can you come up with a good way of doing it? Can you implement it?</li> </ul> <ul> <li>What did I miss?</li> </ul> Sun, 05 Aug 2007 02:39:00 -0500 urn:uuid:a5a3858c-741d-49e7-b4b9-a798f7dd27e9 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/08/05/doing-the-fixture-thing#comments The Practice of Programming Ruby http://www.bofh.org.uk/articles/2007/08/05/doing-the-fixture-thing Deja vu all over again <p>Back when I was still programming Perl, one of the common mistakes that you&#8217;d see when people wrote lazily initialized object accessors was code like:</p> <div class="typocode"><pre><code class="typocode_default ">sub get_content { my($self) = @_; $self-&gt;{content} ||= 'default content'; }</code></pre></div> <p>Code written like this would trundle along quite happily, until you had an attribute where, say, the empty string or 0 were legal values for the attribute. The problems were especially painful when the default value wasn&#8217;t something that perl treated as false. The correct way of writing that code would be:</p> <div class="typocode"><pre><code class="typocode_default ">sub get_content { my($self) = @_; unless (exists($self-&gt;{content})) { $self-&gt;{content} = 'default content' } $self-&gt;{content} }</code></pre></div> <p>Which is substantially uglier, but safe.</p> <p>Safety&#8217;s important, especially in building block code like accessor methods. An accessor method that works 99.99% of the time is like a compiler that produces correct code 99.99% of the time &#8211; useless.</p> <h3>Why déjà vu?</h3> <p>Recently, the usually spot on Jay Fields <a href="http://blog.jayfields.com/2007/07/ruby-lazily-initialized-attributes.html">wrote up</a> the lazy initialization pattern for Ruby. I&#8217;m not entirely sure that I agree with his motivation for the pattern, but I am concerned by his suggested code transformation. He suggests writing your lazy initialization as:</p> <div class="typocode"><pre><code class="typocode_default ">def content @content ||= [] end</code></pre></div> <p>Does that look familiar? This is subject to exactly the same potential bug as the perl code above. Admittedly, the number of possible &#8216;bad&#8217; values is reduced to <code>nil</code> and <code>false</code>, but it only takes one. Here&#8217;s the fix:</p> <div class="typocode"><pre><code class="typocode_default ">def content unless instance_variable_defined? :@content @content = [] end return @content end</code></pre></div> <p>This code is guaranteed to work in all circumstances.</p> <h3>Going a little bit further&#8230;</h3> <p>As Mark Jason Dominus has argued persuasively elsewhere, <a href="http://blog.plover.com/prog/design-patterns.html">patterns are a sign of weakness in a programming language</a>, so how can we go about incorporating this boilerplate code into our language<sup><a href="#fn1">1</a></sup>.</p> <p>How about something like this (as yet untested):</p> <div class="typocode"><pre><code class="typocode_default ">class Module class &lt;&lt; self alias_method :attr_reader_without_default_block, :attr_reader def attr_reader_with_default_block(*args, &amp;default_block) unless block_given? return attr_reader_without_default_block(*args) end unless args.size == 1 raise ArgumentError, &quot;Expected 1 argument&quot; end var_name = &quot;@#{args.first.to_s}&quot; self.define_method(args.first) do unless instance_variable_defined?(var_name) self.set_instance_variable(var_name, default_block.call(self)) end (class &lt;&lt; self; self; end).attr_reader_without_default_block(args.first) return self.send(args.first) end end alias_method :attr_reader, :attr_reader_with_default_block end end</code></pre></div> <p>This code is a little more complex than the boilerplate code. When the generated method is called, possibly initializing the attribute, the <code>(class &lt;&lt; self; self; end).attr_reader_without_default_block(args.first)</code> part replaces the instance&#8217;s accessor with the default <code>attr_reader</code> implementation and calls that instead. This is arguably premature optimization, but it&#8217;s not all that evil&#8230;</p> <p>Assuming I&#8217;ve not screwed anything up, that should allow you to write.:</p> <div class="typocode"><pre><code class="typocode_default ">class Article attr_reader :content {'default content'} end</code></pre></div> <p>and have your <code>content</code> lazily initialized. Extending this to let <code>attr_writer</code> take a block too is a reasonably obvious next step.</p> <p>Extending this lazy initialization approach to work with ActiveRecord based classes is probably the next step after that. Making it work right probably involves a little bit of fossicking around in the workings of ActiveRecord, but it&#8217;s far from impossible.</p> <p id="fn1"><sup>1</sup> I tend to take the Smalltalkish view that it&#8217;s pointless to separate language from library, especially in a dynamic language. A sufficiently expressive language lets you blur the boundary between them.</p> Sun, 29 Jul 2007 18:18:00 -0500 urn:uuid:df256f04-150d-4055-a59c-32f348bccee8 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/07/29/deja-vu-all-over-again#comments Ruby lazyinitialization http://www.bofh.org.uk/articles/2007/07/29/deja-vu-all-over-again How I learned to stop worrying and love aggressive mockery <p>There&#8217;s something enormously liberating about writing an <a href="http://rspec.rubyforge.org/">RSpec</a> description that starts like:</p> <div class="typocode"><pre><code class="typocode_default ">describe ArticlesController, &quot;feeds:&quot; do before do @the_mock = mock('everything', :null_object =&gt; true) ActiveRecord::Base.stub!(:find).and_return(@the_mock) end it &quot;/articles.atom -&gt; atom feed&quot; do get :index, :format =&gt; 'atom' response.should render_template('_atom_feed') end ... end</code></pre></div> <p>The <code>:null_object</code> flag to rspec&#8217;s <code>mock</code> function is remarkably potent.The resulting mock will return itself from any method call that hasn&#8217;t got some other expectation set up. When I&#8217;m testing that my index methods render the appropriate views for the format, I don&#8217;t care that all the various variables have been set up correctly &#8211; I&#8217;ve already tested that in another description &#8211; I just want to get to the point where I&#8217;m about to render a template.</p> <p>What this does is decouple my tests. I can change the way that the index method fetches its stuff from the database and I&#8217;m only going to have to change the innards of the specs that test that.</p> <p>I tend to think of this as being analogous to the object oriented pattern of trying to write your methods at a single level of abstraction. Within a given spec, I should only be setting up expectations that are directly related to what I&#8217;m testing.</p> Wed, 06 Jun 2007 05:21:00 -0500 urn:uuid:2e16fe59-e574-4b39-9cd8-5f38bf91a873 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/06/06/how-i-learned-to-stop-worrying-and-love-aggressive-mockery#comments The Practice of Programming Ruby Typo http://www.bofh.org.uk/articles/2007/06/06/how-i-learned-to-stop-worrying-and-love-aggressive-mockery What the? <p>Wow:</p> <div class="typocode"><pre><code class="typocode_default ">$ rake spec ... 156 examples, no failures $ ./script/spec spec ... 156 examples, 2 failures $ rake [unit tests, all pass] [functional tests, all pass] [specs...] 156 examples, 2 failures</code></pre></div> <p>For extra points, the 2 failures from running the plain <code>rake</code> are not the same as the failures from running <code>./script/spec spec</code>. And if I run <code>./script/spec spec</code> after a full <code>rake</code> run, I get a host of extra failures.</p> <p>I wonder what I&#8217;m doing to so comprehensively screw up test isolation.</p> <p>Ho hum.</p> Sun, 13 May 2007 03:42:00 -0500 urn:uuid:8c7bd369-f657-4534-839e-f9862d62b625 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/05/13/what-the#comments Ruby Typo testisolation http://www.bofh.org.uk/articles/2007/05/13/what-the Things which are fun <p>It&#8217;s definitely fun to commit a major rework of something that&#8217;s been bugging you to <span class="caps">SVN</span>. It&#8217;s slightly less fun to check it out in your production server and have it fall over until you remember you to retweak the environment.rb file.</p> <p>Anyhow, we&#8217;re now running on Typo 4.1.1+r1438. <a href="http://blog.typosphere.org/articles/2007/05/08/its-here-its-new-its-improved-its">Typo 4.1.1</a> got released last night and, pretty much as soon as it had cleared the gates I checked in a major rework of the Article and Feedback state mechanisms.</p> <h3>What state mechanisms?</h3> <p>When you&#8217;re modelling blog posts, and comments, it&#8217;s very easy to think of them in terms of simple status flags. An article is published, or its a draft, so we have a <code>#published</code> boolean and we&#8217;re done.</p> <p>Except, what about an article that you want to publish at a specific time? And how do we work out when to send notifications and trackback pings? Should you send the pings again when an article is first published then withdrawn, then published again?</p> <p>It&#8217;s complicated, and you can end up with a rats nest of complex conditional code.</p> <p>So, you work out that an article can be in one of several states. We went with <code>:new</code>, <code>:draft</code>, <code>:just_published</code>, <code>:published</code>, <code>:publication_pending</code>, <code>:just_withdrawn</code> and <code>:withdrawn</code>, and we used the State Pattern to handle this. All our tangled conditionals were replaced with simple delegations to the state object. There&#8217;s still <em>some</em> conditional code, but there&#8217;s a great deal less of it now.</p> <p>Until recently, we implemented the states using Rails&#8217;s <code>composed_of</code> helper, but it&#8217;s not really suited to the task &#8211; you know your code isn&#8217;t happy when you find yourself calling a class <code>ContentState::Factory</code> and overriding its <code>new</code> method. It was also really hard to divine the workings of the state machine.</p> <p>So, during a discussion of <a href="http://giantrobots.thoughtbot.com/2007/5/1/coding-without-ifs">Coding without ifs</a> I found myself sketching a way of setting up a state field declaratively and thought to myself &#8220;Hey, I could implement that for Typo and make things a good deal clearer&#8230;&#8221;</p> <p>So I did.</p> <p>Now, if you look at the top of <code>article.rb</code>, you&#8217;ll find:</p> <div class="typocode"><pre><code class="typocode_default "> has_state(:state, :valid_states =&gt; [:new, :draft, :publication_pending, :just_published, :published, :just_withdrawn, :withdrawn], :initial_state =&gt; :new, :handles =&gt; [:withdraw, :post_trigger, :after_save, :send_pings, :send_notifications, :published_at=, :published=, :just_published?]) include States</code></pre></div> <p>And it sets up the delegations (as well as a set of <code>#new?</code>, <code>#draft?</code>, ... predicates based on the names of the valid states) for you. I pulled the States module out into a separate <code>article/states.rb</code> file, but given a simple set of states there&#8217;s no reason not to declare them inline.</p> <p>I&#8217;m really pleased with it. I&#8217;ll probably do a bit more work on the interface (I want it to be more language like), add a <code>has_strategy</code> declaration (which I intend to use for our feedback spam checking system) and then extract a plugin from it. If you&#8217;re interested in doing something similar in your own code right now, the thing you need to pinch is <code>lib/stateful.rb</code> in the Typo distribution, and the only documentation is the source. Check <code>app/models/feedback/states.rb</code> and <code>app/models/article/states.rb</code> for examples of states written to this interface.</p> Tue, 08 May 2007 02:12:00 -0500 urn:uuid:8ff4e40a-a647-4e3e-ba5c-fa989c904254 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/05/08/things-which-are-fun#comments Ruby Typo http://www.bofh.org.uk/articles/2007/05/08/things-which-are-fun 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 Things which aren't fun <p>Let&#8217;s say you&#8217;re running tests against your rails application and a test fails.</p> <p>&#8220;Hmm&#8230;&#8221; you think, &#8220;I wonder what could be causing that, let&#8217;s run that test file by itself.&#8221;</p> <p>The test passes.</p> <p>&#8220;Okay&#8230; I wonder if it&#8217;s the rake test loader, let&#8217;s run that test file using that.&#8221;</p> <p>The test passes</p> <p>&#8220;Right, it&#8217;s only the third test file on the list that&#8217;s failing, let&#8217;s try running just the first 3 test files.&#8221;</p> <p>The test fails.</p> <p>&#8220;Okay, so it&#8217;s one of the first two test files that&#8217;s causing the problem. Let&#8217;s remove one and see what happens.&#8221;</p> <p>The test passes.</p> <p>&#8220;Right, because I&#8217;m paranoid, let&#8217;s try running it with the other test file instead. It should fail.&#8221;</p> <p>The test passes.</p> <p>&#8220;Hmm&#8230; the failure appears to be fixture related, let&#8217;s try turning of <code>use_transactional_fixtures</code> in <code>test_helper.rb</code> and running the failing set of tests again.&#8221;</p> <p>The test passes.</p> <h3>Houston, we have a problem</h3> <p>Part of our problem is that Typo is so huge and old, and its test suite is somewhat spotty. Something we&#8217;re doing in the workings of a couple of our controllers is confusing transactional fixtures and that can&#8217;t be good. I suppose my first step is to get all the tests that are still failing with transactional fixtures turned off passing and see if that solves my transactional problem, but I can&#8217;t pretend it&#8217;s a fun option.</p> Mon, 07 May 2007 09:13:00 -0500 urn:uuid:41dacd60-094c-4157-bd28-13967abbc5e4 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/05/07/things-which-arent-fun#comments Ruby Typo http://www.bofh.org.uk/articles/2007/05/07/things-which-arent-fun Rails, CRUD, REST and the importance of adjectives <p>Consider a web request:</p> <pre><code>GET /articles/2007/04/17/adjectives-rule;edit</code></pre> <h3>&#8220;What does it <em>mean?&#8221;</em></h3> <p>If we pass it through the prism of Rails routing, it breaks apart as follows:</p> <dl> <dt><code>GET</code></dt> <dd>The <code>:method</code>, sometimes called the verb.</dd> <dt><code>/articles</code></dt> <dd>The <code>:controller</code>, the thing that&#8217;s going to handle this request</dd> <dt><code>/2007/04/17/adjectives-rule</code></dt><dd>Parameters, passed to the controller method that handles this request</dd> <dt><code>;edit</code></dt><dd>The <code>:action</code>, some way of specifying what this request does</dd> </dl> <p>It&#8217;s certainly one way of looking at it, but if you do I think you&#8217;re limiting your understanding of what it means to program in a RESTful fashion. It&#8217;s an obvious fit for Rails where the dispatcher builds an appropriate controller and then does <code>controller.send params(:action)</code>[1] but it&#8217;s a very &#8216;imperative&#8217; view and that&#8217;s not necessarily a good view. The problem is that <code>:action</code> at the end.</p> <p>What&#8217;s happening is that Rails&#8217;s implementation is leaking into the abstraction that is the <span class="caps">URL</span>. If you let that happen you end up programming with <acronym title="Create, Read, Update, Delete">CRUD</acronym>dy blinkers.</p> <p>Let&#8217;s try another way of breaking that request up into &#8216;parts of speech&#8217;. Here&#8217;s what I think the request means: &#8220;Get me the editor for the article posted on 2007-04-17 called &#8216;adjectives-rule&#8217;&#8221;. <code>;edit</code> isn&#8217;t an action selector, it&#8217;s a <em>view</em> selector.</p> <h3>&#8220;Isn&#8217;t this just navel gazing?&#8221;</h3> <p>At the London Ruby Users&#8217; Group on Monday, there was an occasionally heated discussion of RESTful programming in which several people expressed the view that <span class="caps">REST</span> was limiting because they &#8220;needed more than 4 verbs&#8221; for their application.</p> <p>Much of the discussion of RESTful programming on Rails has been about how to break things down so that you can think of your application in <span class="caps">CRUD</span> terms, and that&#8217;s a terribly limiting way to view things.</p> <p>Let&#8217;s look at another request and see how to interpret it.</p> <code><pre> POST /articles/new;preview Content: article[title]=Adjectives+Rule; article[body]=... </pre></code> <p>If you break this request up along the lines suggested by rails, then it seems that this isn&#8217;t a RESTful request. It&#8217;s POSTing something, which means its creating a new resource, but that resource isn&#8217;t going in the datatabase. Wha?</p> <p>I think this is perfectly RESTful though. What we&#8217;re saying is &#8220;Make me a new preview of the article described in the body of the request&#8221;. The <span class="caps">POST</span> part of the request implies &#8216;make something&#8217;, the rest of the request describes what to make. Our controller knows that articles created for preview are not persistent, so they don&#8217;t go in the database. The preview you create and then throw away is just as much a resource as the finished article, the only difference being that every preview gets thrown away.</p> <p>Looked at like this, it&#8217;s apparent RESTful programming is much richer than the basic 4 <span class="caps">CRUD</span> actions. The important principles to bear in mind are:</p> <dl> <dt><span class="caps">GET</span> must not alter any resource</dt> <dd>This is the really, really, really big one. If you&#8217;re ever tempted to write a method that interprets a <span class="caps">GET</span> request and changes the state of the resource being fetched&#8230; well, think again.</dd> <dt>Statelessness</dt> <dd>This is the idea that the request itself contains all the information the server needs to build the response. No session cookies. There are those who argue for no cookies at all, but until browsers handle <span class="caps">HTTP</span> authentication better I think we&#8217;re stuck with cookie based authentication, but the cookie should really be self contained and not an opaque reference into a catch all session table.</dd> <dt><code>POST</code>, <code>PUT</code> and <code>DELETE</code> should act appropriately</dt> <dd><code>POST</code> makes new stuff, <code>PUT</code> changes old stuff, <code>DELETE</code> removes old stuff. Not that hard to understand. The only wrinkle is that browsers don&#8217;t know how to make <code>PUT</code> and <code>DELETE</code> requests. Your <span class="caps">AJAX</span> actions will make them happily, but if use them in a form field, the browser will be confused. Because you can&#8217;t simply use JavaScript everywhere, you&#8217;re stuck tunneling those request types through <span class="caps">POST</span>. Rails has mechanisms to hide the tunnelling from you.</dd> <dt>Persistent URLs</dt> <dd>If you <span class="caps">GET</span> something from <code>/some/where/or/other</code> today, you should be able to get it there tomorrow unless it&#8217;s been deleted. If the resource has been moved, the right thing to do is to respond with a redirect (permanent or temporary as appropriate). Serving up an entirely new resource is right out. Which doesn&#8217;t mean you can&#8217;t have a resource like <code>/articles/at_random</code> &#8211; the resource you&#8217;re getting isn&#8217;t the article you receive, but &#8216;a randomly chosen article&#8217;. What would be bad would be having <code>/articles/at_random</code> not expire for 10 days.</dd> </dl> <h3>&#8220;You haven&#8217;t mentioned adjectives yet&#8230;&#8221;</h3> <p>This article is a write up of something that occurred to me during a conversation after Monday&#8217;s <span class="caps">LRUG</span> meeting. Someone (whose name I either didn&#8217;t get or forgot) asked me what was the point of using RESTful principles in the first place. During the course of my answer, it suddenly clicked that what Rails calls actions aren&#8217;t really actions; they are adjectives. So, when I sat down to write this, I was expecting that that&#8217;s what I was going to say. But the trouble with late night pub conversation insights is that they aren&#8217;t always accurate or complete. As I wrote, I realised that my basic insight that an <code>:action</code> isn&#8217;t really an action was okay, but an <code>:action</code> is actually a view (I think it might be a controller when you&#8217;re POSTing though, just not a Rails controller).</p> <h3>&#8220;I&#8217;m curious now, what is the point of using RESTful principles?&#8221;</h3> <p>RESTful programming is a discipline. It&#8217;s a set of practices and patterns that help you make good decisions about how to solve problems in your application domain in a consistent way. The hope is that, by being rigorous in your application of the principles, you&#8217;ll end up with a website that&#8217;s easy to use, easy to cache and easy to scale. Certainly many RESTful practices are just out and out good practices.</p> <p>There are other disciplines. <a href="http://www.seaside.st">Seaside</a> is one. As Avi has <a href="http://www.windley.com/archives/2007/03/applied_web_heresies_etech_2007.shtml">shown</a> recently, Seaside isn&#8217;t a smalltalk application framework, it&#8217;s a state of mind, and a weird one at that.</p> <h3>A thought</h3> <p>Here&#8217;s a little something to consider:</p> <h4>Thesis</h4> <p>Rails</p> <h4>Antithesis</h4> <p>Seaside</p> <h4>Synthesis</h4> <p>I dunno, but I&#8217;m looking forward to it.</p> <h3>Coming up</h3> <p>I plan to take a closer look at some of the principles and patterns of RESTful architecture and discuss how to apply them in Rails.</p> <p id="fn1"><sup>1</sup> Almost certainly not exactly what happens, but close enough for jazz.</p> Wed, 18 Apr 2007 03:23:00 -0500 urn:uuid:deef362c-b99c-46a9-b869-7bde5852aaaa pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/04/18/rails-crud-rest-and-the-importance-of-adjectives#comments The Practice of Programming Ruby RESTfulness http://www.bofh.org.uk/trackbacks?article_id=rails-crud-rest-and-the-importance-of-adjectives&day=18&month=04&year=2007 http://www.bofh.org.uk/articles/2007/04/18/rails-crud-rest-and-the-importance-of-adjectives Mmm... parsers <p>So, in my quest to get Rails routes to accept routes like:</p> <pre><code>articles/:comment[article]/comments/:comment[id]</code></pre> <p>I&#8217;ve been playing with parsers for the first time in my programming career. Quite how I&#8217;ve managed to get this far without them I leave as an exercise for the interested reader.</p> <p>At the moment I have a parser that will parse</p> <pre><code>articles/2007/05/12/slug</code></pre> <p>and give back an <code>ActionSelector</code> that yamlizes as</p> <code><pre> --- !ruby/object:ActionSelector controller: articles action: show params: :article: :year: 2007 :month: 05 :mday: 12 :slug: slug </pre></code> <p>Which can be easily turned into the kind of params hash that rails wants from its routing system in order to dispatch the request to the right place.</p> <p>For my next trick, I need refactor the parser I have so that it&#8217;s generated via a set of parser builders. Then I need to write a parser for routing specifiers that can use those builders to build a <span class="caps">URL</span> parser.</p> <p>It&#8217;s a simple matter of programming I tell you.</p> <h3>Updates</h3> <h4>RouteBuilder works (2007041608:00ish)</h4> <p>I now have a <code>RouteBuilder</code> that generates routes and has the same interface as <code>ActionController::Routing::RouteBuilder</code>.</p> <p>My <code>Route</code> doesn&#8217;t have the same interface as <code>AC::Routing::Route</code> yet, but it&#8217;s not far off. The fun part is working out which bits of the interface are essential and which can be safely ignored. I&#8217;m hoping that I won&#8217;t have to rewrite <code>AC::Routing::RouteSet</code> as well, but I&#8217;m not sure how complicit it is with the innards of <code>AC::Route</code>.</p> <h4>Routes can generate paths from options (2007041612:30)</h4> <div class="typocode"><pre><code class="typocode_default ">context &quot;Given a default route&quot; do setup do @route = RouteBuilder.new.build('/:controller/:action/:id') end def gen(hash) # Rails interface is a bit surprising @route.generate(hash.dup, hash.dup, {}) end specify &quot;generation works&quot; do gen(:controller =&gt; 'accounts', :action =&gt; 'show', :id =&gt; 1) \ .should == '/accounts/show/1' gen(:controller =&gt; 'accounts', :id =&gt; 1) \ .should == '/accounts/index/1' gen(:controller =&gt; 'accounts', :action =&gt; ':index') \ .should == '/accounts' end end</code></pre></div> <p>It&#8217;s nowhere near complete, but I&#8217;m being gung ho and starting to integrate my RouteBuilder with Rails. Then I can start pulling the Rails routing tests into my own test suite and get some confidence with its robustness before I start adding the ability to handle routes like <code>/books/:tune[book][id]/tunes/:tune[id]</code>, which is why I started this in the first place.</p> <p>With any luck and some good train hacking time on the way to London I should have something good to show at <span class="caps">LRUG</span> this evening.</p> Sat, 14 Apr 2007 14:13:00 -0500 urn:uuid:f3da7a2d-e9a8-4358-aec7-93e2ea0b0512 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/04/14/mmm-parsers#comments Ruby railsrouting parsing http://www.bofh.org.uk/articles/2007/04/14/mmm-parsers Wanted: module/starter.rb <p>I sometimes think that one of the reasons that <span class="caps">CPAN</span> is such a huge advantage for Perl is the ease with which you can <em>contribute</em> to it. It&#8217;s all very well having a tool for installing libraries from the archive, any fool can do that, but <span class="caps">CPAN</span> has tools for getting started with a new library too.</p> <p>If I want to start a new Perl project, I do:</p> <pre><code>module-starter --module=AuthenticationFairy</code></pre> <p>and the script goes away and builds me an AuthenticationFairy directory complete with all the boilerplate stuff filled in. I know that when I look in <code>AuthenticationFairy</code> I&#8217;ll find a sensible directory structure, a <code>Makefile.PL</code> that will do the right thing, a <code>lib/AuthenticationFairy.pm</code> with the documentation boiler plate filled in and a test directory. And I rejoice because my yaks have been sh aved and I can get on with the interesting business of writing my first test and making sure it fails.</p> <p>I&#8217;ve not found an equivalent for Ruby. Yet.</p> <p>I have found <code>sow</code>, which is part of the <a href="http://blog.zenspider.com/archives/2007/02/hoe_version_120_has_been_released.html">Hoe</a> package, which is definitely a start.</p> <p>Are there any other tools along the lines of Module::Starter that I&#8217;ve missed?</p> Sat, 14 Apr 2007 04:17:00 -0500 urn:uuid:0576b3a5-1a45-48a6-9d14-2a288d8a2cae pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/04/14/wanted-module-starter#comments Ruby hoe sow module starter http://www.bofh.org.uk/articles/2007/04/14/wanted-module-starter You are in a maze of little, twisty evals, all similar. <p>Rails routing is making my head hurt. It&#8217;s starting to remind me of the guts of perl&#8217;s regular expression engine, which was said to be understood by three people, plus or minus five.</p> <p>I just want to write routes like <code>/articles/:art[year]/:art[month]/:art[mday]/:art[slug]</code>.</p> <p>I&#8217;m seriously considering starting again from scratch, which can&#8217;t be right.</p> Thu, 12 Apr 2007 02:06:00 -0500 urn:uuid:0c4ef14e-d292-4344-9686-c9730d7f1100 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/04/12/you-are-in-a-maze-of-little-twisty-evals-all-similar#comments Ruby railsrouting http://www.bofh.org.uk/articles/2007/04/12/you-are-in-a-maze-of-little-twisty-evals-all-similar The "Yes is No" Problem <code><pre> login: pdcawley password: ***** Yes is no and no is yes. Do you want to delete all your files? [y]: _</pre></code> <p>Rereading <a href="http://www.bitwisemag.com/2/What-s-Wrong-With-Ruby">What&#8217;s wrong with Ruby</a>, I realised that the meat of Matthew Huntbach&#8217;s worry about dynamic classes boils down to the &#8216;yes is no&#8217; problem. Given just the source code of a Ruby program, it can be tricky to work out what the eventual program &#8216;looks like&#8217;.</p> <p>Ruby source can be thought of as a program that you run on the Ruby kernel which creates a bunch of classes, objects and relationships between them. In static languages, once a class has been created, that&#8217;s it, the only way to change it is to recompile and restart the program. In dynamic languages, no class is every really &#8216;finished&#8217;, it can be modified at any time.</p> <p>Done right, that can be a great thing. It&#8217;s instructive to look at the way ActiveRecord&#8217;s behaviour gets built up in Ruby. <code>ActiveRecord::Base</code> doesn&#8217;t really do all that much, it concerns itself with the nuts and bolts of marshalling data to and from the database and building the basic accessors and support methods needed to do that. Its implementations of basic methods like <code>#create</code>, <code>#update</code> and <code>#save</code> are positively naïve. New behaviours are then layered on by including other modules. Modules like <code>ActiveRecord::Locking::Optimistic</code>, <code>ActiveRecord::Validations</code>, <code>ActiveRecord::Callbacks</code> and others all layer behaviour on top of these methods, usually by renaming the old method, so <code>#update</code> becomes <code>#update_without_lock</code> and <code>ActiveRecord::Locking::Optimistic#update_with_lock</code> becomes the new <code>#update</code>, at least until <code>ActiveRecord::Timestamp</code> changes its name to <code>#update_without_timestamps</code> and installs the behaviour that it needs.</p> <p>It can make the code harder to understand though. Say you&#8217;re looking at <code>ActiveRecord::Timestamp#update_with_timestamps</code> and you want to look at how <code>#update_without_timestamps</code> does its thing. If you simply grep for <code>def update</code> in the source code, you&#8217;ll find the implementation in <code>ActiveRecord::Base</code> and miss out on the alterations introduced by the locking module. You can&#8217;t simply look at the source code, you have to look at the order in which it was executed, and that can be a headache. Once you understand that you need to look at load order, and you find where that is defined, things get much easier, but things can get seriously scary when plugins come into play too.</p> <p>What&#8217;s needed (or at least desirable) is a way of understanding what the state of the program and its classes will be at runtime. It&#8217;s easy in static languages, it&#8217;ll look like the source code says it looks. It looks like the source code says it will look in Ruby too, but Ruby source code can get a good deal more twisty. Even <code>attr_accessor</code> has the potential to blow minds&#8230;</p> <p>Would you believe it&#8217;s a solved problem? It&#8217;s been solved for years too. Heck, the solution is older than <a href="http://www.loudthinking.com/">David Heinemeier Hansson</a>.</p> <h3>Counsel of Perfection</h3> <p>I&#8217;m thinking of Smalltalk, but I&#8217;m pretty sure that the Lisp Machine folks had similar tools at their disposal. In a Smalltalk image, you can browse the source code at any time, and it always reflects the current specification of the system. In a Smalltalk implementation of ActiveRecord, as soon as you rename <code>#update</code> to <code>#updateWithouLocking</code> that&#8217;s what it&#8217;s called. When, later you&#8217;re looking at the definition of <code>#update</code> and you want to know what <code>#updateWithoutLocking</code> looks like, you can browse straight too it. The knowledge that <code>#updateWithoutLocking</code> used to be called <code>#update</code> hasn&#8217;t been lost, you&#8217;ll find it in your changes, but it&#8217;s irrelevant to how the system behaves now.</p> <p>I&#8217;ve been admiring Smalltalk from afar for a long time now, but until recently it wasn&#8217;t a language I spent any time programming in. I was more likely to think &#8220;How does Smalltalk do that?&#8221;, then fire up my local Squeak image and do a little fossicking about until I had a grasp on how things worked. Then I&#8217;d close it down and do something similar (or curse because I couldn&#8217;t) in Perl or Ruby. You can learn a great deal just doing that; if nothing else I&#8217;ve learned that I like Smalltalk&#8217;s message selector syntax a great deal.</p> <p>Then, a few weeks ago, I watched a couple of screencasts of experienced Smalltalk developers doing their thing and&#8230; wow. I&#8217;ve always known that Smalltalkers rave about the environment, but I&#8217;d not really seen it in full flow.</p> <p>So, I&#8217;ve been doing a few <a href="http://codekata.pragprog.com/">Code Katas</a> in Squeak and starting to get a feel for working in the environment. It&#8217;s really, really lovely. Watch this space for more &#8216;coo er gosh&#8217; type posts. Who know, maybe even an embarrassing screencast &#8211; if nothing else but so I can get some feedback from experienced Smalltalkers on what I&#8217;m doing wrong.</p> <h3>What about Ruby?</h3> <p>Short of someone coming up with a Smalltalk style interactive development environment for Ruby in the next half hour, this isn&#8217;t an immediately useful solution to the problem in Ruby.</p> <h4>But is it really a problem?</h4> <p>Having taken the time to explain why dynamic modification of classes can be a problem, I should point out that I don&#8217;t think it&#8217;s really a problem in practice. Sure, you can do Very Bad Things with it, but so what? You can do the same bad things (and more) in Smalltalk, if you couldn&#8217;t, it would be (nearly?) impossible to implement the Smalltalk environment in the first place. In the absence of an interactive programming environment, you need to take more care with structuring and organizing your code. Impose some standards on yourself &#8211; in Rails for instance, the various ActiveFoo classes are structured similarly: first there&#8217;s the &#8216;active_foo.rb&#8217; file, which is responsible for loading up all the packages that define the class (generally found in the &#8216;active_foo&#8217; sub directory) and <code>include</code>ing them in <code>ActiveFoo::Base</code> in the correct order. This convention helps comprehension. About the only thing I&#8217;d like to see further is some documentation in each module describing the behaviour they expect of any class they&#8217;re included in &#8211; behaviour like that of <code>ActiveRecord::Validations</code> is just too useful not to be pinched for other classes.</p> <p>As always with these things, it boils down to the good taste and skill of the programmer. Write code that communicates your intent clearly to your fellow programmers &#8211; mere compilation is the least of your worries.</p> <h3>Updates</h3> <p>In the comments, <a href="http://fiatdev.com/">Phil Toland</a> has come up with links to some Smaltalk screencasts and a long presentation from Avi Bryant that includes some interaction with a Squeak image.</p> <p>NB: For &#8216;ruby&#8217;, you can read &#8216;pretty much every dynamic OO language ever&#8217;. Except Matthew Huntbach didn&#8217;t write an article called &#8220;What&#8217;s wrong with pretty much every dynamic OO language ever&#8221;.</p> Wed, 04 Apr 2007 05:33:00 -0500 urn:uuid:656093fb-3f84-42da-9678-2e778c4e4e01 pdcawley@bofh.org.uk (Piers Cawley) http://www.bofh.org.uk/articles/2007/04/04/the-yes-is-no-problem#comments The Practice of Programming Ruby smalltalk ruby yesisno http://www.bofh.org.uk/articles/2007/04/04/the-yes-is-no-problem PragDave nails it. Again. <p><span class="caps">REST</span> is easy, it&#8217;s just smart clients using <span class="caps">HTTP</span> to the full.</p> <p>Except, as Dave &#8216;PragDave&#8217; Thomas <a href="http://pragdave.pragprog.com/pragdave/2007/03/the_radar_archi.html">points out</a>, browsers aren&#8217;t smart. They&#8217;re just dumb terminals with prettier graphics.</p> <p>And what does that mean? It means that a typical Rails controller is trying to multiplex two protocols in the same chunk of code. There&#8217;s the pure four and then there&#8217;s the others: <code>;new</code> and <code>;edit</code>, offering up forms for clients too dumb to know how to build their own; and <span class="caps">RJS</span> helpers like <code>;preview</code>, <code>;autocomplete</code> and whatever else you need to do server side to make the Browser look smart.</p> <p>But when you have a class that&#8217;s trying to be two things at once, you really have two classes, you just don&#8217;t know it yet.</p> <p>So, Dave proposes splitting controllers; write a RESTful controller that only has to concern itself with serving up resources that smart clients can reuse and remix as appropriate. Then, you a server side smart client that decorates your resources with all the scaffolding that a browser needs.</p> <p>Dave calls this <span class="caps">RADAR</span>: RESTful Application talking to Dumb Ass Recipient.</p> <p>My first reaction is that Dave&#8217;s definitely onto something. If nothing else it deals with one obvious wart involving authentication and <span class="caps">REST</span>. The problem is, a good RESTful application doesn&#8217;t roll its authentication, just uses <span class="caps">HTTP</span> Digest authentication or <span class="caps">SSL</span> or whatever. With a smart client that&#8217;s fine; smart clients know how to log off as well as on. Browsers don&#8217;t. Essentially, once you&#8217;ve logged on using <span class="caps">HTTP</span> authentication, you&#8217;re authenticated until you restart the browser, which is not necessarily what you need a lot of the time. So most applications use cookies for authentication because the application has rather more control over a cookie. But that&#8217;s not really very RESTful because the connection is now stateful. Disaster!</p> <p>However, if you decompose your application along <span class="caps">RADAR</span> lines, all the conversation with the <span class="caps">REST</span> kernel continues on its stateless way, but the combination of your browser presentation layer and the browser share a bit of state through cookies (and possibly a session) in order to do a better imitation of a smart client.</p> <h3>A thought&#8230;</h3> <p>Hmm&#8230; suddenly the <a href="http://www.zimki.com/">Zimki</a> approach of writing everything in JavaScript is looking more attractive. If you write the presentation layer in JavaScript there&#8217;s nothing to stop it residing either on the server while talking to browser