<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>press play on tape</title>
 <link href="http://blog.absurd.li/atom.xml" rel="self"/>
 <link href="http://blog.absurd.li/"/>
 <updated>2013-03-08T10:48:02+01:00</updated>
 <id>http://blog.absurd.li/</id>
 <author>
   <name>Kaspar Schiess</name>
   <email>kaspar.schiess@absurd.li</email>
 </author>

 
 <entry>
   <title>HTTP... something</title>
   <link href="http://blog.absurd.li/2012/06/13/http_something.html"/>
   <updated>2012-06-13T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2012/06/13/http_something</id>
   <content type="html">&lt;p&gt;A survey of &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; client-side libraries. Too much choice. And my 2 cents.&lt;/p&gt;
&lt;p&gt;Note that these are in no particular order and that the list (still) isn&amp;#8217;t
complete. If you have something that deserves a mention here, let me know. I
will include it for novelty, not for repetition.&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;https://github.com/tarcieri/http&quot;&gt;http&lt;/a&gt; (2011), &lt;a href=&quot;https://github.com/maccman/nestful&quot;&gt;nestful&lt;/a&gt; (2010), &lt;a href=&quot;https://github.com/hukl/righttp&quot;&gt;righthttp&lt;/a&gt; (2010),  &lt;a href=&quot;http://simplehttp.rubyforge.org/&quot;&gt;simplehttp&lt;/a&gt; (2007),  &lt;a href=&quot;https://github.com/xianhuazhou/http_request.rb&quot;&gt;http_request.rb&lt;/a&gt; (2009),  &lt;a href=&quot;https://github.com/ctcherry/plain_http&quot;&gt;plain_http&lt;/a&gt; (2011)&lt;/h2&gt;
&lt;p&gt;I have a hard time seeing the differences between these libraries. There sure
are some, but they might have well copied the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; from one another.&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  Http.get 'http://example.com'             # http
  Nestful.get 'http://example.com'          # nestful
  HTTP.get 'http://example.com'             # righttp
  SimpleHttp.get &quot;http://www.example.com&quot;   # simplehttp
  HttpRequest.get('http://www.github.com')  # http_request.rb
  PlainHTTP.get('http://www.google.com')    # plain_http
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;nestful&lt;/code&gt; has probably the most features geared towards &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;It looks as if everyone is scratching the same itch. And an itch that itches
so bad, you can&amp;#8217;t be bothered with google anymore. Some of these are better 
than others and nestful probably deserves its own category based on features, but there.&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;https://github.com/typhoeus/typhoeus&quot;&gt;Typhoeus&lt;/a&gt; (2009)&lt;/h2&gt;
&lt;p&gt;Typhoeus is a mythical greek god with 100 fire breathing serpent heads.&lt;sup class=&quot;footnote&quot; id=&quot;fnr1&quot;&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; In
the case of typhoeus, a head stands metaphorically for a connection &amp;#8211; this
library allows more than one connection be made at the same time. The
&lt;a href=&quot;http://typhoeus.github.com/&quot;&gt;documentation at github&lt;/a&gt; has a nice &amp;#8216;&lt;a href=&quot;http://typhoeus.github.com/articles/getting_started.html&quot;&gt;getting
started&lt;/a&gt;&amp;#8217; tutorial
that shows you how to do requests.&lt;/p&gt;
&lt;p&gt;Typhoeus really will do parallel requests! If you&amp;#8217;re someone who calls 100
backend services on every request (thanks, &lt;span class=&quot;caps&quot;&gt;SOA&lt;/span&gt;!), you will need this in one of
its forms. This library looks very feature complete and advanced, but as you
might have guessed, this will also work:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  Typhoeus::Request.get('http://example.com')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An interesting variation here is that you can use Typhoeus as a &lt;span class=&quot;caps&quot;&gt;DSL&lt;/span&gt; in your
classes, giving them &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; call perks. See &lt;a href=&quot;http://www.pauldix.net/2009/05/breath-fire-over-http-in-ruby-with-typhoeus.html&quot;&gt;this post&lt;/a&gt; from Paul Dix for an in-depth explanation.&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;http://httpadapter.rubyforge.org/&quot;&gt;httpadapter&lt;/a&gt; (2010)&lt;/h2&gt;
&lt;p&gt;This isn&amp;#8217;t a &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; speaking library, but rather it &amp;#8216;translates &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; request and
response objects for various clients into a common representation&amp;#8217;. The idea
seems to be to create a client-side &lt;em&gt;rack&lt;/em&gt;.&lt;sup class=&quot;footnote&quot; id=&quot;fnr2&quot;&gt;&lt;a href=&quot;#fn2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;http://github.com/appoxy/http_connection/&quot;&gt;http_connection&lt;/a&gt; (2009)&lt;/h2&gt;
&lt;p&gt;This library by RightScale.com seems to attempt to do reliable http
connections that do connection retries. It doesn&amp;#8217;t have as many features as
others, but reliability seems to be something that others don&amp;#8217;t address.&lt;/p&gt;
&lt;p&gt;Is it something that needs to be handled by your &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; library?&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;http://github.com/nahi/httpclient&quot;&gt;httpclient&lt;/a&gt; (2007)&lt;/h2&gt;
&lt;p&gt;This seems to be the most complete client like implementation of &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt;. It has
things like cookie support. (storing cookies from one request to the next,
like a browser does)&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/nahi/httpclient/tree/master/sample&quot;&gt;samples&lt;/a&gt; are very
informative and should be easy enough to pick up.&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  client = HTTPClient.new
  client.get 'http://example.com'
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;a href=&quot;http://httparty.rubyforge.org/&quot;&gt;httparty&lt;/a&gt; (2008)&lt;/h2&gt;
&lt;p&gt;I&amp;#8217;ve never heard of this before today and it seems I am late to the .. well 
let&amp;#8217;s not go there. This library is similar to Typhoeus in that it allows you
to create special purpose classes that encapsulate &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; functionality.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s the simple example from the project page:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  class Twitter
    include HTTParty
    base_uri 'twitter.com'
    basic_auth 'username', 'password'
  end

  Twitter.post('/statuses/update.json', :query =&amp;gt; 
    {:status =&amp;gt; &quot;It's an HTTParty and everyone is invited!&quot;})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&amp;#8217;s been around for some time and even though it doesn&amp;#8217;t seem to be as heavy 
as Typhoeus is on parallelization, it seems to allow terse special purpose
&lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; request classes to be written in just a few lines.&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;https://github.com/ujihisa/net-https-wrapper&quot;&gt;net-https-wrapper&lt;/a&gt; (2009)&lt;/h2&gt;
&lt;p&gt;This library is special in its minimalism. Its (rather short) gemspec has 
the same amount of lines as its implementation. The author doesn&amp;#8217;t seem 
to think we&amp;#8217;d need &lt;code&gt;#get&lt;/code&gt;, ever, so it only speaks &lt;code&gt;#post&lt;/code&gt; or &lt;code&gt;#put&lt;/code&gt;. Is it &lt;a href=&quot;https://github.com/ujihisa/net-https-wrapper/commits/master&quot;&gt;art?&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;http://bogomips.org/http_spew/&quot;&gt;http_spew&lt;/a&gt; (2011)&lt;/h2&gt;
&lt;p&gt;If one of these libraries gets outlawed, it&amp;#8217;s this one. This seems to be the
only library I&amp;#8217;ve looked at that doesn&amp;#8217;t bother with the responses that are
sent by the server. Instead, it attempts to generate as much traffic as
possible without reading things back. As the author rightfully remarks, this
may get you banned from the internet. Or wait. No. Daily business.&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;http://rubygems.org/gems/fast_http&quot;&gt;fast_http&lt;/a&gt; (2010)&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://rubygems.org/gems/fast_http&quot;&gt;Art?&lt;/a&gt; Or just plain &lt;em&gt;fast!&lt;/em&gt; &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt;? I cannot
really tell from the documentation.&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;http://docs.seattlerb.org/net-http-persistent/&quot;&gt;net-http-persistent&lt;/a&gt; (2010), &lt;a href=&quot;https://github.com/bpardee/persistent_http&quot;&gt;persistent_http&lt;/a&gt; (2010)&lt;/h2&gt;
&lt;p&gt;These libraries are not about the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;, but about making &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; connections
persistent. This is also something a browser does and probably should be a
feature of the base library.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;persistent_http&lt;/em&gt; will allow pooling connections instead of keeping one
connection per thread.&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;http://docs.seattlerb.org/net-http-pipeline/&quot;&gt;net-http-pipeline&lt;/a&gt; (2010)&lt;/h2&gt;
&lt;p&gt;Allows &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt;/1.1 request pipelining:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  require 'net/http/pipeline'

  Net::HTTP.start 'localhost' do |http|
    req1 = Net::HTTP::Get.new '/'
    req2 = Net::HTTP::Get.new '/'
    req3 = Net::HTTP::Get.new '/'

    http.pipeline [req1, req2, req3] do |res|
      puts res.code
      puts res.body[0..60].inspect
      puts
    end
  end
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;a href=&quot;http://rubygems.org/gems/HTTPal&quot;&gt;HTTPal&lt;/a&gt; (2007)&lt;/h2&gt;
&lt;p&gt;Similar to &lt;em&gt;httpclient&lt;/em&gt;, this keeps cookies and referrers for you. A simple
library that seems to either do its job or is abandoned &amp;#8211; no releases since the
initial few.&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;https://github.com/rubiii/httpi&quot;&gt;httpi&lt;/a&gt; (2010)&lt;/h2&gt;
&lt;p&gt;A common interface to several &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; backends: This library speaks &lt;em&gt;curb&lt;/em&gt;,
&lt;em&gt;httpclient&lt;/em&gt; and &lt;em&gt;net-http&lt;/em&gt;. The idea is that it gives you a simple interface
to remember and allows all of these backends to be swapped out, depending on
your needs.&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  HTTPI.get 'http://www.example.com'    # will work
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;I&amp;#8217;ve used &lt;em&gt;httpclient&lt;/em&gt; (for its cookie caps) and &lt;em&gt;httpi&lt;/em&gt; (by accident) in the
past. No gripes with those. Also, I must have used &lt;em&gt;net-http&lt;/em&gt; (stdlib) at some
point. The fact that I didn&amp;#8217;t write one of these libraries must mean that it
didn&amp;#8217;t bother me as much as it did others.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve added Typhoeus and HTTParty to the list of libraries I would use. The &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;
idea behind these makes sense and used in the right place, it will simplify
things. Typhoeus certainly comes in handy when making hundreds of requests to
backends.&lt;/p&gt;
&lt;p&gt;Interesting to know about: &lt;em&gt;net-http-persistent&lt;/em&gt; and &lt;em&gt;net-http-pipeline&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;Write another one?&lt;/h2&gt;
&lt;p&gt;No. &lt;/p&gt;
&lt;p&gt;Perhaps we should all clean up our respective acts and:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Use google before using one of the many project skeleton generators that exist. (That is a list to be made another day&amp;#8230;)&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;Merge some of these? Make better libraries instead of more?&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;And a parting note&lt;/h2&gt;
&lt;p&gt;I could make these kind of lists for many problems we
Rubyists solve. The authors of these libraries are not to blame. (or rather,
they are only to blame for their part of the problem) The Ruby community as a
whole is currently experiencing a severe shortness of attention span. If it is
not new, it is probably crap, right?&lt;/p&gt;
&lt;p&gt;No. We should stop the proliferation of new libraries and start working good
ideas into the libraries we already have. Also, a good telling sign whether
you need to release a library is: Is the library bigger than the Gemspec?&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn1&quot;&gt;&lt;a href=&quot;#fnr1&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; http://www.pauldix.net/2009/05/breath-fire-over-http-in-ruby-with-typhoeus.html&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn2&quot;&gt;&lt;a href=&quot;#fnr2&quot;&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; http://httpadapter.rubyforge.org/api/&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="http" label="http" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="libraries" label="libraries" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="survey" label="survey" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="httpi" label="httpi" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="HTTParty" label="HTTParty" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="Typhoeus" label="Typhoeus" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="httpclient" label="httpclient" />
   
 </entry>
 
 <entry>
   <title>cod is a fiction</title>
   <link href="http://blog.absurd.li/2012/03/31/cod_is_a_fiction.html"/>
   <updated>2012-03-31T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2012/03/31/cod_is_a_fiction</id>
   <content type="html">&lt;p&gt;&lt;em&gt;TL;DR About what cod is not and what it is; and on how a good story builds
the kernel of every &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I am currently underway documenting &lt;em&gt;&lt;a href=&quot;https://github.com/kschiess/cod&quot;&gt;cod&lt;/a&gt;&lt;/em&gt; for
a broad usage. This is always an interesting process, since writing about a 
subject seems to be a good way for me to start thinking on other levels than
just code.&lt;/p&gt;
&lt;p&gt;Let me start by saying what &lt;em&gt;cod&lt;/em&gt; is not:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Cod is not a big lump of code&lt;/strong&gt; It could have turned out to be, but no, it
  did not. Cod is a really thin layer over the &lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;IPC&lt;/span&gt; mechanisms your OS
  and Ruby already provide.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Cod will not be your only require&lt;/strong&gt; It is probable that beyond cod, you will
  need a few extra libraries to do what you want. It doesn&amp;#8217;t solve a problem
  domain all by itself, but it gives you one of the pieces.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So now here&amp;#8217;s what cod is:&lt;/p&gt;
&lt;h2&gt;Cod is really a fiction&lt;/h2&gt;
&lt;p&gt;Much more than a set of new functionalities that you can enable only by using 
cod, it is a fiction. It provides you with a way to think about the world of
&lt;span class=&quot;caps&quot;&gt;IPC&lt;/span&gt; that may very well shape that world for the better.&lt;/p&gt;
&lt;p&gt;Stories like these, once shared with others, allow you to refer to a chunk of
lifetime by a few words only. Thinking of chunked (&amp;#8216;told&amp;#8217;) memories, you can
reduce them to what you&amp;#8217;ve told yourself what they are. This reduction is a
reduction in complexity that we seek in code. In life, too much reduction is
dangerous, since we&amp;#8217;re also reducing the stuff life is made of. In code,
reduction will benefit your life, since you now have time to spend off the
hook.&lt;/p&gt;
&lt;p&gt;To achieve these goals, &lt;em&gt;cod&lt;/em&gt; introduces a new abstraction. It uses the
concept of channels, ways for information to flow. These channels have each a
&lt;code&gt;#get&lt;/code&gt; method that allows you to retrieve information from them.
And symmetrically, they have a &lt;code&gt;#put&lt;/code&gt; method that allows to put
information into them.&lt;/p&gt;
&lt;p&gt;This is the basic thing. There is a small universe around those two: Learning
how to know when to stop retrieving information, learning how to wait for more
information without polling. Together, they form the base dictionary for
programs that use cod; it is a small dictionary composed of only a few
ideas.&lt;/p&gt;
&lt;h2&gt;Specifics&lt;/h2&gt;
&lt;p&gt;And then, once you start using it in real life, you need specific features 
that your transport provides. An example would be that pipes created by
&lt;code&gt;IO.pipe&lt;/code&gt; are asymmetric: in most processes, you will either read
from or write to such a pipe. I account for this by having special methods
in the pipe channel, methods that allow splitting the pipe into two pipes
that are read- or write-only.&lt;/p&gt;
&lt;p&gt;But wherever possible, I&amp;#8217;ll do these things without having you notice. For 
example: If you create a channel like this:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  channel = Cod.pipe
  fork do
    # here: #put to the channel
    channel.put &quot;This is information&quot;
  end
  # here: #get from the channel
  channel.get
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;the split will happen behind the scenes and automatically. In daily use, you 
need not worry.&lt;/p&gt;
&lt;p&gt;These specifics still follow the philosophy of the library; they try hard not
to introduce new concepts, but rather stay within the fiction. They are like
that side-story that you never tell, but for the ones that ask the right
question. You went to south-america, but why: for a woman. It went nowhere 
and is irrelevant to your story, but there: motivation for telling the story &amp;amp; 
it still fits in the frame.&lt;/p&gt;
&lt;h2&gt;Environment&lt;/h2&gt;
&lt;p&gt;Like all good stories, &lt;em&gt;cod&lt;/em&gt; takes place in a environment that is not a void.
There are useful characters around, and it tries to take them into account. Of
course, these links all cost time; so this area of the library will need to
grow over time as well.&lt;/p&gt;
&lt;p&gt;For example, a useful transport for information in todays world are queue
servers. There are a couple of names in this domain: RabbitMQ, beanstalkd,
redis, zeromq and &amp;#8230; more. A queue fits into the &lt;em&gt;cod&lt;/em&gt; fiction by providing a
transport for information that allows the participants of the communication to
be on several physical/logical machines or to have non-overlapping lifetimes.
So &lt;em&gt;cod&lt;/em&gt; will, wherever possible and needed, provide channel abstractions of
these queues. For example you can already do the following:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  channel = Cod.beanstalk('my_message_tube')
  channel.put [:a, :piece, :of, :information]
  
  # and later
  channel.get # =&amp;gt; [:a, :piece, :of, :information]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But &lt;em&gt;cod&lt;/em&gt; will never become the library to manage these queues. Like a good
story, it fits into the world around it and doesn&amp;#8217;t disrupt it; A story that
disrupts the world around it is called psychotherapy; let&amp;#8217;s leave that to 
another library and another day.&lt;/p&gt;
&lt;h2&gt;A seed for more&lt;/h2&gt;
&lt;p&gt;I&amp;#8217;ve talked about how &lt;em&gt;cod&lt;/em&gt; is like a story, how it allows to talk about
the world in reduction to what is important. I&amp;#8217;ve shown how &lt;em&gt;cod&lt;/em&gt; deals with 
nagging questions and the world around it.&lt;/p&gt;
&lt;p&gt;I haven&amp;#8217;t given you the story, and that was on purpose; if you want the story,
you can have a few bits &lt;a href=&quot;/2011/04/21/introducing_cod.html&quot;&gt;here&lt;/a&gt; and
&lt;a href=&quot;https://github.com/kschiess/cod&quot;&gt;there&lt;/a&gt; right now. More documentation will be
available soon.&lt;/p&gt;
&lt;p&gt;Every &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; should have a kernel that is story. From there on, things fall in
place naturally; If the story is crooked, so will the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; be; but it will have
coherence. If the story is fair on the other hand, your programs will look
nice and work together like a chorus of unicorns. Either way, the building 
principle called &amp;#8216;story&amp;#8217; is valid and applies.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="cod" label="cod" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="beanstalk" label="beanstalk" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="pipes" label="pipes" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="zack" label="zack" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="rpc" label="rpc" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="unix" label="unix" />
   
 </entry>
 
 <entry>
   <title>Introducing the floor_manager plugin</title>
   <link href="http://blog.absurd.li/2011/09/28/introducing_floor_manager.html"/>
   <updated>2011-09-28T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2011/09/28/introducing_floor_manager</id>
   <content type="html">&lt;p&gt;One of the decisions a modern development team has to make is: &lt;strong&gt;What kind of
fixture framework should we use?&lt;/strong&gt; By now, I hope that &lt;span class=&quot;caps&quot;&gt;YAML&lt;/span&gt; fixtures have failed you&amp;#8230;&lt;/p&gt;
&lt;p&gt;In this blog post, I will tell you about the answer I&amp;#8217;ve found and why I think
it is useful. But please, do not think that mine is the only answer in the
field. Look for &lt;a href=&quot;http://rubygems.org/gems/factory_girl&quot;&gt;factory_girl&lt;/a&gt; and
others.&lt;/p&gt;
&lt;h2&gt;floor_manager&lt;/h2&gt;
&lt;p&gt;As of today, I&amp;#8217;ve released the
&lt;a href=&quot;https://github.com/kschiess/floor_manager&quot;&gt;floor_manager&lt;/a&gt; gem, which you can
install in the usual manner. To be able to tell you how to create fixtures
using that gem, here&amp;#8217;s a few datamapper models that I&amp;#8217;ll be creating a fixture
for:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
class Person
  has n, :accounts
  has n, :groups
  
  property :full_name, String
  property :age, Integer
end

class Account
  belongs_to :person
  belongs_to :primary_group, model: 'Group'
  
  property :name, String, key: true
end
class Group
  belongs_to :person
  
  property :name, String, key: true
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is datamapper syntax for Ruby 1.9. If someone translates this into
ActiveRecord, the following examples will all work.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s create a series of fixtures for these three models. Incidentally, they
will serve to illustrate almost all aspects of floor_manager.&lt;/p&gt;
&lt;h2&gt;Factory floors&lt;/h2&gt;
&lt;p&gt;The line is: &amp;#8220;floor_manager doesn&amp;#8217;t just handle individual girls, it handles
entire factory floors. And it is even less sexistic, since it handles
employees, not just &amp;#8216;girls&amp;#8217;&amp;#8221;. You say: yes, but &lt;strong&gt;what does it mean?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A floor is a namespace of fixture objects. Such a floor contains employees,
individual fixture templates or singletons. A really simple floor looks like
this:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
FloorManager.define(:my_simple_floor) do
  one :employee do
    name 'John Doe'
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This defines a singleton fixture (more about that later) named :employee, an 
instance of the &lt;code&gt;Employee&lt;/code&gt; class. This employees name field is then
set to &amp;#8216;John Doe&amp;#8217;.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s how you use :employee in your specs:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
describe &quot;some spec&quot; do
  let(:floor) { FloorManager.get(:my_simple_floor) }
  let(:employee) { floor.employee }
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gives you an instance of Employee (imagine this is also a model you have)
with &amp;#8216;name&amp;#8217; filled in, but not saved. In fact, it is aequivalent to calling
&lt;code&gt;floor.build(:employee)&lt;/code&gt;. Here are some other ways to get objects
from the floor:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
floor.create(:employee) # =&amp;gt; a saved model, provided it could be saved.
floor.build(:employee) # =&amp;gt; build, but don't persist, see above
floor.attrs(:employee) # =&amp;gt; just an attribute hash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see from the above code, floor_manager forces you to name your
fixture spaces. It also encourages you to start new fixture spaces per topic.
Or maybe even one per spec?&lt;/p&gt;
&lt;p&gt;Floor definitions go into normal ruby files that you keep below &lt;code&gt;spec/support&lt;/code&gt;. Or anywhere else. You will then require these files
in your &lt;code&gt;spec_helper.rb&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Simple fixtures: Singletons&lt;/h2&gt;
&lt;p&gt;What does the term singletons mean? It refers to what you already do when 
you use &lt;span class=&quot;caps&quot;&gt;YAML&lt;/span&gt; fixtures: Singletons only ever exist once in memory and also 
only once in the database, if they are created or saved.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s a floor with a singleton:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
FloorManager.define(:singleton) do
  one :john_doe, model: Person do
    full_name 'John Doe'
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you use &lt;code&gt;floor.create(:john_doe)&lt;/code&gt; in your specs, you will
trigger one database &lt;span class=&quot;caps&quot;&gt;INSERT&lt;/span&gt; and then subsequently just access the instance you
generated. This can be helpful when you really want just one
john_doe in all your tests, let&amp;#8217;s say he&amp;#8217;s your system administrator and you
want to test with &lt;code&gt;:john_doe&lt;/code&gt; specifically, not just &lt;em&gt;a&lt;/em&gt; john doe.&lt;/p&gt;
&lt;h2&gt;Generators&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s say you define the floor &lt;code&gt;:generators&lt;/code&gt; as follows:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
FloorManager.define(:generators) do
  any :person do
    full_name 'John Doe'
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you now access &lt;code&gt;:person&lt;/code&gt; from the floor through any of the
methods on floor (&lt;code&gt;#create&lt;/code&gt;, &lt;code&gt;#build&lt;/code&gt;,
&lt;code&gt;#attrs&lt;/code&gt;) you will get a new instance every time. This means that
each &lt;code&gt;#create&lt;/code&gt; will trigger an &lt;span class=&quot;caps&quot;&gt;INSERT&lt;/span&gt;, if the created model is
valid.&lt;/p&gt;
&lt;p&gt;Generators&lt;sup class=&quot;footnote&quot; id=&quot;fnr1&quot;&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; often need to create random integers or strings for each of their
instances. Here&amp;#8217;s how you would do that:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
FloorManager.define(:generators_random) do
  any :person do
    full_name.string(8)
    age.integer(21..50)
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I guess that is pretty self-explanatory. This gives you any kind of person
that is legally of age but not yet retired.&lt;/p&gt;
&lt;p&gt;Note that random generation is not one of floor_managers main strengths. Sorry. Use this:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
any :person do
  full_name { ... create a name here }
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This should get you where you would need to be to use any of the available
pseudo-data generation libraries.&lt;/p&gt;
&lt;h2&gt;Associations&lt;/h2&gt;
&lt;p&gt;Here&amp;#8217;s how you would create a Person instance with Account and Group attached:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
FloorManager.define(:full_example) do
  one :person do
    full_name 'John Doe'
    age.integer(20..50)
    
    groups.append :group
    accounts.append :account
  end
  one :group do
    name.string(8)
  end
  one :account do
    name.string(8)
    primary_group.set :group
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Collections have the &lt;code&gt;#append&lt;/code&gt; method for adding objects to them, 
methods that accept a single object should be filled with &lt;code&gt;#set&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When I now call&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  person = floor.create(:person)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I will get a Person instance that has a group and an account attached. The 
above statement yanks an entire object graph into existence! I think that is 
pretty cool.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re asking yourself why I didn&amp;#8217;t use &lt;code&gt;any&lt;/code&gt; in the above
example, please think it through and post the answer in the comments. I&amp;#8217;ll
post the real reason about next week&amp;#8230;&lt;/p&gt;
&lt;h2&gt;Setup, Teardown: Caveats&lt;/h2&gt;
&lt;p&gt;Like all good things, floor_manager has a few caveats attached, things to remember.&lt;/p&gt;
&lt;p&gt;Before you can use fixtures (any kind of fixtures, really), you will need to
&lt;strong&gt;reset your database to a known state&lt;/strong&gt;. I mostly prefer this to be an empty
database, best achieved with
&lt;a href=&quot;http://rubygems.org/gems/database_cleaner&quot;&gt;database_cleaner&lt;/a&gt;. Have a look at
that project and install this properly, then you can forget about
floor_manager preconditions.&lt;/p&gt;
&lt;p&gt;When you don&amp;#8217;t remember this, what will happen is the following: You&amp;#8217;ll
eventually create an object that has some kind of unique constraint (like
&lt;code&gt;Account&lt;/code&gt; and &lt;code&gt;Group&lt;/code&gt; above) twice. The second time
around, the &lt;span class=&quot;caps&quot;&gt;INSERT&lt;/span&gt; fails. You get an error message that looks like it&amp;#8217;s coming
from floor_manager, but really is issued by your &lt;span class=&quot;caps&quot;&gt;ORM&lt;/span&gt; system. And the insert
fails. And you can&amp;#8217;t execute your spec. This means a spec fails because you
have a side effect via the database from an earlier spec, something you
&lt;em&gt;absolutely&lt;/em&gt; want control over/ never to happen. So run already, use
&lt;a href=&quot;http://rubygems.org/gems/database_cleaner&quot;&gt;database_cleaner&lt;/a&gt;, in any of its
modes!&lt;/p&gt;
&lt;p&gt;Also, since FloorManager retains some (global :() state, you will &lt;strong&gt;need to
call &lt;code&gt;FloorManager.reset&lt;/code&gt; before each spec&lt;/strong&gt;. This is best achieved
with the following bit in spec_helper.rb:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
Rspec.configure do |config|
  # other stuff...
  
  config.before(:each) { FloorManager.reset }
end
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Works With&lt;/h2&gt;
&lt;ul&gt;
	&lt;li&gt;Rails &amp;amp; ActiveRecord&lt;/li&gt;
	&lt;li&gt;Sinatra &amp;amp; Datamapper&lt;/li&gt;
	&lt;li&gt;Probably a lot of other stuff: It is written to be flexible and environment-agnostic.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Why you should use floor manager&lt;/h2&gt;
&lt;p&gt;Because it gives you&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;fixtures as code&lt;/li&gt;
	&lt;li&gt;separation of fixtures&lt;/li&gt;
	&lt;li&gt;access to attributes and unsaved objects&lt;/li&gt;
	&lt;li&gt;flexibility between generator and singletons&lt;/li&gt;
	&lt;li&gt;yanks entire object graphs into existence!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;sh_bash&quot;&gt;
$ gem install floor_manager
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;right now! The mgmt.&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;footnote&quot; id=&quot;fnr1&quot;&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; Generators are what factory_girl calls a &amp;#8216;factory&amp;#8217;. The factories of 
floor_manager build bigger items.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="activerecord" label="activerecord" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="datamapper" label="datamapper" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="rails" label="rails" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="sinatra" label="sinatra" />
   
 </entry>
 
 <entry>
   <title>Parslet Tree Mangling and Transformations</title>
   <link href="http://blog.absurd.li/2011/06/29/tree_mangling_and_transformations.html"/>
   <updated>2011-06-29T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2011/06/29/tree_mangling_and_transformations</id>
   <content type="html">&lt;p&gt;A simple parser in &lt;a href=&quot;http://kschiess.github.com/parslet&quot;&gt;parslet&lt;/a&gt; will at first
only output strings from its parsing stage:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  class SimpleParser &amp;lt; Parslet::Parser
    root :ifthenelse

    rule(:ifthenelse) {
      _if &amp;gt;&amp;gt; _then &amp;gt;&amp;gt; _else.maybe
    }

    rule(:_if)    { str('if') &amp;gt;&amp;gt; space? &amp;gt;&amp;gt; number }
    rule(:_then)  { str('then') &amp;gt;&amp;gt; space? &amp;gt;&amp;gt; number }
    rule(:_else)  { str('else') &amp;gt;&amp;gt; space? &amp;gt;&amp;gt; number }

    rule(:number) { match[&quot;0-9&quot;].repeat(1) &amp;gt;&amp;gt; space? }

    rule(:space?) { match[&quot;\s&quot;].repeat }
  end
  
  SimpleParser.new.parse(%Q(if 1 then 2 else 3))
  # =&amp;gt; &quot;if 1 then 2 else 3&quot;@0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This means that a match has been found at input position 0. That&amp;#8217;s all the
information you can get from this. But what if this is not enough?&lt;/p&gt;
&lt;p&gt;You add tags. Let&amp;#8217;s say, we want to know what numbers are in the if, then and
else branch, respectively. It would only be natural to assume that tagging 
number like this:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  ...
  rule(:number) { match[&quot;0-9&quot;].repeat(1).as(:number) &amp;gt;&amp;gt; space? }
  ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;would be enough. And it is, in a way:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  SimpleParser.new.number.parse('123')  # =&amp;gt; {:number=&amp;gt;&quot;123&quot;@0}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So you launch the full example (without extracting the number parser) and you
get this:&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
  &amp;gt; ruby simple.rb
  Duplicate subtrees while merging result of 
    IFTHENELSE
  only the values of the latter will be kept. (keys: [:number])
  Duplicate subtrees while merging result of 
    IFTHENELSE
  only the values of the latter will be kept. (keys: [:number])
  {:number=&amp;gt;&quot;3&quot;@17}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The warnings that parslet outputs can be shut up with &lt;code&gt;-W0&lt;/code&gt; on the
command line, but the result is hardly what we expect. (what about 1 and 2?)
So the warnings probably mean something. To explain this, I&amp;#8217;d like to dive
into what parslet does with the output from its parsing stages (also called
atoms).&lt;/p&gt;
&lt;h2&gt;Output Merging Algorithm (Handwaving Version)&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s consider a parser that has no tags (&lt;code&gt;.as(...)&lt;/code&gt;) in it. The
two basic atoms of such a parser will have strings as output:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  str('a').parse('a')   # =&amp;gt; &quot;a&quot;@0
  match['a'].parse('a') # =&amp;gt; &quot;a&quot;@0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is always the case. As shown above, the entire parser will have the 
input string as output. Here are the stages such an input string goes through
before being returned to you:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  parser = str('a') &amp;gt;&amp;gt; str('b') &amp;gt;&amp;gt; str('c')
  input  = 'abc'

  # Stage 1: Sequence matching result (yes, a Ruby Array)
  [&quot;a&quot;@0, &quot;b&quot;@1, &quot;c&quot;@2]
  
  # Stage 2: Merging ajacent strings
  &quot;abc&quot;@0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From this, we&amp;#8217;ll deduce &lt;strong&gt;merge rule #1&lt;/strong&gt;: &lt;em&gt;Elements of a sequence or a
repetition match are concatenated if they&amp;#8217;re strings.&lt;/em&gt; This rule is enough to
explain the first result we had above where our &lt;code&gt;:ifthenelse&lt;/code&gt; rule
would return the string we fed into it.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s inspect what happens when we start tagging. The most interesting case is
partial tagging, since that is what occurs most often in real life. The things
we parse contain delimiters that are not signal, but syntactic noise:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  parser = str('a') &amp;gt;&amp;gt; str('b').as(:important) &amp;gt;&amp;gt; str('c')
  
  # Stage 1: Basic matching
  [&quot;a&quot;@0, {:important =&amp;gt; &quot;b&quot;@1}, &quot;c&quot;@2]
    
  # Stage 2: Merge
  {:important=&amp;gt;&quot;b&quot;@1}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here&amp;#8217;s &lt;strong&gt;rule #2&lt;/strong&gt;: &lt;em&gt;In mixed sequences and repetitions, hashes (tagged
elements) and arrays (collections of tagged elements) are retained.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Now to add a last element, let&amp;#8217;s also look at how multiple tags are handled:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  parser = str('a') &amp;gt;&amp;gt; str('b').as(:b) &amp;gt;&amp;gt; str('c').as(:c)
  
  # Stage 1: Basic matching
  [&quot;a&quot;@0, {:b=&amp;gt;&quot;b&quot;@1}, {:c=&amp;gt;&quot;c&quot;@2}]
  
  # Stage 2: Merge
  {:b=&amp;gt;&quot;b&quot;@1, :c=&amp;gt;&quot;c&quot;@2}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here&amp;#8217;s &lt;strong&gt;rule #3&lt;/strong&gt;: &lt;em&gt;In sequences, hashes mean a named subtree. As such, the
branches are merged into one hash.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Why the &amp;#8220;Duplicate subtrees&amp;#8221; Message?&lt;/h2&gt;
&lt;p&gt;We now have enough rules for figuring out what the message&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
  Duplicate subtrees while merging result of 
    IFTHENELSE
  only the values of the latter will be kept. (keys: [:number])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;means. Each of the parser atoms &lt;code&gt;:_if&lt;/code&gt;, &lt;code&gt;:_then&lt;/code&gt; and
&lt;code&gt;:_else&lt;/code&gt; essentially output &lt;code&gt;{:number =&amp;gt; X}&lt;/code&gt;. (#2) Those
are then merged together into one hash. (#3) Since all of them have a single
key &lt;code&gt;:number&lt;/code&gt;, parslet cannot merge them together without
discarding information. As output we get&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  {:number=&amp;gt;&quot;3&quot;@17}
  # result of 
  {:number=&amp;gt;&quot;1&quot;@3}.merge({:number=&amp;gt;&quot;2&quot;@10}).merge({:number=&amp;gt;&quot;3&quot;@17})
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;How to fix this&lt;/h2&gt;
&lt;p&gt;To fix this, you will need to provide parslet with more information on how
to arrange the information:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  class SimpleParser &amp;lt; Parslet::Parser
    # ...
    rule(:_if)    { str('if') &amp;gt;&amp;gt; space? &amp;gt;&amp;gt; number.as(:cond) }
    rule(:_then)  { str('then') &amp;gt;&amp;gt; space? &amp;gt;&amp;gt; number.as(:then) }
    rule(:_else)  { str('else') &amp;gt;&amp;gt; space? &amp;gt;&amp;gt; number.as(:else) }
    # ...
  end
  
  SimpleParser.new.parse(%Q(if 1 then 2 else 3))
  # =&amp;gt; {:cond=&amp;gt;{:number=&amp;gt;&quot;1&quot;@3}, :then=&amp;gt;{:number=&amp;gt;&quot;2&quot;@10}, :else=&amp;gt;{:number=&amp;gt;&quot;3&quot;@17}}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Results are still merged together, but this time the keys are all distinct.
Hence no warning and no discarded information.&lt;/p&gt;
&lt;h2&gt;And Transformation&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s consider transforming this into something useful:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  class SimpleTransform &amp;lt; Parslet::Transform
    rule(:number =&amp;gt; simple(:n)) { Integer(n) }

    rule(
      :cond =&amp;gt; simple(:c), 
      :then =&amp;gt; simple(:t), 
      :else =&amp;gt; simple(:e)) { [c, t, e] }
  end
  
  SimpleTransform.new.apply(SimpleParser.new.parse(%Q(if 1 then 2 else 3)))
  # =&amp;gt; [1, 2, 3]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, a first rule transforms all &lt;code&gt;:numbers&lt;/code&gt; into real
Ruby numbers in one single step. A second rule then uses the semantic tags to
reorder the information in the tree into a simple triplet of [&lt;span class=&quot;caps&quot;&gt;COND&lt;/span&gt;, &lt;span class=&quot;caps&quot;&gt;THEN&lt;/span&gt;,
&lt;span class=&quot;caps&quot;&gt;ELSE&lt;/span&gt;].&lt;/p&gt;
&lt;p&gt;This shows that both levels of tags (&lt;code&gt;:numbers&lt;/code&gt; and
&lt;code&gt;:if/:then/:else&lt;/code&gt;) are needed and useful.&lt;/p&gt;
&lt;p&gt;Careful readers will have noticed that the above Transformer is missing a 
rule for the case where &amp;#8216;else&amp;#8217; is missing. Here&amp;#8217;s the full Transformer:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  class SimpleTransform &amp;lt; Parslet::Transform
    rule(:number =&amp;gt; simple(:n)) { Integer(n) }

    rule(
      :cond =&amp;gt; simple(:c), 
      :then =&amp;gt; simple(:t), 
      :else =&amp;gt; simple(:e)) { [c, t, e] }
    rule(
      :cond =&amp;gt; simple(:c), 
      :then =&amp;gt; simple(:t)) { [c, t, nil] }
  end
  
  SimpleTransform.new.apply(SimpleParser.new.parse(%Q(if 1 then 2)))
  # =&amp;gt; [1, 2, nil]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Due to the nature of the transformers in parslet the case distinction gets
folded into multiple pattern matching rules. This is supposed to remind
you of functional programming &amp;#8211; Duplication is a good thing, at least here.&lt;/p&gt;
&lt;h2&gt;Wrapping it up&lt;/h2&gt;
&lt;p&gt;I&amp;#8217;ve tried to show you some of the more technical aspects of parsing and
transformation. We&amp;#8217;ve seen how parser output gets mangled to throw away
all those strings parslet deems unimportant to you. With the three rules given
above, you will be able to reason about this stage.&lt;/p&gt;
&lt;p&gt;Also, I hope to inspire a &amp;#8216;more is more&amp;#8217; approach in connection with
transformer rules. Rule actions should not handle case distinctions; a
properly encoded tree will contain enough variety to be able to match
different cases directly. It goes without saying that the code in these blocks
should be kept short, since some of it will be repeated.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="parslet" label="parslet" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="transformations" label="transformations" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="tree" label="tree" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="PORO" label="PORO" />
   
 </entry>
 
 <entry>
   <title>Introducing Cod</title>
   <link href="http://blog.absurd.li/2011/04/21/introducing_cod.html"/>
   <updated>2011-04-21T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2011/04/21/introducing_cod</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://www.google.com/search?q=cod&amp;amp;tbm=isch&quot;&gt;Cod&lt;/a&gt; is a library for
interprocess communication that I am working on in the wee hours these days.
My goal is to make things really simple and to overlay sockets, pipes and
other means of communication with an interface that is easy to remember.&lt;/p&gt;
&lt;p&gt;Cod is open source software and will be released sometime this year. In the
meantime, please look at
&lt;a href=&quot;https://github.com/kschiess/cod&quot;&gt;github.com/kschiess/cod&lt;/a&gt; to get an idea. Try
it out and send me feedback!&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt; (2012-03-31): I&amp;#8217;ve since rewritten cod from scratch. Some of the stuff
talked about here will not work anymore.&lt;/p&gt;
&lt;h2&gt;Building on small elements&lt;/h2&gt;
&lt;p&gt;One of the main ideas of parslet was to build on small elements and to
construct larger ideas from them. This style of construction pervades my work
and never gets old for me. In Cod, I am trying to achieve much the same. All
work you do with it will be based on the concept of a unidirectional
communication channel:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  channel = Cod.pipe
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a channel based on &lt;code&gt;IO.pipe&lt;/code&gt;. It abstracts all the nitty
gritty for you. Here&amp;#8217;s how you communicate with child processes:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  control = Cod.pipe
  
  pid = fork do
    loop do
      # do something important &amp;amp; interesting
      break if control.waiting? &amp;amp;&amp;amp; control.get == :shutdown
    end
  end
  
  # eventually, deciding that we want to shut down the child: 
  control.put :shutdown
  
  Process.waitall
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see in the above sample, Cod defaults to serializing Ruby objects
through channels. This will be open for customization later on, but is mostly
what you&amp;#8217;ll want anyway.&lt;/p&gt;
&lt;p&gt;For now, you are forced to ask if messages are queued up
(&lt;code&gt;control.waiting?&lt;/code&gt;) &amp;#8211; however I will be working on allowing a
Cod.select as well, implementing mixed #select calls on real FDs and Cod
channels. This is real important for the style of process design I am aiming
for.&lt;/p&gt;
&lt;h2&gt;Channels in channels&lt;/h2&gt;
&lt;p&gt;Cod channels try to be serializable. This sounds trivial, but has really 
profound implications. Let&amp;#8217;s say you want to create a client/server type of 
interaction: You will have a common server address and open up a channel to 
it. But to be able to get a response back, you will need two things:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;A channel to receive answers in&lt;/li&gt;
	&lt;li&gt;and to be able to communicate the channel to the server.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&amp;#8217;s how you would probably do this in Cod:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  server = Cod.beanstalk('somehost:11300', 'server')
  client = Cod.beanstalk('somehost:11300')
  
  server.put ['heiho server!', client]
  answer = client.get
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And on the server side of this:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  comm = Cod.beanstalk('somehost:11300', 'server')
  
  message, client = comm.get
  answer = act_on(message)
  client.put answer
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But of course, in real life this is slightly more complex. You will want to
use &lt;code&gt;Cod::Client&lt;/code&gt; and &lt;code&gt;Cod::Service&lt;/code&gt; for this kind of
interaction; it bundles this functionality and delivers a debugged and robust
implementation.&lt;/p&gt;
&lt;h2&gt;Bleeding edge&lt;/h2&gt;
&lt;p&gt;The above code will not even work. I am illustrating the idea, see. But it 
might very soon. Have a look at &lt;code&gt;./examples&lt;/code&gt; &amp;#8211; those typically 
work. For now, assume that nothing else does.&lt;/p&gt;
&lt;h2&gt;Patterns of distributed computing&lt;/h2&gt;
&lt;p&gt;Cod will: Capture and encode patterns of distributed computation/communication
in a library that allows the programmer to focus on the level above. To allow
communication (even cross-communication?) with the newest fad queue server X,
you&amp;#8217;ll write a channel implementation for X and then profit of all higher
order primitives directly.&lt;/p&gt;
&lt;p&gt;Nifty. Been chuckling about the simplicity of it for days now. (Insert thunder
&amp;amp; lightning)&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="zeromq" label="zeromq" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="cod" label="cod" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="beanstalk" label="beanstalk" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="pipes" label="pipes" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="zack" label="zack" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="rpc" label="rpc" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="unix" label="unix" />
   
 </entry>
 
 <entry>
   <title>Parslet and its friends</title>
   <link href="http://blog.absurd.li/2011/02/02/parslet_and_its_friends.html"/>
   <updated>2011-02-02T00:00:00+01:00</updated>
   <id>http://blog.absurd.li/2011/02/02/parslet_and_its_friends</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://kschiess.github.com/parslet&quot;&gt;Parslet&lt;/a&gt; is a small parser framework for
Ruby. It uses the &lt;span class=&quot;caps&quot;&gt;PEG&lt;/span&gt; formalism for its grammars, and its not alone to do so.
I have been asked to compare parslet to
&lt;a href=&quot;http://github.com/nathansobo/treetop&quot;&gt;Treetop&lt;/a&gt; and
&lt;a href=&quot;http://github.com/mjijackson/citrus&quot;&gt;Citrus&lt;/a&gt;. For raw parsing speed. With
complicated grammars.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve generated treetop and citrus versions from &lt;a href=&quot;https://github.com/rkh&quot;&gt;rkhs&lt;/a&gt;
&lt;a href=&quot;https://github.com/rkh/Reak&quot;&gt;Ansi Smalltalk grammar&lt;/a&gt;. As a byproduct, parslet
now exposes visitors for the grammar and can generate these two formats as
string.&lt;/p&gt;
&lt;p&gt;Benchmarks have been run using the above grammar with varying input sizes. 
This matters a lot for this grammar, since it nests very deep. Speed is not
going to vary linearly with size of input in some cases.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve included two versions of parslet, the current one and the very soon to
be released (these days in fact) 1.1.0. The difference between the two is
about one month of performance optimization.&lt;/p&gt;
&lt;p&gt;Treetop and citrus enter the competition with the latest released gems. (1.4.9
and 2.3.4 respectively) I am putting the code that generates these grammars
into the next release of parslet, so these benchmarks can be rerun once either
one changes.&lt;/p&gt;
&lt;p&gt;Here are the pure numbers:&lt;/p&gt;
&lt;table&gt;
	&lt;tr&gt;
		&lt;td&gt; &lt;strong&gt;Input size&lt;/strong&gt; &lt;/td&gt;
		&lt;td&gt; &lt;strong&gt;parslet-1.0&lt;/strong&gt; &lt;/td&gt;
		&lt;td&gt; &lt;strong&gt;parslet-1.1&lt;/strong&gt; &lt;/td&gt;
		&lt;td&gt; &lt;strong&gt;treetop&lt;/strong&gt; &lt;/td&gt;
		&lt;td&gt; &lt;strong&gt;citrus&lt;/strong&gt; &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; 185 chars    &lt;/td&gt;
		&lt;td&gt; 23.644s       &lt;/td&gt;
		&lt;td&gt; 0.291s        &lt;/td&gt;
		&lt;td&gt; 0.644s    &lt;/td&gt;
		&lt;td&gt; 2.503s   &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; 361 chars    &lt;/td&gt;
		&lt;td&gt; 14m28.970s    &lt;/td&gt;
		&lt;td&gt; 0.335s        &lt;/td&gt;
		&lt;td&gt; 0.405s    &lt;/td&gt;
		&lt;td&gt; 1m16.155s&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; 671 chars    &lt;/td&gt;
		&lt;td&gt; 19m2.713s     &lt;/td&gt;
		&lt;td&gt; 0.390s        &lt;/td&gt;
		&lt;td&gt; 0.421s    &lt;/td&gt;
		&lt;td&gt; 1m26.287s&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; 1671 chars   &lt;/td&gt;
		&lt;td&gt; &lt;em&gt;ages&lt;/em&gt;        &lt;/td&gt;
		&lt;td&gt; 0.581s        &lt;/td&gt;
		&lt;td&gt; 0.477s    &lt;/td&gt;
		&lt;td&gt; 1m34.930s&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; 9796 chars   &lt;/td&gt;
		&lt;td&gt; &lt;em&gt;ages&lt;/em&gt;        &lt;/td&gt;
		&lt;td&gt; 2.281s        &lt;/td&gt;
		&lt;td&gt; 0.933s    &lt;/td&gt;
		&lt;td&gt; 5m8.059s &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; 22186 chars  &lt;/td&gt;
		&lt;td&gt; &lt;em&gt;ages&lt;/em&gt;        &lt;/td&gt;
		&lt;td&gt; 5.521s        &lt;/td&gt;
		&lt;td&gt; 1.630s    &lt;/td&gt;
		&lt;td&gt; 7m35.694s&lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;These figures have been measured on my weakly MacBook Air (1.6 GHz, the old
one) using Ruby 1.9.2 p136. The exact figures don&amp;#8217;t matter much, we&amp;#8217;re after a
graphic of big O here:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/2011-02-02/comparison1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As you can see, treetop and parslet kind of fight it out along the X axis. 
Here&amp;#8217;s another graphic that displays the relevant details of that:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/2011-02-02/comparison2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;Conclusions&lt;/h1&gt;
&lt;p&gt;There is a big difference between the 1.0 and 1.1 version of parslet. In 
fact, I think it is now big enough to warrant a release. I&amp;#8217;ll continue to do
performance optimization. The numbers indicate that parslet looses out 
versus treetop for big inputs because it allocates a lot of small objects. 
I might find ways around that.&lt;/p&gt;
&lt;p&gt;One of the ideas I&amp;#8217;m tossing around is to optimize not only the way work is 
being done, but the amount of work itself. If you imagine a tiny part
of a grammar that is still not too unlikely to occur in reality:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  str('chunky') &amp;gt;&amp;gt; str('bacon')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is quite obvious that this could be simplified by a grammar walk to&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  str('chunkybacon')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This impacts on several levels. There is now just one parslet to test against,
which means less code to execute. Input is read in bigger chunks; this will
also benefit performance. And finally, error messages might even be improved
by an optimized version of the grammar. Did I mention that you can now visit
the grammar tree inside parslet by requiring
&lt;code&gt;parslet/atoms/visitor&lt;/code&gt;? So things are ready for this step, its
just that I want to flush the other changes to the public, so to speak, before
starting something new.&lt;/p&gt;
&lt;h2&gt;Parslet vs&amp;#8230;&lt;/h2&gt;
&lt;p&gt;Comparing parslet against treetop or citrus based on performance alone will
always miss the point. Certainly parsing speed matters. But being able to
progress with your parser project and not hit roadblocks early matters just as
much. I&amp;#8217;ve gotten good feedback in that respect; it seems that what works for
me also worked for others. Also, I am happy that people on irc
(&lt;code&gt;#parslet&lt;/code&gt; on freenode) have been helping each other out,
(re)creating the friendly atmosphere I associate with Ruby.&lt;/p&gt;
&lt;p&gt;I think parslet needs to make further progress in several directions. One
direction will certainly be execution speed. And treetops code generation
really does a lot, at least so it seems. But realize, treetop does less work
as well; parslet keeps all these detailed error messages around for you to
peruse. That&amp;#8217;s got to count, right?&lt;/p&gt;
&lt;h2&gt;These are exciting times&lt;/h2&gt;
&lt;p&gt;And I am happy to be part of it. If you haven&amp;#8217;t seen parslets quiet beauty 
yet, you should head to the &lt;a href=&quot;http://kschiess.github.com/parslet&quot;&gt;project home page&lt;/a&gt; and check it out. If you have, please
upgrade to 1.1 – it contains bug fixes and a speedy core. Doing so
will improve both yours and your users experience!&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="parslet" label="parslet" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="treetop" label="treetop" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="citrus" label="citrus" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="peg" label="peg" />
   
 </entry>
 
 <entry>
   <title>Stack Traces in Parslet</title>
   <link href="http://blog.absurd.li/2011/01/11/stack_traces_in_parslet.html"/>
   <updated>2011-01-11T00:00:00+01:00</updated>
   <id>http://blog.absurd.li/2011/01/11/stack_traces_in_parslet</id>
   <content type="html">&lt;p&gt;I get a lot of interesting puzzles from users of
&lt;a href=&quot;http://github.com/kschiess/parslet&quot;&gt;parslet&lt;/a&gt;. You think you&amp;#8217;re asking me about
a feature, but generally, if you have to ask, I haven&amp;#8217;t yet written about it
in &lt;a href=&quot;http://kschiess.github.com/parslet/&quot;&gt;parslets documentation&lt;/a&gt;. And I usually
need to, since it is obviously an issue.&lt;/p&gt;
&lt;p&gt;This post treats why parslet doesn&amp;#8217;t do any compilation; or rather: why parslet
doesn&amp;#8217;t need to do any compilation.&lt;/p&gt;
&lt;h2&gt;Why the compilation phase?&lt;/h2&gt;
&lt;p&gt;One of the reasons other parser frameworks (&amp;#8216;generators&amp;#8217;) generate parser code
for you is that when the parse fails, the exception will contain a stack trace
useful to you. Let&amp;#8217;s look at a small sample in the
&lt;a href=&quot;http://treetop.rubyforge.org/&quot;&gt;Treetop&lt;/a&gt; dialect:&lt;/p&gt;
&lt;pre class=&quot;sh_sourceCode&quot;&gt;&lt;code&gt;
  grammar Simple
    rule addition
      integer (plus integer)*
    end

    rule plus
      '+' space?
    end

    rule integer
      [0-9]+ space?
    end

    rule space
      ' '+
    end
  end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you apply this to the text &amp;#8216;&lt;code&gt;1 ++ 2&lt;/code&gt;&amp;#8217;, Treetop returns
&lt;code&gt;nil&lt;/code&gt; and inspection of the associated failure reason yields this
error message:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;pre&gt;Expected   at line 1, column 3 (byte 3) after +&lt;/pre&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This means that Treetop has been expecting a &amp;#8217; &amp;#8217; (space) at byte 3, but saw a
&amp;#8216;+&amp;#8217; (plus). What Treetop could do (but doesn&amp;#8217;t currently) at this point is
raise an exception at the exact place the parse fails. I&amp;#8217;ve inserted the 
above error message as&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
fail &quot;Expected   at line 1, column 3 (byte 3) after +&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;at the location the parse fails. This gets me the following stack trace:&lt;/p&gt;
&lt;pre class=&quot;sh_sourceCode&quot;&gt;&lt;code&gt;
(...)/simple.rb:202:in `block in _nt_space': Expected   at line 1, column 3 (byte 3) after + (RuntimeError)
  from (...)/simple.rb:197:in `loop'
  from (...)/simple.rb:197:in `_nt_space'
  from (...)/simple.rb:164:in `_nt_integer'
  from (...)/simple.rb:41:in `_nt_addition'
  from (...)/treetop-1.4.9/lib/treetop/runtime/compiled_parser.rb:18:in `parse'
  from driver.rb:8:in `&amp;lt;main&amp;gt;'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since Treetop compiles your grammar down to ruby, the stack trace contains all
rules as method names and indicates where in your grammar you might collide 
with the input provided. So &lt;strong&gt;the stack trace is for debugging&lt;/strong&gt;. Or rather it
could be, if &lt;code&gt;#terminal_parse_failure&lt;/code&gt; in Treetop is overridden
to raise an error.&lt;/p&gt;
&lt;h2&gt;Limitations&lt;/h2&gt;
&lt;p&gt;The stack trace reflects the state of the call stack when the error happens.
This stack is linear, and so must be the stack trace. But &lt;span class=&quot;caps&quot;&gt;PEG&lt;/span&gt; parsing isn&amp;#8217;t
linear: you might encounter an alternative (&amp;#8216;&lt;code&gt;a|b&lt;/code&gt;&amp;#8217;) and ultimately
fail in &amp;#8216;&lt;code&gt;b&lt;/code&gt;&amp;#8217; because neither one matches.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s assume that &amp;#8216;&lt;code&gt;a&lt;/code&gt;&amp;#8217; should have matched the input and contains
an imperfection. We&amp;#8217;ll be interested in all the reasons &amp;#8216;&lt;code&gt;a&lt;/code&gt;&amp;#8217;
didn&amp;#8217;t match the input. &lt;em&gt;But the stack trace will show only why
&amp;#8216;&lt;code&gt;b&lt;/code&gt;&amp;#8217; didn&amp;#8217;t match&lt;/em&gt;, since it was tried last.&lt;/p&gt;
&lt;p&gt;A linear stack trace will never capture why a grammar didn&amp;#8217;t consume a
particular input. If we could design the ideal kind of error message, we would
try to &lt;strong&gt;include all alternatives&lt;/strong&gt; that have failed.&lt;/p&gt;
&lt;p&gt;What else would we wish for? There is one last property of stack traces that 
renders them unsuited for parser error reports: They capture the whole history
of that process. If you give Treetop a rule like this one:&lt;/p&gt;
&lt;pre class=&quot;sh_sourceCode&quot;&gt;&lt;code&gt;
  rule rec
    '.' rec / ''
  end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which matches any number of &amp;#8216;.&amp;#8217;s (dots), your stack trace will grow with the
number of dots in the input. Yet all those recursive calls wont add to the
informational content of the error report. All that it will say is that you
were expecting a dot, but got something else. Ideally, this report should only
show that the rule &amp;#8216;rec&amp;#8217; failed, and what it encountered instead of a dot. &lt;strong&gt;It
should not repeat&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Not Stack Traces, Error Trees&lt;/h2&gt;
&lt;p&gt;The error reports &lt;a href=&quot;http://kschiess.github.com/parslet&quot;&gt;parslet&lt;/a&gt; generates have
both properties we&amp;#8217;ve seen above. They preserve all relevant error
information, not just the last alternative matched, and they never show all
levels of recursion.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s how that might look (taken from 
&lt;a href=&quot;http://kschiess.github.com/parslet/get-started.html&quot;&gt;Getting Started&lt;/a&gt;):&lt;/p&gt;
&lt;pre class=&quot;sh_sourceCode&quot;&gt;&lt;code&gt;
  Parsing 1++2: Don't know what to do with ++2 at line 1 char 2.
  `- Unknown error in SUM / INTEGER
     |- Failed to match sequence (INTEGER OPERATOR EXPRESSION) at line 1 char 3.
     |  `- Unknown error in [0-9]{1, } SPACE?
     |     `- Expected at least 1 of \\s at line 1 char 2.
     |        `- Failed to match \\s at line 1 char 3.
     `- Unknown error in [0-9]{1, } SPACE?
        `- Expected at least 1 of \\s at line 1 char 2.
           `- Failed to match \\s at line 1 char 3.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This illustrates both accounts very well:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;The alternative &lt;code&gt;SUM / INTEGER&lt;/code&gt; produces two error reports, 
  from left to right. The ascii tree helps reading these reports.&lt;/li&gt;
	&lt;li&gt;All parts are readable and refer our grammar directly. Line
  numbers cease to mean much when we&amp;#8217;re dealing with PEGs.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;And beyond&lt;/h2&gt;
&lt;p&gt;There are many more cool parts to parslet; I suggest you check it out. The
upcoming 1.1 release will improve execution speed vastly; of course it
also features the cool error reports you&amp;#8217;ve just been shown.&lt;/p&gt;
&lt;p&gt;It also features tree transformations to be able to act on your grammar, but
that is a topic for another post.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="stacktrace" label="stacktrace" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="parslet" label="parslet" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="parser" label="parser" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="error reporting" label="error reporting" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="design" label="design" />
   
 </entry>
 
 <entry>
   <title>Procrastinate away!</title>
   <link href="http://blog.absurd.li/2010/12/23/procrastinate_away.html"/>
   <updated>2010-12-23T00:00:00+01:00</updated>
   <id>http://blog.absurd.li/2010/12/23/procrastinate_away</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve just released version 0.2 of
&lt;a href=&quot;https://github.com/kschiess/procrastinate&quot;&gt;procrastinate&lt;/a&gt;, the library that is
out to stop you from using threads ever again. Indeed, as has been
&lt;a href=&quot;http://stackoverflow.com/questions/1191553/why-might-threads-be-considered-evil&quot;&gt;observed&lt;/a&gt;
&lt;a href=&quot;http://www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf&quot;&gt;elsewhere&lt;/a&gt;,
threads in programming are evil and belong into limbo at least, if not
downright hell.&lt;/p&gt;
&lt;p&gt;Opinion to the side. While procrastination will not get a lot done, &lt;em&gt;procrastinate&lt;/em&gt; will. You can use it to simply and directly distribute work 
to a few cores and then collect back the results, all in a few lines:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
require 'procrastinate'
include Procrastinate

class Worker
  def fact(n)
    # Insert your factorial implementation here.
  end
end

scheduler = Scheduler.start(SpawnStrategy::Throttled.new(5))
worker = scheduler.create_proxy(Worker.new)

futures = 10.times.map do |i|
  [i, worker.fact(i)]
end

futures.each do |i, fact_i|
  puts &quot;Factorial(#{i}) == #{fact_i.value}&quot;
end

scheduler.shutdown
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Get the code &lt;a href=&quot;/samples/2010-12-23-procrastinate/fact.rb&quot;&gt;here&lt;/a&gt;. This uses at
most 5 worker &lt;del&gt;threads&lt;/del&gt; &lt;ins&gt;processes&lt;/ins&gt; (&lt;code&gt;Throttled.new(5)&lt;/code&gt;) to compute factorials 
behind the scenes and returns the results through an intricate system of pipes
to the main process. All of this is hidden.&lt;/p&gt;
&lt;p&gt;There are only two really important differences to calling
&lt;code&gt;fact(n)&lt;/code&gt; directly:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Your methods return value must be able to pass through
  &lt;code&gt;Marshal.dump&lt;/code&gt; and &lt;code&gt;Marshal.load&lt;/code&gt;. No returning
  lambdas, at least not for now.&lt;/li&gt;
	&lt;li&gt;You cannot share data with the rest of your code. Your methods will get
  executed in total isolation and any changes to the state of your objects
  made will just get lost.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And it is precisely that second point that I consider a feature, not a bug. 
This is real multiprocessing with no data sharing, making your functions as
pure as fresh snow.&lt;/p&gt;
&lt;h2&gt;Status, When is this ready?&lt;/h2&gt;
&lt;p&gt;Procrastinate is where some of my sweat is invested right now; the library
will probably evolve some more before I declare it done. It is today very
useful for a number of things.&lt;/p&gt;
&lt;p&gt;And just to drive this point home, I&amp;#8217;ll show you another application of procrastination: System Administration! Here&amp;#8217;s a tool I&amp;#8217;ve been also hacking on lately: &lt;a href=&quot;https://github.com/kschiess/ndo&quot;&gt;ndo&lt;/a&gt;. Just do a quick&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
gem install ndo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and you&amp;#8217;re almost ready. For this to really work, you have to create a host
set first. A host set is a file below &lt;code&gt;~/.ndo&lt;/code&gt; called anything you like. This 
file contains one line per host you want to execute a command on. Let&amp;#8217;s say we
want to talk to &amp;#8216;barbie&amp;#8217; and &amp;#8216;ken&amp;#8217; at the same time: I&amp;#8217;ll call that set &lt;code&gt;~/.ndo/wonderland&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
barbie
ken
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this, I can now see if either barbies or kens disk is full:&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
&amp;gt; ndo wonderland &quot;df -h&quot;
barbie {
    Filesystem            Size  Used Avail Use% Mounted on
    /dev/sda1              74G  9.0G   61G  13% /
    none                   32G  532K   32G   1% /dev
    none                   32G     0   32G   0% /dev/shm
    none                   32G  224K   32G   1% /var/run
    none                   32G     0   32G   0% /var/lock
    none                   32G     0   32G   0% /lib/init/rw
    none                   74G  9.0G   61G  13% /var/lib/ureadahead/debugfs}

ken {
    Filesystem            Size  Used Avail Use% Mounted on
    /dev/sda1              56G  7.1G   46G  14% /
    none                   32G  400K   32G   1% /dev
    none                   32G     0   32G   0% /dev/shm
    none                   32G  200K   32G   1% /var/run
    none                   32G     0   32G   0% /var/lock
    none                   32G     0   32G   0% /lib/init/rw
    none                   56G  7.1G   46G  14% /var/lib/ureadahead/debugfs
    /dev/sr0              3.9G  3.9G     0 100% /cdrom}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will easily scale over hundreds of servers and give you a scriptable
server infrastructure.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;To drive this home: Start doing things with
&lt;a href=&quot;https://github.com/kschiess/procrastinate&quot;&gt;procrastinate&lt;/a&gt; now. Send me your
ideas and sample applications. Together we&amp;#8217;ll eliminate threading from the
face of this earth.&lt;/p&gt;
&lt;p&gt;And perhaps, execute &amp;#8216;&lt;code&gt;sudo rm -rf /&lt;/code&gt;&amp;#8217; on all of your servers
today. Or not. Better not in fact.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="libraries" label="libraries" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="multiprocessing" label="multiprocessing" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="multithreading" label="multithreading" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ndo" label="ndo" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="procrastinate" label="procrastinate" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="threads" label="threads" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="who_uses_this_anyway" label="who_uses_this_anyway" />
   
 </entry>
 
 <entry>
   <title>Projects, Projects, Projects...</title>
   <link href="http://blog.absurd.li/2010/11/23/projectsprojectsprojects.html"/>
   <updated>2010-11-23T00:00:00+01:00</updated>
   <id>http://blog.absurd.li/2010/11/23/projectsprojectsprojects</id>
   <content type="html">&lt;p&gt;Usually when you don&amp;#8217;t hear from me here, I am really busy. The policy until 
now has been not to write about that; but there I went and cracked.&lt;/p&gt;
&lt;h2&gt;parslet&lt;/h2&gt;
&lt;p&gt;I&amp;#8217;ve discovered that the parser library I&amp;#8217;ve written during my brief excursion 
(that is to be repeated) into the world of compiler writing is valuable on
its own. In fact, its probably even more valuable than any of the things I 
did with the compiler. That&amp;#8217;s just the way these projects go.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve thrown together a small &lt;a href=&quot;http://kschiess.github.com/parslet&quot;&gt;website&lt;/a&gt; for
the project and am working towards an 1.0 release. Encouragements, comments,
&amp;#8230; are welcome!&lt;/p&gt;
&lt;h2&gt;picky&lt;/h2&gt;
&lt;p&gt;On a related note, I&amp;#8217;ve been loosely involved in helping to get
&lt;a href=&quot;http://floere.github.com/picky/index.html&quot;&gt;picky&lt;/a&gt; ready for a 1.0 release as
well. Picky is a search engine for categorized data, data that is organized in
small fields. Like .. for example a database. But who has one of those, right?&lt;/p&gt;
&lt;h2&gt;Apple Mail woes&lt;/h2&gt;
&lt;p&gt;At work I was trying to get Apple Mail and Thunderbird to autoconfigure
email. My goal was to have the user enter &amp;#8216;john.doe@example.com&amp;#8217; and figure
out the rest by looking at our &lt;span class=&quot;caps&quot;&gt;LDAP&lt;/span&gt; database.&lt;/p&gt;
&lt;p&gt;And I got it working. At least for Thunderbird which has a &lt;a href=&quot;https://wiki.mozilla.org/Thunderbird:Autoconfiguration&quot;&gt;documented
&lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt; and for Microsoft
Outlook, which also has an
&lt;a href=&quot;http://technet.microsoft.com/en-us/library/cc511507.aspx&quot;&gt;&lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt;. Yeah, you read
right. &lt;em&gt;Microsoft Outlook&lt;/em&gt;. That didn&amp;#8217;t go according to plan.&lt;/p&gt;
&lt;p&gt;Apple Mail does two things for autodiscovery behind the scenes.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;It &lt;em&gt;phones home&lt;/em&gt; (apple.com) getting a binary answer that is &lt;span class=&quot;caps&quot;&gt;AFAIK&lt;/span&gt; not
  documented. Try with &amp;#8216;something@gmail.com&amp;#8217;.&lt;/li&gt;
	&lt;li&gt;It pretends to speak Microsoft and &lt;em&gt;doesn&amp;#8217;t honor the answer&lt;/em&gt;. It posts the
  same autodiscovery &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; request as Outlook does. Somehow I failed to get it
  working with the same answer that Outlook accepts. &lt;strong&gt;So there&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You probably got by now that this is a tale of &lt;span class=&quot;caps&quot;&gt;FAIL&lt;/span&gt;. Indeed I posted to 
&lt;a href=&quot;http://stackoverflow.com/questions/4245828/implementing-settings-autodiscovery-for-apple-mail&quot;&gt;stackoverflow&lt;/a&gt; about this, but can I really expect an answer to that? Universe? 
Surprise me!.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="snafu" label="snafu" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="apple" label="apple" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="microsoft" label="microsoft" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="mail" label="mail" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="picky" label="picky" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="parslet" label="parslet" />
   
 </entry>
 
 <entry>
   <title>Merged upstream to jekyll</title>
   <link href="http://blog.absurd.li/2010/11/08/jekyll_pulled_from_upstream.html"/>
   <updated>2010-11-08T00:00:00+01:00</updated>
   <id>http://blog.absurd.li/2010/11/08/jekyll_pulled_from_upstream</id>
   <content type="html">&lt;p&gt;For those who use my inofficial fork of
&lt;a href=&quot;http://github.com/kschiess/jekyll&quot;&gt;jekyll&lt;/a&gt; that also speaks haml, good news:
I&amp;#8217;ve just completed another merge of the new features of jekyll with the
changes that enable haml and sass.&lt;/p&gt;
&lt;p&gt;This time the merge bridges a gap of two minor versions; a lot of changes had
happened upstream. Looks like we might soon be able to close down this fork
and get official haml/sass support in jekyll, albeit only in unsafe mode.&lt;/p&gt;
&lt;p&gt;Anyway, update today.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="jekyll" label="jekyll" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="haml" label="haml" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="merge" label="merge" />
   
 </entry>
 
 <entry>
   <title>last_puppetrun - A small tool for your puppets</title>
   <link href="http://blog.absurd.li/2010/06/07/a_small_tool_for_puppet.html"/>
   <updated>2010-06-07T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2010/06/07/a_small_tool_for_puppet</id>
   <content type="html">&lt;p&gt;To complement last weeks post about &lt;a href=&quot;/2010/05/27/how_to_get_your_very_own_puppet_show.html&quot;&gt;getting puppet into your
datacenter&lt;/a&gt;, here&amp;#8217;s a
small post on a tool I wrote to monitor your puppets.&lt;/p&gt;
&lt;p&gt;The tool will look at &lt;code&gt;/var/log/messages&lt;/code&gt; and look for the last 
successful puppet run for all your nodes (as given by&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
  $ puppetca -al
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;). It needs to be run as root.&lt;/p&gt;
&lt;p&gt;You can download it &lt;a href=&quot;http://github.com/kschiess/last_puppetrun&quot;&gt;from github&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
  git clone git://github.com/kschiess/last_puppetrun.git
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Not the same as &lt;code&gt;puppetlast&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Connaisseurs of puppet will bark: &amp;#8220;But there is already puppetlast&amp;#8221;. &lt;em&gt;Yes.
There is.&lt;/em&gt; The information &lt;code&gt;puppetlast&lt;/code&gt; gives you is &lt;em&gt;&amp;#8220;When did
puppet last run on host X&amp;#8221;&lt;/em&gt;?. That is not at all the same as &amp;#8220;When did puppet
last &lt;em&gt;successfully&lt;/em&gt; run on host X?&amp;#8221; &amp;#8211; which is the answer provided by
&lt;code&gt;last_puppetrun&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you have a parse error / a doubly defined resource in your puppet recipes, 
the tool presented here will allow you to see the problem early.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="puppet" label="puppet" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="last_puppetrun" label="last_puppetrun" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="automation" label="automation" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="system administration" label="system administration" />
   
 </entry>
 
 <entry>
   <title>How to get your own puppet show</title>
   <link href="http://blog.absurd.li/2010/05/27/how_to_get_your_very_own_puppet_show.html"/>
   <updated>2010-05-27T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2010/05/27/how_to_get_your_very_own_puppet_show</id>
   <content type="html">&lt;p&gt;When I mention &lt;a href=&quot;http://www.puppetlabs.com/&quot;&gt;puppet&lt;/a&gt; to people, a lot of them
answer: &amp;#8220;Oh, don&amp;#8217;t get started on this, I should do that as well.&amp;#8221; Yeah, well
guess what, you should. Here&amp;#8217;s my helping hand to that.&lt;/p&gt;
&lt;p&gt;Puppet is a tool that allows you to manage the configuration of your data
center in a recipe and then apply it to each machine. It is open-sourceish and
developed by a company called &amp;#8216;&lt;a href=&quot;http://www.puppetlabs.com/&quot;&gt;Puppet Labs&lt;/a&gt;&amp;#8217; (formerly: &amp;#8216;Reductive Labs&amp;#8217;) in 
Portland, Oregon.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s what you need to get started with puppet:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;A puppet master&lt;/strong&gt;
  This can be any machine at all, although I would recommend you virtualize
  this. The puppet master will not be doing a lot at first. It seems like a 
  real box would be wasted on this.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;At least &lt;strong&gt;one other machine&lt;/strong&gt; you want to manage.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, the real benefits of puppet will apply when you manage hundreds or 
thousands of machines with it. But. Knowing puppet, I would even manage my two
machine production setup with it. For any kind of setup that has real value, 
you need a description of some kind on how to reconstruct the machines should
you loose them completely. Most people have started entering this step-by-step information into a Wiki of a kind. Puppet can be that as well.&lt;/p&gt;
&lt;p&gt;Either way. Here&amp;#8217;s what comes next in this article:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Pick a puppet&lt;/li&gt;
	&lt;li&gt;Install the puppet master&lt;/li&gt;
	&lt;li&gt;Create an initial configuration&lt;/li&gt;
	&lt;li&gt;Install puppet on the clients&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Pick a puppet&lt;/h2&gt;
&lt;p&gt;The real trouble with puppet is that it is (still) a relatively young project
and under active development. You want to get a really recent puppet version
to be able to use new features. On the other hand, puppet is the first thing
you need to install on a machine &amp;#8212; to do this in an automated way, you want
to be able to use what your package management gives you.&lt;/p&gt;
&lt;p&gt;I would recommend you look at the puppet versions your package managements
give you (you will probably be managing more than one OS/ OS version). Then
pick the lowest number. That is the version you will be writing your puppet
recipies against. If that is not high enough &amp;#8212; you need some other solution.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ve gone the other way and have done our own packaging. This way, we can be
sure that all puppets talk to each other. I can&amp;#8217;t really tell you here how to
do that, but a good start is to fetch the latest package for your OS, unpack
it, replace the puppet files in it and then repack it. Most often, this will
work fine.&lt;/p&gt;
&lt;h2&gt;Install the puppet master&lt;/h2&gt;
&lt;p&gt;The puppet master machine should be reachable as &amp;#8216;puppet.&lt;span class=&quot;caps&quot;&gt;YOURDOMAIN&lt;/span&gt;&amp;#8217; or just
&amp;#8216;puppet&amp;#8217;. This will avoid a lot of trouble later on.&lt;/p&gt;
&lt;p&gt;Your puppet master will need a package called &amp;#8216;puppetmaster&amp;#8217;. This can also be
installed via rubygems, but most often the OS package will give you
startup/shutdown scripts that the gem doesn&amp;#8217;t have.&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
  root       734  0.0  0.0   5992   604 tty1     Ss+  08:44   0:00 /sbin/getty -8 38400 tty1
  puppet    1044  0.5  0.9 116356 39356 ?        Ssl  08:45   0:00 /usr/bin/ruby1.8 /usr/sbin/puppetmasterd --masterport=8140
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a result of the above step, you should see a puppetmaster binary running
and you should have the &amp;#8216;puppetca&amp;#8217; script available (as root).&lt;/p&gt;
&lt;p&gt;You will also need some kind of source control system. I recommend git (&amp;#8216;git-core&amp;#8217;).&lt;/p&gt;
&lt;h2&gt;Create an initial configuration&lt;/h2&gt;
&lt;p&gt;Here is a &lt;a href=&quot;/samples/2010-05-puppet/puppet_sample_config.tgz&quot;&gt;sample puppet
configuration&lt;/a&gt; for you to
fill in. This follows the &lt;a href=&quot;http://projects.puppetlabs.com/projects/puppet/wiki/Puppet_Best_Practice&quot;&gt;puppet best
practices&lt;/a&gt;.
Just check this in into a git repository and fill in the blanks.&lt;/p&gt;
&lt;p&gt;Then have a look at &lt;code&gt;/etc/puppet/&lt;/code&gt; on your puppet master server. (or where your config sits) Some of these files are also worthy to be included
in your repository. Candidates are &lt;code&gt;fileserver.conf&lt;/code&gt; and &lt;code&gt;puppet.conf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Once you&amp;#8217;ve gone and completed the sample structure, you can make a checkout
of it to &lt;code&gt;/etc/puppet/&lt;/code&gt;. This is what you will be doing each time
you make a change to the configuration.&lt;/p&gt;
&lt;h2&gt;Install puppet on the clients&lt;/h2&gt;
&lt;p&gt;Now let&amp;#8217;s link up a client that has puppet installed. First, you should request a certificate from your puppet master:&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
  # puppetd --test
  warning: peer certificate won't be verified in this SSL session
  notice: Did not receive certificate
  notice: Set to run 'one time'; exiting with no certificate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On your server (as root), list the clients that have requested a certificate (but haven&amp;#8217;t received one yet):&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
  # puppetca -l
  myfirstnode.DOMAIN
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sign the certificate:&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
  # puppetca -s myfirstnode.DOMAIN
  Signed myfirstnode.DOMAIN
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now repeat:&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
  # puppetd --test
  ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You should see your initial configuration for the node being applied.&lt;/p&gt;
&lt;h2&gt;Parting Words&lt;/h2&gt;
&lt;p&gt;These guidelines have been compiled from documentation at puppet labs and from my own experience. &lt;a href=&quot;http://docs.puppetlabs.com/guides/configuring.html&quot;&gt;Here&lt;/a&gt; &lt;a href=&quot;http://docs.puppetlabs.com/&quot;&gt;are&lt;/a&gt; &lt;a href=&quot;http://docs.puppetlabs.com/guides/language_tutorial.html&quot;&gt;some&lt;/a&gt; of the links that I recommend also reading. And now off you go, recruit an &lt;a href=&quot;http://www.youtube.com/watch?v=x5sXk5tHbqA&quot;&gt;army of puppets to reign over&lt;/a&gt;!&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="system administration" label="system administration" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="puppet" label="puppet" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="guide" label="guide" />
   
 </entry>
 
 <entry>
   <title>New Stuff in rspec - a Cheatsheet</title>
   <link href="http://blog.absurd.li/2010/05/11/new_features_in_rspec.html"/>
   <updated>2010-05-11T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2010/05/11/new_features_in_rspec</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://pure-rspec-rubynation.heroku.com/&quot;&gt;This&lt;/a&gt; presentation puts together a
nice overview of features that old-school rspec users like me don&amp;#8217;t really
use. I have decided to put myself to it and extracted a &lt;a href=&quot;/img/2010-05-11/rspec_new_features.pdf&quot;&gt;cheat
sheet&lt;/a&gt; from the presentation for your
perusal. Full steam ahead!&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="rspec" label="rspec" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="cheat sheet" label="cheat sheet" />
   
 </entry>
 
 <entry>
   <title>Migrating Request Trackers backend</title>
   <link href="http://blog.absurd.li/2010/04/14/migrating_request_tracker_backend.html"/>
   <updated>2010-04-14T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2010/04/14/migrating_request_tracker_backend</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve been stupid enough to try to use &lt;a href=&quot;http://bestpractical.com/rt/&quot;&gt;Request Tracker&lt;/a&gt; 
with its default (sqlite) backend. 
&lt;a href=&quot;http://www.sqlite.org/faq.html#q5&quot;&gt;Bad idea&lt;/a&gt;. Please read that and don&amp;#8217;t think
I am bashing sqlite, I am not.&lt;/p&gt;
&lt;p&gt;As a note to self and to the next guy falling into that trap, here&amp;#8217;s how it 
can be done:&lt;/p&gt;
&lt;h2&gt;Preparation&lt;/h2&gt;
&lt;p&gt;Install postgresql and make sure you can access it through a local user using
passwords. This might mean you have to tweak postgresqls settings, notably
&lt;code&gt;pg_hba.conf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re using Request Tracker version 3.8.4, you can use the schema behind
this &lt;a href=&quot;/samples/2010-04-14/request_tracker-3.8.4-schema.sql&quot;&gt;link&lt;/a&gt; to prepare
your database. Otherwise I would suggest using the tool that is provided 
in the installation (&lt;code&gt;rt-setup-database&lt;/code&gt;) to do that. Your command
line will have to look something like this:&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
  $ rt-setup-database --action schema
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;RT will use its database settings from
&lt;code&gt;/etc/request-trackerXXX/RT_SiteConfig.pm&lt;/code&gt; to connect to your
database, so make sure that points to the new location&amp;#8230;&lt;/p&gt;
&lt;h2&gt;Migration&lt;/h2&gt;
&lt;p&gt;Now you have two databases that have exactly the same schema, but one contains
the data. Turn off your mail gateway and your apache (site is closed for now)
and install the prerequisites for this
&lt;a href=&quot;/samples/2010-04-14/migrate_to_pgsql.rb&quot;&gt;script&lt;/a&gt;. This should mostly be the
&amp;#8216;pg&amp;#8217; gem and the &amp;#8216;sqlite3&amp;#8217; gem. Using aptitude, this would look like this:&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
  $ aptitude install libpgsql-ruby libsqlite3-ruby
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Running the script should be easy: Give it the location of RTs sqlite database
as parameter. Adjust the pgsql connection settings inside the script to match
your installation.&lt;/p&gt;
&lt;p&gt;The script will insert all rows from sqlite into postgresql that are missing 
there. You can run the script a few times; it will reach a steady state the 
second time round that looks like this:&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
  ACL: Source: 26, Target: 26
  ... lots of tables ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Those are all tables and their corresponding &lt;code&gt;max(id)&lt;/code&gt;s.&lt;/p&gt;
&lt;h2&gt;Correct the sequences&lt;/h2&gt;
&lt;p&gt;Since all &lt;code&gt;INSERT&lt;/code&gt;s are done giving the &lt;code&gt;id&lt;/code&gt; of the 
rows the postgresql sequences will all be off and you wont be able to insert
new data. This is easy to correct: Run the following lines against your database:&lt;/p&gt;
&lt;pre class=&quot;sh_sql&quot;&gt;&lt;code&gt;
  select setval('acl_id_seq', (select max(id) from acl));
  select setval('attachments_id_seq', (select max(id) from attachments));
  select setval('attributes_id_seq', (select max(id) from attributes));
  select setval('cachedgroupmembers_id_seq', (select max(id) from cachedgroupmembers));
  select setval('customfields_id_seq', (select max(id) from customfields));
  select setval('customfieldvalues_id_seq', (select max(id) from customfieldvalues));
  select setval('groupmembers_id_seq', (select max(id) from groupmembers));
  select setval('groups_id_seq', (select max(id) from groups));
  select setval('links_id_seq', (select max(id) from links));
  select setval('objectcustomfields_id_s', (select max(id) from objectcustomfields));
  select setval('objectcustomfieldvalues_id_s', (select max(id) from objectcustomfieldvalues));
  select setval('principals_id_seq', (select max(id) from principals));
  select setval('queues_id_seq', (select max(id) from queues));
  select setval('scripactions_id_seq', (select max(id) from scripactions));
  select setval('scripconditions_id_seq', (select max(id) from scripconditions));
  select setval('scrips_id_seq', (select max(id) from scrips));
  select setval('templates_id_seq', (select max(id) from templates));
  select setval('tickets_id_seq', (select max(id) from tickets));
  select setval('transactions_id_seq', (select max(id) from transactions));
  select setval('users_id_seq', (select max(id) from users));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These statements are a copy of what himdel has on his
&lt;a href=&quot;http://himdel.blogspot.com/2009/04/migrating-request-tracker-from-rt-345.html&quot;&gt;blog&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Done&lt;/h2&gt;
&lt;p&gt;This should conclude your migration. Start apache and the mail gateway again
and browse through your tickets – they are all there. Of course, this is
at your own peril. But if all goes well, you will have migrated your Request
Tracker instance to PostgreSQL in almost no time.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="request tracker" label="request tracker" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="unix" label="unix" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="postgresql" label="postgresql" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="sqlite" label="sqlite" />
   
 </entry>
 
 <entry>
   <title>ZFS backups and other tidbits</title>
   <link href="http://blog.absurd.li/2010/04/05/zfs_backups_and_tidbits.html"/>
   <updated>2010-04-05T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2010/04/05/zfs_backups_and_tidbits</id>
   <content type="html">&lt;p&gt;It seems that OpenSolaris zfs has already got &lt;code&gt;zfs backup&lt;/code&gt; and 
&lt;code&gt;zfs restore&lt;/code&gt; commands. Our Solaris release doesn&amp;#8217;t yet. Anyhow, 
backing up is &lt;a href=&quot;http://www.taobackup.com/&quot;&gt;simple&lt;/a&gt;, right?&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ll perform the following steps:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Snapshot the datasets&lt;/strong&gt; once an hour. This can be done with the simplest of
  scripts, the hard part being a naming scheme for the backups.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  dataset = 'pool/something'
  name = Time.now.strftime(&quot;%Y%m%d%H%M&quot;)
  `zfs snapshot #{dataset}@#{name}`
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Sync the snapshots&lt;/strong&gt; to another machine (hot standby) using &lt;code&gt;zfs
  send&lt;/code&gt; and &lt;code&gt;zfs receive&lt;/code&gt; with a good combination of the
  flags &lt;code&gt;-I&lt;/code&gt; and &lt;code&gt;-R&lt;/code&gt;.
  This is almost trivial as well. &lt;span class=&quot;caps&quot;&gt;ZFS&lt;/span&gt; does a whole lot of work there for you, 
  you just have to come up with what to sync where.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;And lastly, to prevent our pools from running full: &lt;strong&gt;Weed out snapshots&lt;/strong&gt; we
  don&amp;#8217;t want anymore, both in the backup and in the active set. This is what
  the remainder of the article is going to be about.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For all practical purposes, only the &lt;a href=&quot;http://en.wikipedia.org/wiki/Backup_rotation_scheme&quot;&gt;Grandfather-Father-Child
scheme&lt;/a&gt; helps us in this
situation. We don&amp;#8217;t bother with the &lt;em&gt;Towers of Hanoi&lt;/em&gt; even though that might
be an algorithmic exercise worth it. It turns out that a generic &lt;span class=&quot;caps&quot;&gt;GFC&lt;/span&gt;
implementation is worth it as well.&lt;/p&gt;
&lt;p&gt;The Grandfather-Father-Child (&lt;span class=&quot;caps&quot;&gt;GFC&lt;/span&gt;) scheme sounds easy enough when presented.
Let&amp;#8217;s assume you want to keep 24 hourly , 7 daily, 12 monthly and 2 yearly
backups around. This gives you a solid backlog for your data.&lt;/p&gt;
&lt;p&gt;In the above setup, your backups will be named like this:&lt;/p&gt;
&lt;pre&gt;
  pool/dataset@201004042200
  pool/dataset@201004042300
  pool/dataset@201004050000
  (... snippage ...)
  pool/dataset@201004050700
  pool/dataset@201004050800
  pool/dataset@201004050900
&lt;/pre&gt;
&lt;p&gt;But to infuse a bit of real world in this problem description, here&amp;#8217;s what&amp;#8217;ll
happen: Your administrator will snapshot any dataset at random before making
an important change. He&amp;#8217;ll either name this snapshot
&lt;code&gt;@pre_important_change&lt;/code&gt; or even
&lt;code&gt;@201004050907_important_change&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Another thing that &lt;em&gt;will&lt;/em&gt; happen (as in
&lt;a href=&quot;http://en.wikipedia.org/wiki/Murphy&amp;#39;s_law&quot;&gt;Murphy&lt;/a&gt; says it does) is that your
cronjob that does the snapshots will do so at irregular moments because of
several factors (machine load, pesky users).&lt;/p&gt;
&lt;p&gt;So here is a more realistic input to our algorithm:&lt;/p&gt;
&lt;pre&gt;
  pool/dataset@201004042200
  pool/dataset@201004042301
  pool/dataset@201004050010
  (... snippage ...)
  pool/dataset@201004050705
  pool/dataset@201004050800
  pool/dataset@pre_important_change
  pool/dataset@201004050900
  pool/dataset@201004050907_important_change
&lt;/pre&gt;
&lt;p&gt;So I was looking for something simple that could &amp;#8211; in this context &amp;#8211; apply
rules like the ones above (24 hourly backups). After a bit of discussion with
one of my coworkers we came up with something surprisingly simple given the
irregularity of the problem.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ll express the algorithm as a method on something I will call a &lt;code&gt;SnapshotSet&lt;/code&gt;, returning a new set containing the snapshots we 
want to &lt;em&gt;keep&lt;/em&gt;. Here&amp;#8217;s now you would use this:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  set = SnapshotSet.new([snapshot1, snapshot2, ...])
  
  keep = set.gpc(
    1.hour =&amp;gt; 24, 
    1.day =&amp;gt; 7)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This reduces the problem to this: Given a list of snapshots (each with a
timestamp) and a list of &lt;code&gt;(interval, count)&lt;/code&gt; tuples, find which 
snapshots should be kept.&lt;/p&gt;
&lt;p&gt;The following is structured in two parts: What to do for each of the tuples and how to synthesize the resulting keep list.&lt;/p&gt;
&lt;h2&gt;For each &lt;code&gt;(interval, count)&lt;/code&gt; tuple&amp;#8230;&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/img/2010-04-05/zfs_obsolete_1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The image shows a timeline with snapshots in orange. Let&amp;#8217;s say we want to find
out which snapshots to keep to be able to provide 7 daily snapshots. (&lt;code&gt;(1.day, 7)&lt;/code&gt;) To do this, we create a list of sample points starting 1 day ago, with step size of 1 day each. This is also drawn in the 
picture.&lt;/p&gt;
&lt;p&gt;For each of those sample points the snapshot that is closest in time is kept. 
Look at this picture:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/2010-04-05/zfs_obsolete_2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This procedure will yield &lt;em&gt;at most&lt;/em&gt; 7 daily snapshots to keep in a best effort
manner.&lt;/p&gt;
&lt;h2&gt;And how to synthesize the result&lt;/h2&gt;
&lt;p&gt;The resulting list of snapshots to keep can now be assembled by computing the
union of all the snapshots that would have been kept for each tuple. This list
completely covers what the rules specified.&lt;/p&gt;
&lt;p&gt;Except that we probably don&amp;#8217;t want to delete all the newest snapshots that the
rules say nothing about, like the few ticks between &lt;em&gt;1 day ago&lt;/em&gt; and the &lt;em&gt;now&lt;/em&gt;.
So I&amp;#8217;ll just say that all snapshots between now and the first tick of all
tuples must be kept as well. (hand waving)&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This three-step backup plan seems to work surprisingly well. If anyone is
interested in some code, I think I could put this up on github &amp;#8211; but I don&amp;#8217;t
want to add to the redundancy in the field ;). In this article I&amp;#8217;ve shown how
a simple Grandfather-Father-Child backup scheme could be made to work with
real world input data.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="zfs" label="zfs" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="algorithm" label="algorithm" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="design" label="design" />
   
 </entry>
 
 <entry>
   <title>A few Ruby Anti-Patterns</title>
   <link href="http://blog.absurd.li/2010/03/18/some_ruby_antipatterns.html"/>
   <updated>2010-03-18T00:00:00+01:00</updated>
   <id>http://blog.absurd.li/2010/03/18/some_ruby_antipatterns</id>
   <content type="html">&lt;p&gt;Some things you can do with Ruby you just shouldn&amp;#8217;t. Often one doesn&amp;#8217;t notice
until later on, when you are looking for a bug in code.&lt;/p&gt;
&lt;h2&gt;rescue everything&lt;/h2&gt;
&lt;p&gt;This is a story from real life. In our recent release of
&lt;a href=&quot;http://rubyforge.org/projects/net-ldap&quot;&gt;net-ldap&lt;/a&gt; we have this snippet of
code:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  begin
    @socket = TCPSocket.new(host, port)
  rescue
    raise LdapError, &quot;Something is wrong with your connection.&quot;
  end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So when you get the &amp;#8216;Something is wrong &amp;#8230;&amp;#8217; error, where do you go look?
Right, you check and recheck your credentials.&lt;/p&gt;
&lt;p&gt;Except that wasn&amp;#8217;t the problem. We recently reorganized the project and fixed
some Ruby 1.9 stuff. This was the reason for our rerelease as well. During
that work, we (ok, probably I did) fat-fingered the import of
&amp;#8216;&lt;code&gt;socket&lt;/code&gt;&amp;#8217; with the obvious &lt;code&gt;NameError&lt;/code&gt; as a
consequence.&lt;/p&gt;
&lt;p&gt;The above code will tell you that something is wrong with the connection even
if nothing is. Look at how I think this should be written:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  begin
    @conn = TCPSocket.new( server[:host], server[:port] )
  rescue SocketError
    raise LdapError, &quot;No such address or other socket error.&quot;
  rescue Errno::ECONNREFUSED
    raise LdapError, &quot;Server #{server[:host]} refused connection on port #{server[:port]}.&quot;
  end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We could dispute the details here, but the main point is that you should
almost never &lt;em&gt;rescue everything&lt;/em&gt;. This is an anti-pattern in Ruby and in other
languages as well. If you don&amp;#8217;t know what happened, make it scream really
loud.&lt;/p&gt;
&lt;p&gt;There is another big anti-pattern hidden in this war story: Write tests for
your code. Because that would have told me what was wrong.&lt;/p&gt;
&lt;h2&gt;Extending basic Types&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s say I have a few derivates of Ruby basic types with strings attached:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  class StringString &amp;lt; String
    attr_accessor :strings
  end
  class StringArray &amp;lt; Array
    attr_accessor :strings
  end
  
  ary = [
    StringString.new('foo'),
    StringArray.new([StringString.new('bar')])
  ]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I want to create a clean &lt;span class=&quot;caps&quot;&gt;YAML&lt;/span&gt; representation of this, looking something like&lt;/p&gt;
&lt;pre class=&quot;sh_yaml&quot;&gt;&lt;code&gt;
  ---
  - foo
  - - bar
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But turning what I have into &lt;span class=&quot;caps&quot;&gt;YAML&lt;/span&gt; I get this:&lt;/p&gt;
&lt;pre class=&quot;sh_yaml&quot;&gt;&lt;code&gt;
  --- 
  - !str:StringString foo
  - !seq:StringArray 
    - !str:StringString bar
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And of course, turning it to &lt;span class=&quot;caps&quot;&gt;YAML&lt;/span&gt; is just one of the problems you have.
Everywhere you use inspection/reflection in your code, these
&lt;code&gt;StringString&lt;/code&gt; things won&amp;#8217;t behave correctly.&lt;/p&gt;
&lt;p&gt;Stop and think about how you would do it for a second. There seems to be no
real easy way to do this, even when you own the &lt;code&gt;StringString&lt;/code&gt; and
&lt;code&gt;StringArray&lt;/code&gt; types. Of course, if you knew you only had 
strings, you could use &lt;code&gt;#to_s / #to_a&lt;/code&gt; and be done with it. But 
polymorphically? What we need is a &lt;code&gt;#detach_strings&lt;/code&gt; method.&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  def detach_strings(mess)
    mess.class.ancestors[1].new(mess)
  end

  puts detach_strings(StringString.new('bar')).to_yaml
  # =&amp;gt; &quot;--- bar\n&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ugly, isn&amp;#8217;t it? Yeah. But in my opinion that is entirely the blame of the
extended basic type anti-pattern. I wont spend time on making this beautiful,
but rather will transform the code so it doesn&amp;#8217;t use extended types anymore.&lt;/p&gt;
&lt;h2&gt;Your own Anti-Patterns?&lt;/h2&gt;
&lt;p&gt;Do you have any Ruby anti-patterns from your work? I would be interested in 
hearing about them.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="anti pattern" label="anti pattern" />
   
 </entry>
 
 <entry>
   <title>Notes on CoffeeScript; a javascript replacement</title>
   <link href="http://blog.absurd.li/2010/02/22/experimenting_with_coffeescript.html"/>
   <updated>2010-02-22T00:00:00+01:00</updated>
   <id>http://blog.absurd.li/2010/02/22/experimenting_with_coffeescript</id>
   <content type="html">&lt;p&gt;This weekend I had the chance to work/play with &lt;a href=&quot;http://github.com/jashkenas/coffee-script&quot;&gt;CoffeeScript&lt;/a&gt;, a new language 
created by Jeremy Ashkenas.&lt;/p&gt;
&lt;p&gt;I had been so desperate trying to get &lt;em&gt;jquery.facelist&lt;/em&gt; by Ian Tearle do my
evil bidding that I decided to scratch and rewrite it. After all, how
complicated can things be, its just javascript, right? This was – in the past 
– a recipe for disaster. I would try a rewrite and end up with something 
as complicated as the original. And end up feeling worse about it, since this
time it was my code.&lt;/p&gt;
&lt;p&gt;A change of approach was in order. And since I am a fan of clever code generation, I decided to use CoffeeScript for my rewrite. Here&amp;#8217;s some notes about this experiment.&lt;/p&gt;
&lt;h2&gt;Source to Source compilation&lt;/h2&gt;
&lt;p&gt;CoffeeScript installs with&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
  $ gem install coffee-script
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Its executable &lt;code&gt;coffee&lt;/code&gt; is a source to source compiler that turns
CoffeeScript into perfectly valid and well formed Javascript. CoffeeScript is
written in Ruby using a treetop parser.&lt;/p&gt;
&lt;h2&gt;Shorter than Javascript&lt;/h2&gt;
&lt;p&gt;The source code you write in CoffeeScript is considerably shorter than what
you would write in Javascript. Languages either read like noise or they read
like signal &amp;#8211; and CoffeeScript is definitively signal. To me, Javascript has
always seemed like just a tiny bit too complicated to properly remember &amp;#8211; and
what I wrote turned always out to be lacking in some area.&lt;/p&gt;
&lt;p&gt;As an example, remember what you have to do to create your own namespace in 
Javascript? Yeah,&lt;/p&gt;
&lt;pre class=&quot;sh_javascript&quot;&gt;&lt;code&gt;
  (function() {
    // your isolated namespace here
  })
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;does the job. CoffeeScript will do that for you, no syntax to learn. Turns
out, you always want to do that anyway.&lt;/p&gt;
&lt;p&gt;Or, another example. I always have to glance at a reference to remember how
to do prototype based &lt;span class=&quot;caps&quot;&gt;OOP&lt;/span&gt; in javascript. Not just because it is not class 
based, that part I&amp;#8217;ve been able to wrap my head around by now. But because the
syntax is so much like blessing references in Perl:&lt;/p&gt;
&lt;pre class=&quot;sh_javascript&quot;&gt;&lt;code&gt;
  Foo.prototype.my_method = function my_method() {
    return alert('hi');
  };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What the fail. This is so much typing, it&amp;#8217;s almost like Javascript is trying
to look like Java. CoffeeScript makes this pleasant:&lt;/p&gt;
&lt;pre class=&quot;sh_coffeescript&quot;&gt;&lt;code&gt;
  Foo::my_method: -&amp;gt;
    alert('hi')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CoffeeScript doesn&amp;#8217;t hide Javascript, it just makes it easy. (&lt;a href=&quot;http://jashkenas.github.com/coffee-script/&quot;&gt;Here&amp;#8217;s the rest
of the introduction&lt;/a&gt;)&lt;/p&gt;
&lt;h2&gt;Writing correct Javascript&lt;/h2&gt;
&lt;p&gt;CoffeeScript also takes the pain out of writing correct Javascript. Maybe I am
in this business for too long already, but I distinctly remember fighting with
Internet Explorer (was it 4?) for hours on end over a misplaced semicolon.
Generations of future programmers will be able to learn how not to do error
reporting from that piece of crap. It just told you that you had an error in
line &lt;span class=&quot;caps&quot;&gt;XYZ&lt;/span&gt;, and whatever number X, Y and Z was, you could be sure that it was
unrelated to the line the semicolon was missing in.&lt;/p&gt;
&lt;p&gt;JSLint was an improvement. At least you could have some kind of feedback on
your code before going into a frustration loop with IE. Mostly JSLint would
tell you all the things that would trip up a browser and fixing its warnings
could get you that far already.&lt;/p&gt;
&lt;p&gt;CoffeeScript takes this one step further. Since its output passes JSLint
without warnings, its like that red sports car &amp;#8211; faster &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;AND&lt;/span&gt;&lt;/strong&gt; cooler. My 
experience with it says that when coffee compiles it, it probably runs. And
since there is less noise to it, its easier to get right. No fiddling with
bits of syntax, just writing code.&lt;/p&gt;
&lt;h2&gt;Plays well with others&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Exhibit A&lt;/strong&gt;: A piece of &lt;a href=&quot;http://haml-lang.com/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;HAML&lt;/span&gt;&lt;/a&gt; code:&lt;/p&gt;
&lt;pre class=&quot;sh_haml&quot;&gt;&lt;code&gt;
  .part
    .name John Doe
    .address Infinity Drive
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Exhibit B&lt;/strong&gt;: &lt;a href=&quot;http://sass-lang.com/&quot;&gt;Sass&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;sh_sass&quot;&gt;&lt;code&gt;
  .part
    color: #fff
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And &lt;strong&gt;finally&lt;/strong&gt; (maybe in that same &lt;span class=&quot;caps&quot;&gt;HAML&lt;/span&gt; file, thanks to &lt;a href=&quot;http://github.com/inem/coffee-haml-filter&quot;&gt;coffee-haml-filter&lt;/a&gt;):&lt;/p&gt;
&lt;pre class=&quot;sh_haml&quot;&gt;&lt;code&gt;
  :coffee
    $('.name').each(-&amp;gt;
      alert(this.text()))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;My ruby liking soul is only slightly worried by the importance of indentation
in these languages. Putting that aside, I can really enjoy all of them.
(And no, don&amp;#8217;t write all of your CoffeeScript inline with your haml!)&lt;/p&gt;
&lt;h2&gt;The Result&lt;/h2&gt;
&lt;p&gt;After several attempts, I have been able to complete a rewrite. The resulting
code will now be used in the application I am building. You can look at it
here:
&lt;a href=&quot;http://github.com/kschiess/jquery.objectlist&quot;&gt;kschiess/jquery.objectlist&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The code I have written reads like a cross between Ruby, Smalltalk and Scheme.
The methods have become really short, and some of the data is hidden as
lambdas in hooks. CoffeeScript will allow to do all of this: Writing clean OO
code, writing functional style and just writing idiomatic .. Javascript.&lt;/p&gt;
&lt;p&gt;Writing this has felt good and really really funky. I have focused on the 
usability of the language in these notes, but I urge you to look at the 
&lt;a href=&quot;http://jashkenas.github.com/coffee-script/&quot;&gt;introduction&lt;/a&gt;. CoffeeScript has&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;list comprehension&lt;/li&gt;
	&lt;li&gt;terse lambda syntax, with or without this binding&lt;/li&gt;
	&lt;li&gt;pattern matching&lt;/li&gt;
	&lt;li&gt;heck, even a small rake replacement!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Do check it out!&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="javascript" label="javascript" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="coffeescript" label="coffeescript" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="jquery" label="jquery" />
   
 </entry>
 
 <entry>
   <title>The Ruby Object Hierarchy</title>
   <link href="http://blog.absurd.li/2010/02/17/ruby_object_hierarchy.html"/>
   <updated>2010-02-17T00:00:00+01:00</updated>
   <id>http://blog.absurd.li/2010/02/17/ruby_object_hierarchy</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://banisterfiend.wordpress.com/2008/11/25/a-complete-ruby-class-diagram/&quot;&gt;Every&lt;/a&gt;
&lt;a href=&quot;http://eigenclass.org/hiki/class+hierarchy+introspection+evil.rb&quot;&gt;self&lt;/a&gt;
&lt;a href=&quot;http://objectgraph.rubyforge.org/&quot;&gt;respecting&lt;/a&gt;
&lt;a href=&quot;http://www.insula.cz/dali/material/rubycl/&quot;&gt;ruby&lt;/a&gt;
&lt;a href=&quot;http://www.brpreiss.com/books/opus8/html/page113.html&quot;&gt;programmer&lt;/a&gt;
has one of these on his blog. Join the 
club.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/img/2010-02-17/ruby_object_hierarchy.pdf&quot;&gt;&lt;img src=&quot;/img/2010-02-17/ruby_object_hierarchy.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(Click for a pdf of this. Filled triangles are &lt;em&gt;class&lt;/em&gt; relationships, empty
triangles are &lt;em&gt;super&lt;/em&gt; relationships, funky diamonds are funky &lt;em&gt;metaclass&lt;/em&gt; relationships, thanks _why!)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/samples/2010-02-17/ruby_object_hierarchy.zip&quot;&gt;Here&lt;/a&gt; is the source code for this. A few notes on the code:&lt;/p&gt;
&lt;p&gt;The code also graphs the &amp;#8216;&lt;strong&gt;actual class&lt;/strong&gt;&amp;#8217; as reported
&lt;a href=&quot;http://banisterfiend.wordpress.com/2008/10/25/the-secret-life-of-singletons/&quot;&gt;here&lt;/a&gt;.
I didn&amp;#8217;t see the use of that, so it&amp;#8217;s gone from the version displayed here.&lt;/p&gt;
&lt;p&gt;This is probably the most &lt;strong&gt;shoddy piece&lt;/strong&gt; of code I&amp;#8217;ve ever released. Note to
self: Breathe out, relax. It doesn&amp;#8217;t actually hurt.&lt;/p&gt;
&lt;p&gt;If you want to run this yourself, call it like this:&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
  $ ruby extconf.rb &amp;amp;&amp;amp; make
  (... snippage ...)
  $ ruby graph.rb RECURSION_DEPTH &amp;gt; mygraph.dot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The code does depth first graph traversal over Ruby&amp;#8217;s object graph and outputs
a &lt;a href=&quot;http://www.graphviz.org/&quot;&gt;graphviz&lt;/a&gt; dot file. It seems that while recursion depths bigger than
3 are sure funky, they don&amp;#8217;t add much to the picture.&lt;/p&gt;
&lt;p&gt;A few things that are interesting in the above graph (trying not to be
redundant with others):&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;There are really a lot more metaclasses than you think. They might gather in
  groups and descend upon you in your sleep, even. You think turtles is bad?
  Metaclasses is way badder.&lt;/li&gt;
	&lt;li&gt;Class really ties the room together. Without it, Ruby would really be off
  balance. I guess that&amp;#8217;s why its called &lt;em&gt;class oriented programming&lt;/em&gt;.&lt;/li&gt;
	&lt;li&gt;Everything is created out of nothing. It fits with my belief system to have
  &lt;code&gt;nil&lt;/code&gt; sit on the top of that diagram.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Happy hacking!&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="internals" label="internals" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="graphviz" label="graphviz" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="humor" label="humor" />
   
 </entry>
 
 <entry>
   <title>toamqp 0.3.1 released</title>
   <link href="http://blog.absurd.li/2010/02/09/toamqp_0_3-1_released.html"/>
   <updated>2010-02-09T00:00:00+01:00</updated>
   <id>http://blog.absurd.li/2010/02/09/toamqp_0_3-1_released</id>
   <content type="html">&lt;p&gt;Just a quick note to let you know that I am releasing
&lt;a href=&quot;http://github.com/kschiess/toamqp&quot;&gt;toamqp&lt;/a&gt; today. I&amp;#8217;ve already presented
all the &lt;a href=&quot;/2010/01/26/the_new_thrift_over_amqp_explained.html&quot;&gt;novelties&lt;/a&gt; in 
this place, now its time to get the code some action.&lt;/p&gt;
&lt;p&gt;This release includes many bugfixes and code cleanups. It also features
a &lt;code&gt;TOAMQP::SpecServer&lt;/code&gt; helper class that allows easier testing
of the code. With this testing becomes a breeze &amp;#8211; you set it up like this:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  server = TOAMQP.server(MyHandler.new, TOAMQP::SpecServer)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then you get two options; either you make all the calls and then call&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  server.serve
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will act on all the messages that wait at the broker and then return. 
When you want to satisfy your mock&amp;#8217;s expectations, this is the method to use.&lt;/p&gt;
&lt;p&gt;You can also use&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  server.serve_in_thread
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and then go off and make a bunch of client calls. Just don&amp;#8217;t forget to tear 
down this server thread:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  server.stop_and_join
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will wait for the thread to close down.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Do go off and have fun with this release. And by all means, tell me what
doesn&amp;#8217;t work.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="thrift" label="thrift" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="RPC" label="RPC" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="AMQP" label="AMQP" />
   
 </entry>
 
 <entry>
   <title>The new Thrift / AMQP bridge: Explained</title>
   <link href="http://blog.absurd.li/2010/01/26/the_new_thrift_over_amqp_explained.html"/>
   <updated>2010-01-26T00:00:00+01:00</updated>
   <id>http://blog.absurd.li/2010/01/26/the_new_thrift_over_amqp_explained</id>
   <content type="html">&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;p&gt;Since this has grown into a really long article, Here&amp;#8217;s what its about: I talk about &lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt; using thrift and &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt;. This can be setup in at least two different
ways, one gives you round-robin load balancing, the other allows you to filter
messages. At the end I provide you with a project roadmap and an invitation 
to contribute.&lt;/p&gt;
&lt;h2&gt;thrift_over_amqp becomes toamqp?&lt;/h2&gt;
&lt;p&gt;I have reworked the &lt;code&gt;thrift_over_amqp&lt;/code&gt; plugin into a real gem that
can be used everywhere. To do this, I&amp;#8217;ve rewritten the code and cleaned up the
javaish &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; mess. Must&amp;#8217;ve been the contact stress with thrift APIs. But this
is &lt;a href=&quot;/2010/01/04/redesign_and_rename.html&quot;&gt;old news&lt;/a&gt; already.&lt;/p&gt;
&lt;p&gt;Let me try to give you some new .. well ah .. news. Here&amp;#8217;s a graphic list of 
operation modes for thrift calls when sent via an &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt; broker:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/2010-01-26/toamqp_layouts.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://incubator.apache.org/thrift/&quot;&gt;Thrift&lt;/a&gt; itself provides you just with the
same old point to point procedure call (first schema). Where do the other
combinations come from?, you ask. Those are pretty much what &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt; does for
you. Using toamqp, you can take advantage of these other operation modes for
&lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt; calls.&lt;/p&gt;
&lt;p&gt;To say it with the words of the king – A little less conversation, a little
more action please:&lt;/p&gt;
&lt;h2&gt;One to One example&lt;/h2&gt;
&lt;p&gt;About the simplest thing you can do with &lt;code&gt;toamqp&lt;/code&gt; is to connect
two points of your infrastructure via &lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt;. To do this, you need to write a 
thrift specification of the receiver:&lt;/p&gt;
&lt;pre class=&quot;sh_thrift&quot;&gt;&lt;code&gt;
  service receiver {
    /**
     * Let's say we have a search server somewhere, answering with a list
     * of search results to us:
     */
     list&amp;lt;string&amp;gt; search(1: string word)
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is better than the usual &lt;code&gt;getTime&lt;/code&gt; &lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt; call, since we &amp;#8216;&lt;em&gt;now
what time it is&lt;/em&gt;&amp;#8217;, right? As you can see, thrift has a rich set of types that
can be sent over the wire. You can create new types yourself and even do 
exception handling.&lt;/p&gt;
&lt;p&gt;You may be wondering what the &amp;#8216;&lt;code&gt;1: &lt;/code&gt;&amp;#8217; is about in the list of
arguments of our function. That is thrift&amp;#8217;s micro-level versioning. You give
all your parameters a unique id and have to make sure you only use that id
when you&amp;#8217;re talking about the exact same thing. I can rename
&amp;#8216;&lt;code&gt;word&lt;/code&gt;&amp;#8217;, as long as I use the same id; I can also introduce new
parameters unilaterally and be assured that only receivers who have use for
them will receive them.&lt;/p&gt;
&lt;h3&gt;Turning the specification in some code&lt;/h3&gt;
&lt;p&gt;You can now use thrift to generate Ruby code from that. This generally looks
like this:&lt;/p&gt;
&lt;pre class=&quot;sh_bash&quot;&gt;&lt;code&gt;
  &amp;gt; thrift --gen rb receiver.thrift
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This only works if you install the whole
&lt;a href=&quot;http://incubator.apache.org/thrift/&quot;&gt;thrift&lt;/a&gt; suite, not just the rubygem.
Doing so will give you the compiler for the thrift &lt;span class=&quot;caps&quot;&gt;IDL&lt;/span&gt;. I may someday include
a new rake task generator into toamqp for making this step real easy. For now
you are stuck with the command line.&lt;/p&gt;
&lt;p&gt;You most likely get a &amp;#8216;&lt;code&gt;gen-rb&lt;/code&gt;&amp;#8217; subdirectory that contains three
ruby files. We&amp;#8217;re now just one step away from writing our sender/receiver
pair. For the request sender (aka client), we write:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  require 'toamqp'    # requires thrift and bunny
  require 'gen-rb/receiver.rb'

  sender = TOAMQP.client('receiver', Receiver)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first argument to &lt;code&gt;.client&lt;/code&gt; is the name of the exchange that 
you want to use for all messages. Sender and receiver must use the same name
here. Think of it as the &lt;em&gt;address&lt;/em&gt; of the receiver.&lt;/p&gt;
&lt;p&gt;The second argument is the module that contains all thrift generated classes.
&lt;span class=&quot;caps&quot;&gt;TOAMQP&lt;/span&gt; will dynamically look up the &amp;#8216;&lt;code&gt;Client&lt;/code&gt;&amp;#8217; class from that 
module and return you an instance of that client, connected to your queue
server. Speaking of which: You can configure the connection attributes using
the longish method &lt;code&gt;#connection_attributes=&lt;/code&gt; on the connection 
manager:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  TOAMQP.connection_manager.connection_attributes = {
    :user =&amp;gt; 'username', 
    :password =&amp;gt; 'password', 
    :host =&amp;gt; 'myqueue.mydomain.com'
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The default is a connect to localhost.&lt;/p&gt;
&lt;h3&gt;Server implementation&lt;/h3&gt;
&lt;p&gt;Thrift makes it easy to write a receiver for our service (a simple one at
least):&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  require 'toamqp'
  require 'gen-rb/receiver.rb'
  
  class ReceiverHandler &amp;lt; TOAMQP::Service::Base
    exchange 'receiver'   # same as we used above
    serves Receiver
    
    def search(query)
      # search implementation with proper exception handling
      return %w{a few search results}
    end
  end
  
  TOAMQP.server(ReceiverHandler.new).   # create the server
    serve                               # enter its main loop
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will create thrift server instance and call its &lt;code&gt;#serve&lt;/code&gt; method that will singlethreadedly (is that a word?) serve requests from the
sender. So doing&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  sender.search('chunky bacon')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;will return .. no chunky bacon
&lt;a href=&quot;http://ejohn.org/blog/eulogy-to-_why/&quot;&gt;anymore&lt;/a&gt;, think about the serialization
issues, but a ruby array of your search results. This is all thanks to thrift
- all that toamqp does at this point is connect the thrift endpoints through
your message queue.&lt;/p&gt;
&lt;p&gt;I have chosen to make the handler implementation lean towards
ActiveRecord-style class declarations. This has some disadvantages: You really
have to decide what you&amp;#8217;re going to serve and how the exchange is going to be
named, for all instances of the class. On the plus side, you are free to
meddle with your own constructor – and you don&amp;#8217;t have to call
&lt;code&gt;super&lt;/code&gt;, something I always seem to forget.&lt;/p&gt;
&lt;p&gt;Note that there is a second argument to &lt;code&gt;#server&lt;/code&gt; that allows you
to specify which server class to instantiate. You can plug one of the evented
or threaded servers that come with thrift in there, although I must admit that
my tests are cruelly lacking in that area. Speaking of tests: toamqp also
comes with a server called &amp;#8216;&lt;code&gt;TOAMQP::SpecServer&lt;/code&gt;&amp;#8217; that can help you
write integration tests against the whole infrastructure. You should really
read the specs in the &amp;#8216;&lt;code&gt;spec/integration&lt;/code&gt;&amp;#8217; subdirectory of toamqp
to get an example of usage for that.&lt;/p&gt;
&lt;h2&gt;Extending to round robin load balancing&lt;/h2&gt;
&lt;p&gt;This is all very plain thrift stuff &amp;#8211; nothing you could not also achieve with
tcp transports. Let&amp;#8217;s take advantage of your message broker (your queue) a
little more. One of the things that a broker does as per specification is
round-robin balancing of message receivers.&lt;/p&gt;
&lt;p&gt;If we connect more than one receiver to the exact same exchange (a
simplification of issues here, more down below), they will each get 50% (in
the discret sense of the term, not the quantum mechanic sense) of the load.
It&amp;#8217;s really as simple as that, just run two servers. And nothing stops you
from running 10, on different machines. Let me give you a small example of a
forking server that starts more than one server process on one machine:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  $pids = []
  2.times do 
    $pids &amp;lt;&amp;lt; fork { TOAMQP.server(ReceiverHandler.new).serve }
  end
  
  Signal.trap(&quot;CHLD&quot;) {
    Process.wait; 
    $pids.delete($?.pid)
  }
  
  sleep 1 until $pids.empty?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Of course, this is a brutal oversimplification of the issues &lt;a href=&quot;/2009/11/18/some_tricks_to_learn_from_unicorn.html&quot;&gt;involved&lt;/a&gt;. You might want to look at the threaded server that comes with thrift or/and at unicorn, a forking web server for more information about 
this.&lt;/p&gt;
&lt;p&gt;One small warning at this point: Thrift itself is not thread safe, and neither
is toamqp. You cannot just spawn a few Ruby threads and use the client in all
of them; you might have to create one client object per thread. And you should
really look at the servers that come with thrift, they solve many of the
issues with threading you might have.&lt;/p&gt;
&lt;p&gt;So road-robin balancing and load distribution over several machines is done, 
what is next?&lt;/p&gt;
&lt;h2&gt;Routing messages to the right server&lt;/h2&gt;
&lt;p&gt;Sometimes you don&amp;#8217;t just have many servers of the &lt;em&gt;same kind&lt;/em&gt;, but many
servers with the same interface of &lt;em&gt;different kind&lt;/em&gt;. toamqp supports this
directly.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s say you have two places to search for, your desk and your wastebasket. (Since we all know that important documents are stored there, right?) So ideally, you would want to search them both:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  desk        = TOAMQP.client('receiver', Receiver, { :location =&amp;gt; :desk })
  wastebasket = TOAMQP.client('receiver', Receiver, { :location =&amp;gt; :wastebasket })
  
  [desk, wastebasket].map { |sender| sender.search('important document') }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will fail brutally after experimenting with the code above. The reason is
that for this to work, you will need to redeclare the &amp;#8216;receiver&amp;#8217; exchange on
your broker to be of a different type. Before, it was &lt;em&gt;direct&lt;/em&gt; (as in &amp;#8216;send my
messages &lt;em&gt;directly&lt;/em&gt; to the receiver&amp;#8217;), now it should be &lt;em&gt;headers&lt;/em&gt; (as in
&amp;#8216;&lt;em&gt;filter by the headers&lt;/em&gt; I send&amp;#8217;). Luckily toamqp does this for you, provided
you clear the old variant from your servers first. You can either do this by
restarting your server or by manually issuing a delete call via &amp;#8216;bunny&amp;#8217;.&lt;/p&gt;
&lt;p&gt;For really easy experimentation you should just change the exchange name to 
&amp;#8216;receiver_filtered&amp;#8217;. This way toamqp will declare a new exchange and your 
&lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt; broker will not throw an error.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ll just show you how to implement a wastebasket receiver; the desk receiver
should follow from that. Note that since they implement the &lt;em&gt;same&lt;/em&gt; interface 
but have &lt;em&gt;different&lt;/em&gt; implementations, you will really need two different classes:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  class Wastebasket &amp;lt; TOAMQP::Service::Base
    exchange 'receiver', match =&amp;gt; { :location =&amp;gt; :wastebasket }
    serves Receiver
    
    def search(query)
      # ...
    end
  end
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Combining the layouts&lt;/h3&gt;
&lt;p&gt;These two layouts (Round-Robin Load Balancing and Header Routing) can of
course be combined. Together these two will help with most if not all
communication needs you might have.&lt;/p&gt;
&lt;h2&gt;Possible extensions, Status, Roadmap&lt;/h2&gt;
&lt;p&gt;The current released version of the library is 0.3.0. You should not be using
that, however. If you really want to help me, please check out the repository
from &lt;a href=&quot;http://github.com/kschiess/toamqp&quot;&gt;my github account&lt;/a&gt; and use the 
&lt;a href=&quot;http://github.com/kschiess/toamqp/tree/0.3.1-rc-a&quot;&gt;0.3.1-rc-*&lt;/a&gt; branch. This 
will give you the latest fixes and help me discover issues with the 0.3.1 
release. Mind you, there should not be too many now &amp;#8211; I am using this code
in production and have encountered but few surprises.&lt;/p&gt;
&lt;p&gt;In about two weeks time, I will be releasing 0.3.1. This marks the end of the big rewrite. Once that is done, I would like to start working towards at 
least partial compatibility with &lt;a href=&quot;https://launchpad.net/txamqp&quot;&gt;txAMQP&lt;/a&gt; for 0.3.2.&lt;/p&gt;
&lt;p&gt;Of course, many things are left to be done. Here&amp;#8217;s my current wishlist:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;A specialized rake task for building thrift files (I have something
  semi-finished laying around)&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;Wrap the client proxy object in a thread safe way. This could lead to a 
  generic thread-safe-o-matic for client proxies.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;Do some real testing with multithreaded server. Find the issues and the
  solutions.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;Broadcasting to many receivers? Easy to do and would enhance the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; 
  for announcing presence, sending heartbeats, etc&amp;#8230;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please get in contact if any questions remain (almost impossible, if you read
my drivel until here, you must be the expert by now). I welcome all
contributions that are accompanied by specs.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="thrift" label="thrift" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="amqp" label="amqp" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="toamqp" label="toamqp" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="rpc" label="rpc" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="thrift_over_amqp" label="thrift_over_amqp" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="round robin" label="round robin" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="load balancing" label="load balancing" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="filter" label="filter" />
   
 </entry>
 
 <entry>
   <title>Using rake as a component</title>
   <link href="http://blog.absurd.li/2010/01/14/using_rake_as_a_component.html"/>
   <updated>2010-01-14T00:00:00+01:00</updated>
   <id>http://blog.absurd.li/2010/01/14/using_rake_as_a_component</id>
   <content type="html">&lt;p&gt;Rake is a useful beast. As one of the most mature ruby projects it makes my
life better by allowing me to forget everything I ever knew about
&lt;code&gt;make&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Embedded Rake&lt;/h2&gt;
&lt;p&gt;I would like to show here how you can use rake as a library, not as a tool.
The following piece of code shows how you can declare tasks in your own Ruby
classes:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  require 'rake'
  class RocketScience
    include Rake::TaskManager
    def task(*args, &amp;amp;block)
      define_task(Rake::Task, *args, &amp;amp;block)
    end

    def init
      task :build_rocket do
        p :build_rocket # rocket building here
      end

      task :launch_rocket =&amp;gt; :build_rocket do
        p :launch_rocket # launching here - only works if you build it first
      end
      self
    end
  end
  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;Rake::TaskManager&lt;/code&gt; mixin retrofits task management to any of
your classes. It defines a few methods that allow creation, invocation and
management of your own tasks. The example uses &lt;code&gt;#define_task&lt;/code&gt; to
add tasks to the current instance of &lt;code&gt;RocketScience&lt;/code&gt;. You can find
the default definitions for &lt;code&gt;#task&lt;/code&gt;, &lt;code&gt;#file&lt;/code&gt; and the
whole &lt;code&gt;TaskManager&lt;/code&gt; mixin in rake.rb in rake&amp;#8217;s source code at the
top level.&lt;/p&gt;
&lt;p&gt;Now the above example doesn&amp;#8217;t do much yet. To show that rake is really useful
for your code, here&amp;#8217;s how to print something:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  class RocketScience   # reopen the class
    def run
      self[:launch_rocket].invoke
    end

    def options
      options = OpenStruct.new
      options.trace = false
      options.dryrun = false
      options
    end
  end
  
  RocketScience.new.init.run
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We need to provide rake with an options method that defines some of the 
runtime options you can set in the command line tool as well. The above 
example will print&lt;/p&gt;
&lt;pre&gt;
  :build_rocket
  :launch_rocket
&lt;/pre&gt;
&lt;p&gt;A whole lot, isn&amp;#8217;t it?&lt;/p&gt;
&lt;p&gt;Now you will say that embedding rake like this is a complicated way of 
doing the following:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  require 'rake'
  
  task :build_rocket do
    p :build_rocket # rocket building here
  end

  task :launch_rocket =&amp;gt; :build_rocket do
    p :launch_rocket # launching here - only works if you build it first
  end
  
  Rake::Task[:launch_rocket].invoke
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You would be right. The only thing the first example buys you is that your 
rake namespace is not a singleton anymore, you can actually have multiple 
tasks with the same name in different instances of &lt;code&gt;RocketScience&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Remote Rake&lt;/h2&gt;
&lt;p&gt;One last rake trick before you can go out to play: I recently discovered an
heavily underdocumented feature in
&lt;a href=&quot;http://rubyhitsquad.com/Vlad_the_Deployer.html&quot;&gt;vlad&lt;/a&gt; the deployer: remote 
rake tasks from within rake. Perhaps this is underdocumented because it is
so stupidly obvious to everyone (but me!), but I think it is definitly worth
the mention:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  require 'rake'
  require 'rake_remote_task'

  role :server, 'server1'
  role :server, 'server2'

  remote_task :ls, :roles =&amp;gt; :server do 
    run 'ls'
  end

  Rake::Task[:ls].invoke
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above example shows how you can execute &amp;#8216;&lt;code&gt;ls&lt;/code&gt;&amp;#8217; on multiple
remote servers. You first define your servers as being part of a role, using
either the &lt;code&gt;role&lt;/code&gt; keyword (as above) or the &lt;code&gt;host&lt;/code&gt;
keyword:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  host 'multiple-purpose-host', :db, :application
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then you write remote rake tasks against these roles as shown. Note that the
example uses the &amp;#8216;rake-on-a-stick&amp;#8217; technique I&amp;#8217;ve shown above and could well
be integrated with everything said above. Of course, you could make it a
vanilla &lt;code&gt;Rakefile&lt;/code&gt; as well.&lt;/p&gt;
&lt;p&gt;Since vlad is capistrano built on rake, it should be clear that vlad contains
this feature. But I think this is useful for all uses of rake, not just
deployments. Using this you can write &lt;code&gt;Rakefile&lt;/code&gt;s that execute on
multiple servers &lt;span class=&quot;caps&quot;&gt;AND&lt;/span&gt; locally at once. Serious coolness. Goodbye Capistrano,
welcome to our new russian overlords.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="rake" label="rake" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="capistrano" label="capistrano" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="vlad" label="vlad" />
   
 </entry>
 
 <entry>
   <title>A redesign and a rename in 2010</title>
   <link href="http://blog.absurd.li/2010/01/04/redesign_and_rename.html"/>
   <updated>2010-01-04T00:00:00+01:00</updated>
   <id>http://blog.absurd.li/2010/01/04/redesign_and_rename</id>
   <content type="html">&lt;p&gt;For those of you following the thrift_over_amqp_transport plugin: I have just
finished a complete rewrite. The &amp;#8216;plugin&amp;#8217; is now called &amp;#8216;toamqp&amp;#8217; and is
available through rubygems:&lt;/p&gt;
&lt;pre class=&quot;sh_sh&quot;&gt;&lt;code&gt;
  $ gem install toamqp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The version that is currently published has some minor bugs. I will publish
another version real soon now (0.3.1) that fixes those and then some.&lt;/p&gt;
&lt;h2&gt;The redesign&lt;/h2&gt;
&lt;p&gt;Starting with the new version it is now really easy to create server and client
for a &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt; service. Really, its just a few lines:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  # A real small server: 
  class MyServiceImplementation &amp;lt; TOAMQP::Service::Base
    serves ThriftServiceModule
    exchange :my_service
    
    # Service methods go here
  end
  
  TOAMQP.server(MyServiceImplementation.new).serve
&lt;/code&gt;&lt;/pre&gt;

&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  # A real small (smaller!) client
  client = TOAMQP.client(:my_service, ThriftServiceModule)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please have a look at the &lt;span class=&quot;caps&quot;&gt;README&lt;/span&gt; in the
&lt;a href=&quot;http://github.com/kschiess/toamqp&quot;&gt;source&lt;/a&gt;. I&amp;#8217;ve also included a few samples
in the &amp;#8216;&lt;code&gt;examples&lt;/code&gt;&amp;#8217; subdirectory of the project – this should get
you running in no time.&lt;/p&gt;
&lt;p&gt;I will publish a real &lt;span class=&quot;caps&quot;&gt;HOWTO&lt;/span&gt; for a few sample use cases here soon.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="thrift" label="thrift" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="AMQP" label="AMQP" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="toamqp" label="toamqp" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="open source" label="open source" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="design" label="design" />
   
 </entry>
 
 <entry>
   <title>OpenID explained (while cooking chicken soup)</title>
   <link href="http://blog.absurd.li/2009/11/29/openid_explained_while_cooking_chicken_soup.html"/>
   <updated>2009-11-29T00:00:00+01:00</updated>
   <id>http://blog.absurd.li/2009/11/29/openid_explained_while_cooking_chicken_soup</id>
   <content type="html">&lt;p&gt;I am going to explain OpenID in just the time it takes to cook a chicken soup.
Those two hours will allow me to write just the really simple explanation I
have been looking for on the internets recently. My throwing in some Ruby code
and some diagrams will allow you to hopefully create an OpenID consumer with
some trust in what you are doing and in less time than it took me.&lt;/p&gt;
&lt;h2&gt;OpenID? What is that?&lt;/h2&gt;
&lt;p&gt;OpenID will allow you to use multiple sites with just one login. Follow this
&lt;a href=&quot;http://openid.net/&quot;&gt;link&lt;/a&gt; to get to know more on the topic. I am going to
assume you&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;know what OpenID is (from a users perspective) and&lt;/li&gt;
	&lt;li&gt;you already have one.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;How does it work?&lt;/h2&gt;
&lt;p&gt;Keep in mind that we&amp;#8217;re running against the clock here and bear with me while
I insult your user with the following diagram:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://dd.dynamicdiagrams.com/2009/03/visualization-a-la-dilbert/&quot;&gt;&lt;img src=&quot;/img/2009-11-29/openid_sequence.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Authenticating your user in 4 easy steps:&lt;/p&gt;
&lt;p&gt;1. Your user gives you an OpenID, claiming it&amp;#8217;s his.&lt;/p&gt;
&lt;p&gt;2. You perform discovery on the OpenID. You find out that in reality, &amp;#8216;the OpenID provider&amp;#8217; will answer questions about &amp;#8216;the users OpenID&amp;#8217;.&lt;/p&gt;
&lt;p&gt;3. So you redirect your user to his OpenID provider. You pass along data that
will help ask the question: &amp;#8220;Is this guy who he says he is?&amp;#8221;&lt;/p&gt;
&lt;p&gt;4. You don&amp;#8217;t care about how your user identifies to his service. All you care
about is that you get your user redirected back to you and that this special 
redirect carries data proving the users association with the OpenID he gave.&lt;/p&gt;
&lt;h1&gt;And in Practice&lt;/h1&gt;
&lt;p&gt;You should install &lt;a href=&quot;http://openidenabled.com/ruby-openid/&quot;&gt;ruby-openid&lt;/a&gt; (&lt;code&gt;gem install ruby-openid&lt;/code&gt;). Imaging that you have a form that
POSTs the users OpenID as &amp;#8216;&lt;code&gt;:openid&lt;/code&gt;&amp;#8217;. Steps 2 &amp;amp; 3 above would 
look like this:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  def start
    # Did the user fill in the field? (maybe step 1 failed)
    render 'form' and return unless params[:openid]
  
    # Perform discovery (step 2)
    openid_request = openid.begin(params[:openid])
    
    return_to = url_for :action =&amp;gt; :complete, :only_path =&amp;gt; false
    realm     = root_url

    # Send the user to his provider (step 3)
    redirect_to openid_request.redirect_url(realm, return_to)
    
  rescue OpenID::OpenIDError
    # Step 2 (Discovery) failed
    render 'form'
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Please keep in mind that this is a really stripped down no-nonsense version
of the code that only serves to illustrate the concept simply. I&amp;#8217;ll point
you to correct (and more complex) code later.&lt;/p&gt;
&lt;p&gt;As you can see we redirect the user to an &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; that comes straight out of the 
discovery process. We pass along a realm and a &lt;code&gt;return_to&lt;/code&gt;-url, so
that when the user has finished talking to his provider, he will come back and
call our &lt;code&gt;#complete&lt;/code&gt; action.&lt;/p&gt;
&lt;p&gt;I am obviously skipping over a lot of detail, including but not limiting
myself to where you get the &lt;code&gt;'openid'&lt;/code&gt; instance from. Now there&amp;#8217;s
something uninteresting I don&amp;#8217;t want to talk about! As I said, all the useful
stuff will be in the end- and footnotes, as usual&lt;sup class=&quot;footnote&quot; id=&quot;fnr1&quot;&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Back to our main narrative: The user finishes authenticating with his OpenID
provider and comes back to &lt;code&gt;return_to&lt;/code&gt; – meaning our
&lt;code&gt;#complete&lt;/code&gt; action:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  def complete
    this_url          = url_for :action =&amp;gt; 'complete', :only_path =&amp;gt; false
    this_urls_params  = request.query_parameters
    
    # Verify the OpenID security answer with what we think it should be (step 4)
    openid_response = openid.complete(this_urls_params, this_url)
    
    if openid_response.status == OpenID::Consumer::SUCCESS
      # All right: The guy is who he says he is.
    else
      # Nope.
    end
  end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We pass the &lt;code&gt;#complete&lt;/code&gt; method the url we&amp;#8217;re supposed to be at and
the query parameters the way Rails sees them before mixing in
&amp;#8216;&lt;code&gt;:action&lt;/code&gt;&amp;#8217; and &amp;#8216;&lt;code&gt;:controller&lt;/code&gt;&amp;#8217;. This will call back to
the OpenID provider once more to check if everything is as it should be.&lt;/p&gt;
&lt;p&gt;Once verification of query parameters, of cryptographic hashes and subliminal
messages succeeds &amp;#8211; we can let the user in. Note that verifying an OpenID is
like verifying an email address. We don&amp;#8217;t know anything about the users
identity yet, only about his association to the OpenID. It turns out that this
is often enough. This is standard practice with email after all.&lt;/p&gt;
&lt;h2&gt;More information&lt;/h2&gt;
&lt;p&gt;can be found in the sample Rails application provided in the
&lt;code&gt;examples&lt;/code&gt; subdirectory of the &lt;code&gt;ruby-openid&lt;/code&gt; gem. Have a
look at the
&lt;a href=&quot;http://github.com/aslakhellesoy/ruby-openid/blob/master/examples/rails_openid/app/controllers/consumer_controller.rb&quot;&gt;Consumers&lt;/a&gt;
Controller. Some of that code really is more complex than it needs to be –
keep in mind that it just handles a lot of cases in the same bit of code. Most
applications wont need to copy that complexity.&lt;/p&gt;
&lt;p&gt;The code of &lt;code&gt;ruby-openid&lt;/code&gt; is also &lt;a href=&quot;http://github.com/aslakhellesoy/ruby-openid/tree/master/lib/&quot;&gt;well
annotated&lt;/a&gt;. It
reads a bit like the Python it is ported from, but apart from that is really
ok. Go have a look!&lt;/p&gt;
&lt;h2&gt;In parting&lt;/h2&gt;
&lt;p&gt;a few last words: I hope to have simplified OpenID and the use of
&amp;#8216;ruby-openid&amp;#8217;. I would be interested to hear your comments and thoughts -
leave them below. Also. And most importantly. If you have any really good
&lt;strong&gt;recipe for chicken soup&lt;/strong&gt;, I&amp;#8217;d be most happy to borrow it from you.&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;footnote&quot; id=&quot;fnr1&quot;&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; The &lt;code&gt;#openid&lt;/code&gt; method should be implemented about the same way
the &lt;code&gt;#consumer&lt;/code&gt; method in the rails example of &lt;code&gt;ruby-openid&lt;/code&gt;
is.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="OpenID" label="OpenID" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="Cooking" label="Cooking" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="reading code" label="reading code" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="rails" label="rails" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
 </entry>
 
 <entry>
   <title>Some tricks that can be learnt from the unicorn</title>
   <link href="http://blog.absurd.li/2009/11/18/some_tricks_to_learn_from_unicorn.html"/>
   <updated>2009-11-18T00:00:00+01:00</updated>
   <id>http://blog.absurd.li/2009/11/18/some_tricks_to_learn_from_unicorn</id>
   <content type="html">&lt;p&gt;My general disgust with threaded/evented programming has led me to read up on
the good old unix techniques used in &lt;a href=&quot;http://unicorn.bogomips.org/&quot;&gt;unicorn&lt;/a&gt;.
What a good read it was. The mix of programmers that have constructed unicorns
have very different styles. That makes reading fun. I guess anyone could
distinguish Zed Shaw&amp;#8217;s style from the rest of the pack&amp;#8230;&lt;/p&gt;
&lt;p&gt;But there are also some unix techniques that I&amp;#8217;ve learnt from unicorn and that
I will share with you now&lt;sup class=&quot;footnote&quot; id=&quot;fnr1&quot;&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h2&gt;The Self Pipe Trick&lt;/h2&gt;
&lt;p&gt;This trick allows you to handle signals safely in your code. A nice side-effect
is that it will also allow you to trigger running of a process without using 
signalling.&lt;/p&gt;
&lt;p&gt;Assume you have two processes, A and B. One process wants 
to be able to signal the other, awaking it from sleep. Lets assume that
they share a FD to a pipe, where &lt;code&gt;read_end&lt;/code&gt; is the end of the pipe 
that is open for reading and &lt;code&gt;write_end&lt;/code&gt; the one open for writing to.&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  # Process A: Sleep and wait for a signal: 
  IO.select([read_end])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code snippet is used to put the process A to sleep, waiting for a
signal&lt;sup class=&quot;footnote&quot; id=&quot;fnr1&quot;&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. You would then use the following technique to wake the process up:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  # Process B: Awake process A
  write_end.write_nonblock('.')   # the '.' is arbitrary
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Process A wakes up because you&amp;#8217;ve just written something to the FD that its 
waiting on&lt;sup class=&quot;footnote&quot; id=&quot;fnr3&quot;&gt;&lt;a href=&quot;#fn3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Note that this technique can also be used to wake process A up from a signal
handler. So you get safe &lt;span class=&quot;caps&quot;&gt;IPC&lt;/span&gt; in just a few lines.&lt;/p&gt;
&lt;p&gt;This trick seems to be &lt;a href=&quot;http://osiris.978.org/~alex/safesignalhandling.html&quot;&gt;well&lt;/a&gt;
known in the unix world, there are even some alternatives (read that link).&lt;/p&gt;
&lt;h2&gt;Keepalive through an unlinked file&lt;/h2&gt;
&lt;p&gt;Another thing that I found most enlightening is how unicorn handles sending
heartbeats to the controlling process from its workers. This is not as easy 
as it looks, since actively sending heartbeats will require the master to 
listen at the same moment. The solution unicorn uses decouples the master
from the client in that respect.&lt;/p&gt;
&lt;p&gt;The master opens one temporary file per worker and &lt;em&gt;unlinks it right away&lt;/em&gt;&lt;sup class=&quot;footnote&quot; id=&quot;fnr4&quot;&gt;&lt;a href=&quot;#fn4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;.
The open file handle to that file is then shared with all the worker processes.&lt;/p&gt;
&lt;p&gt;Each worker will then do the following to prove its alive and kicking:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  tmpfile.chmod(m = 0 == m ? 1 : 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The chmod will use either &amp;#8216;1&amp;#8217; or &amp;#8216;0&amp;#8217; each time this gets executed.&lt;sup class=&quot;footnote&quot; id=&quot;fnr5&quot;&gt;&lt;a href=&quot;#fn5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; (Assign &amp;#8216;0&amp;#8217;
to the local variable &amp;#8216;m&amp;#8217;, compare it to &amp;#8216;0&amp;#8217;. If it matches (&lt;code&gt;m ==
0&lt;/code&gt;), &lt;code&gt;m = 1&lt;/code&gt;, otherwise &lt;code&gt;m = 0&lt;/code&gt;. A one line
toggle.)&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s what the master does to check the worker&amp;#8217;s status&lt;sup class=&quot;footnote&quot; id=&quot;fnr6&quot;&gt;&lt;a href=&quot;#fn6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  stat = worker.tmpfile.stat
  unless (diff = (Time.now - stat.ctime)) &amp;lt;= timeout
    # Worker has gone stale and needs to be respawned
  end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Even though the file is unlinked it still has metadata associated with it. 
Using the file&amp;#8217;s &lt;code&gt;#ctime&lt;/code&gt; we can check when the file was last mode changed, and
thus when the worker was last alive.&lt;/p&gt;
&lt;p&gt;This nice gem of a technique uses the unix file system as an external data
store. I really like the details that went into this, like the fact that its
unlinked already or the small code hack that is explained in the parentheses
above. I haven&amp;#8217;t been able to find that technique elsewhere, though I am sure
it is part of any bearded unix guru&amp;#8217;s toolbox.&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;footnote&quot; id=&quot;fnr1&quot;&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; All references to unicorn code are made against revision
6311cc30b96b08f72fe00a9a0d1e291cf9923e52 of the repository @
git://git.bogomips.org/unicorn.git.&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;footnote&quot; id=&quot;fnr2&quot;&gt;&lt;a href=&quot;#fn2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; &lt;code&gt;unicorn.rb&lt;/code&gt;, method &lt;code&gt;#master_sleep&lt;/code&gt;, lines 422-429&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;footnote&quot; id=&quot;fnr3&quot;&gt;&lt;a href=&quot;#fn3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; &lt;code&gt;unicorn.rb&lt;/code&gt;, method &lt;code&gt;#awaken_master&lt;/code&gt;, lines 431-438&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;footnote&quot; id=&quot;fnr4&quot;&gt;&lt;a href=&quot;#fn4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; &lt;code&gt;util.rb&lt;/code&gt;, &lt;code&gt;Util.tmpio&lt;/code&gt;, lines 75-86&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;footnote&quot; id=&quot;fnr5&quot;&gt;&lt;a href=&quot;#fn5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; &lt;code&gt;unicorn.rb&lt;/code&gt;, method &lt;code&gt;#worker_loop&lt;/code&gt;, lines 631-639,
be sure to read the interesting comment right above.&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;footnote&quot; id=&quot;fnr6&quot;&gt;&lt;a href=&quot;#fn6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; &lt;code&gt;unicorn.rb&lt;/code&gt;, &lt;code&gt;#murder_lazy_workers&lt;/code&gt;, lines 517-527&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="reading code" label="reading code" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="tricks" label="tricks" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="unix" label="unix" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="unicorn" label="unicorn" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="bearded unix gurus" label="bearded unix gurus" />
   
 </entry>
 
 <entry>
   <title>One-Way RPC using AMQP as transport and THRIFT for communication</title>
   <link href="http://blog.absurd.li/2009/11/05/one_way_rpc_using_amqp_and_thrift.html"/>
   <updated>2009-11-05T00:00:00+01:00</updated>
   <id>http://blog.absurd.li/2009/11/05/one_way_rpc_using_amqp_and_thrift</id>
   <content type="html">&lt;p&gt;In this article I would like to present &amp;#8216;&lt;a href=&quot;http://github.com/kschiess/thrift_amqp_transport&quot;&gt;thrift_amqp_transport&lt;/a&gt;&amp;#8217;, 
a small library I&amp;#8217;ve worked on in the past months. It allows you to do 
one way rpc (method calls) using &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt; as a transport layer. This will decouple
the sender from the receiver completely. I will present some usage examples 
in the second part of this article.&lt;/p&gt;
&lt;p&gt;What is &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt;? Igvita.com has recently featured a nice &lt;a href=&quot;http://www.igvita.com/2009/10/08/advanced-messaging-routing-with-amqp/&quot;&gt;overview
article&lt;/a&gt;
about &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt; and Ruby. &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt; is a protocol for asynchronous messaging/ queuing
over the network.&lt;/p&gt;
&lt;p&gt;Thrift (&lt;a href=&quot;http://www.igvita.com/2007/11/30/ruby-web-services-with-facebooks-thrift/&quot;&gt;also on
igvita.com&lt;/a&gt;)
is an &lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt; framework developed by Facebook (formerly) that got made an Apache
project. It allows you to do cross language/ cross platform method calls. I am
impressed by the clean design that went into this. The intermediary definition
language that is used is surprisingly rich, allows you to aggregate data into
types and to transmit hashes and lists.&lt;/p&gt;
&lt;h2&gt;A very basic example of &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt; usage&lt;/h2&gt;
&lt;p&gt;Your rails application wants to create directories on demand. Using &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt;, you
can queue up new directories to be created like this:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  require 'bunny'

  Bunny.start do |connection|
    work_queue = connection.queue('work')

    work_queue.publish('create_directory foo')
  end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A small sample worker might look like this:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  require 'bunny'

  Bunny.start do |connection|
    work_queue = connection.queue('work')

    work = work_queue.pop

    unless work.payload == :queue_empty
      command, *args = work.payload.split

      # Execute the command 
      case command
        when 'create_directory'
          puts &quot;Create directory #{args.first}&quot;
      end
    else
      puts &quot;No work to do.&quot;
    end
  end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, any non-trivial use will implement some form of &lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt;-mechanism.
(even this trivial example does) As long as you&amp;#8217;re not transmitting only data, 
but want to act on that data, you will implement some kind of dispatch 
mechanism on the other end.&lt;/p&gt;
&lt;h2&gt;&lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt; instead of strings&lt;/h2&gt;
&lt;p&gt;To avoid writing a complex dispatch mechanism, it would probably be wise to
use some kind of &lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt; implementation to reduce complexity at this point. Using
&amp;#8216;&lt;code&gt;thrift_amqp_transport&lt;/code&gt;&amp;#8217;, the above code would look like this:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  require 'thrift_amqp_transport'
  
  # Yes, its more setup code.
  connection = Thrift::AMQP::Connection.start
  transport = connection.client_transport('work_rpc')
  protocol = Thrift::BinaryProtocol.new(transport)
  client = MyService::Client.new(protocol)

  client.createDirectory('foo')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This layers thrift binary messages atop the &amp;#8216;work_rpc&amp;#8217; queue on your &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt;
host. To your &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt; server, this looks like just another message. To receive
work and do something, you would write this code:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  require 'thrift_amqp_transport'
  
  class MyServiceHandler
    def createDirectory(name)
      puts &quot;Creating #{name}&quot;
    end
  end
  
  connection = Thrift::AMQP::Connection.start
  handler = MyServiceHandler.new()
  processor = MyService::Processor.new(handler)
  server_transport = connection.server_transport('work_rpc')

  server = Thrift::SimpleServer.new(processor, transport)
  server.serve    # never returns
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, dispatching has completely gone from the code. You can now
extend the service without rewriting any dispatcher/parser code, using 
thrift&amp;#8217;s rich set of intermediate types in your method calls.&lt;/p&gt;
&lt;p&gt;You might be wondering where all those new classes
(&lt;code&gt;MyService::Processor, MyService::Client, ...&lt;/code&gt;) suddenly come
from. Those are generated by thrift, starting from the service definition,
which would look like this in our case:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
  service MyService {
    oneway void createDirectory(1:string name);
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Some possible past&amp;amp;future uses of this&lt;/h2&gt;
&lt;p&gt;I am using this for queuing up work and acting on it like you can see in the
example above. This is probably more complex (setup-wise) than other solutions, but allows me to restart workers at any time, since the work is 
stored on the queue in a persistent manner.&lt;/p&gt;
&lt;p&gt;But of course, with the power of thrift and &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt; under the 
hood, some other uses become possible:&lt;/p&gt;
&lt;h3&gt;Round Robin Load Balancing&lt;/h3&gt;
&lt;p&gt;The library might offer the possibility to acknowledge a message once the 
work is done. This would allow you to push work on the queue and get some
guarantees that its really becoming acted upon. If a worker pops a work item
and doesn&amp;#8217;t acknowledge it, most &lt;span class=&quot;caps&quot;&gt;AMQP&lt;/span&gt; implementations should redeliver the
work item at one of the next &lt;code&gt;pop&lt;/code&gt;s. (to the next worker)&lt;/p&gt;
&lt;h3&gt;Service Discovery (one to many broadcast)&lt;/h3&gt;
&lt;p&gt;With the current state of the code, you could already have a service broadcast
its presence on the network, updating it with heartbeats.&lt;/p&gt;
&lt;h3&gt;Two-Way Messaging&lt;/h3&gt;
&lt;p&gt;I would be interested in extending this library to allow two-way messaging.&lt;/p&gt;
&lt;h1&gt;Status &amp;amp; Limitations&lt;/h1&gt;
&lt;p&gt;The library is under active development and will be extended in the future. 
Some of the above uses are not yet possible, patches are welcome.&lt;/p&gt;
&lt;p&gt;You can get the source code &lt;a href=&quot;http://github.com/kschiess/thrift_amqp_transport&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="amqp" label="amqp" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="thrift" label="thrift" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="queue" label="queue" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="rpc" label="rpc" />
   
 </entry>
 
 <entry>
   <title>On sharing your models and still keep the database a secret</title>
   <link href="http://blog.absurd.li/2009/10/07/on_sharing_rails_models.html"/>
   <updated>2009-10-07T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2009/10/07/on_sharing_rails_models</id>
   <content type="html">&lt;p&gt;Your rails application is useful to someone. Now he wants to do more, depend
on the data it handles and use it in other parts of his business. The simplest
thing to do would be to give him access to your database and just let him 
have the data, right?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;As it turns out: not really.&lt;/em&gt; While this is a good short term solution, it
will certainly bite you in the long run. Not everyone accessing your data does
so in a way that preserves your invariants and integrity constraints. And even
though I think that &lt;code&gt;ActiveRecord&lt;/code&gt; has found a sweet spot in
specifying business rules you need to realize that it wont tolerate other gods
beside it. Constraints and higher level rules specified in your Ruby code will
only be maintained if you access the data through Ruby code.&lt;/p&gt;
&lt;p&gt;The solution to this is obvious: Don&amp;#8217;t share your database, share your access
layer. Every access to the database has to go through your models. And those
will be the keeper of invariants, the maintainer of .. you get my drift.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s the short list of options you have to go about this:&lt;/p&gt;
&lt;h2&gt;Share model code&lt;/h2&gt;
&lt;p&gt;This is the first idea that you will have and probably not the best. Somehow
bad ideas always come up first.&lt;/p&gt;
&lt;p&gt;Following this idea, you would share your model code between various projects
(using git submodules or the like) and access the database from all projects, 
going through the model code.&lt;/p&gt;
&lt;p&gt;This has a number of downsides:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Your model code will change over time. That generates deployment issues: How
  will you update your projects all at the same time? If you don&amp;#8217;t, you are 
  back at square one.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;Worse: Your database will need to change. But if you do that, all your model
  code (or the part that is not generated anyway) will possibly become invalid. 
  So doing a migration means updating all your code &lt;em&gt;at the same time&lt;/em&gt;. So you
  stop the world and do the update&amp;#8230;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;Another minor issue, if you are doing &lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt;/&lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; 
  &lt;a href=&quot;http://localhost:4000/2009/09/02/i_am_somewhat_of_a_tester.html&quot;&gt;like me&lt;/a&gt;:
  Where do you keep the tests for your model code? In the project that uses the
  code, because that project depends on the features that the test demands?
  Or in your model code project, since the code is there?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If I were you, I would not go down that road.&lt;/p&gt;
&lt;h2&gt;Distribute the data&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://oreilly.com/catalog/9780596515201&quot;&gt;Enterprise Rails&lt;/a&gt; does mention a 
few ways to distribute your data to the application that needs the data. 
The idea is to create a books database (and a books model) that is then used
by the &amp;#8216;book processing system&amp;#8217; locally. &lt;em&gt;Why share when you can own it?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Because sharing is really what makes applications interesting to whomever uses
it. And sharing things in a good way really is what application architecture
is about.&lt;/p&gt;
&lt;p&gt;So data distribution doesn&amp;#8217;t work, since there will always be some overlap
in data access.&lt;/p&gt;
&lt;h2&gt;Provide model access as a service&lt;/h2&gt;
&lt;p&gt;The remaining solution then is: Provide access to your model layer through
small services that you publish. Access the model through them and &lt;em&gt;only&lt;/em&gt; that
way.&lt;/p&gt;
&lt;p&gt;When the model changes, the service can stay the same. This solves the deployment
issues I&amp;#8217;ve shown with the first solution. And because it decouples the consumer
of the service from the data, essentially where the data is located doesn&amp;#8217;t 
matter anymore.&lt;/p&gt;
&lt;p&gt;Your service will provide an &lt;em&gt;interface&lt;/em&gt; for data access. This will hide 
complexity, allow you to provide abstraction. Its just a good idea&amp;#8482;.&lt;/p&gt;
&lt;h1&gt;And to end on a practical note&lt;/h1&gt;
&lt;p&gt;I am getting a lot of mileage out of &lt;a href=&quot;http://incubator.apache.org/thrift/&quot;&gt;thrift&lt;/a&gt; 
these days. Being able to create service points and not limit myself to 
one particular language at the same time just has this innate beauty to 
the language geek in me.&lt;/p&gt;
&lt;p&gt;Thrift lets you create services that look like instances of objects on both
sides. It will handle marshalling and unmarshalling for you. The internal
architecture of thrift really convinces me. It is
&lt;a href=&quot;http://github.com/kschiess/thrift_amqp_transport&quot;&gt;hackable&lt;/a&gt; / more on that
later on.&lt;/p&gt;
&lt;p&gt;I am really not convinced of &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt;/&lt;span class=&quot;caps&quot;&gt;SOAP&lt;/span&gt;/&lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;RPC&lt;/span&gt;. I don&amp;#8217;t want to clutter my
controllers with &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; generating code. And even though I am using &lt;span class=&quot;caps&quot;&gt;REST&lt;/span&gt; style
controllers these days (as a way of structuring my application), I don&amp;#8217;t want
those be an &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; at the same time. I am really afraid of ending up with the
&amp;#8216;Big Generic Interface To Everything&amp;#8482;&amp;#8217; and not being able to change it 
anymore when I need to. It ties things together that want to be free!&lt;/p&gt;
&lt;p&gt;Thrift is small and neat. I can create a service within the space of an
hour but still am able to do so explicitly.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="rails" label="rails" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="models" label="models" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="soa" label="soa" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="services" label="services" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="REST" label="REST" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="bdd" label="bdd" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="tdd" label="tdd" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="thrift" label="thrift" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="XML RPC" label="XML RPC" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="SOAP" label="SOAP" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="rpc" label="rpc" />
   
 </entry>
 
 <entry>
   <title>A useful addition to your spec_helper.rb</title>
   <link href="http://blog.absurd.li/2009/09/29/useful_rspec_helper.html"/>
   <updated>2009-09-29T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2009/09/29/useful_rspec_helper</id>
   <content type="html">&lt;p&gt;Here&amp;#8217;s a little something that is really useful to put at the end of your 
&lt;code&gt;spec/spec_helper.rb&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  # Run away with this. However, if it causes a nightly bug hunt or two, don't
  # blame me. Please. 
  class EscapedOut
    def initialize(old_io)
      @old_io = old_io
    end
    def write(str)
      @old_io.write str.gsub(/&amp;lt;/, '&amp;amp;lt;')
    end
  end
  $stdout = EscapedOut.new($stdout)  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Afterwards, to quickly debug your specs in TextMate, you just enter&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  it &quot;some specification&quot; do
    p some_object  # temporary debug code
    
    # some test here that fails for unknown reasons
  end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and it will just work, outputting the string you&amp;#8217;d expect and not a very short
line starting with &amp;#8216;#&amp;#8217; and then nothing. The trick is that the string that is
originally output (something like &amp;#8216;&lt;code&gt;#&amp;lt;Foo:0x128a964&amp;gt;&lt;/code&gt;&amp;#8217;) is converted into 
&lt;code&gt;#&amp;amp;amp;lt;Foo:0x128a964&amp;gt;&lt;/code&gt; which will output just fine.&lt;/p&gt;
&lt;p&gt;You&amp;#8217;re welcome.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="rails" label="rails" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="rspec" label="rspec" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="tricks" label="tricks" />
   
 </entry>
 
 <entry>
   <title>Joel, duct tape is just one of the tools we have.</title>
   <link href="http://blog.absurd.li/2009/09/24/on_smart_boys_in_programming.html"/>
   <updated>2009-09-24T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2009/09/24/on_smart_boys_in_programming</id>
   <content type="html">&lt;p&gt;I used to really like what you write &amp;#8216;on software&amp;#8217; &amp;#8211; now I start really
hating it. But that is more useful, because you always get me to think.&lt;/p&gt;
&lt;p&gt;The guy with the 
&lt;a href=&quot;http://www.joelonsoftware.com/items/2009/09/23.html&quot;&gt;duct tape&lt;/a&gt; – I would hate 
his guts if he was on my team.&lt;sup class=&quot;footnote&quot; id=&quot;fnr1&quot;&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; The little stunt with &lt;em&gt;prev&lt;/em&gt; and &lt;em&gt;next&lt;/em&gt;
pointers of a linked list rolled into 32bits using &lt;em&gt;&lt;span class=&quot;caps&quot;&gt;XOR&lt;/span&gt;&lt;/em&gt; – nice. &lt;strong&gt;But very
immature&lt;/strong&gt;. If that guy goes missing, you can basically scrap his code and
start again. That is not very much better than using multiple inheritance&lt;sup class=&quot;footnote&quot; id=&quot;fnr2&quot;&gt;&lt;a href=&quot;#fn2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;
and multithreaded &lt;span class=&quot;caps&quot;&gt;COM&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;You are missing a point.&lt;/em&gt; The point is not to deliver software, at least not
only, but to deliver &lt;em&gt;working&lt;/em&gt; software. There are really just two possible
outcomes: Either the thing you&amp;#8217;re creating works half-way, or it doesn&amp;#8217;t.&lt;sup class=&quot;footnote&quot; id=&quot;fnr3&quot;&gt;&lt;a href=&quot;#fn3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
If it works half-way, you (or someone else) will have to work on it for the
whole of its lifetime (ambiguity intended). And the customer doesn&amp;#8217;t want old
bugs cropping up again and again. And he wont listen to you if you talk about
duct tape. He doesn&amp;#8217;t care.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Duct tape&lt;/em&gt; is just one of the tools we have. And as such, it needs to be
applied where appropriate. Anyone claiming one tool to be vastly better than
all the others is just wrong, whatever the tool. Your smart boy should learn
to write code that others can read and maintain. Then he&amp;#8217;s got a real future
in software development.&lt;/p&gt;
&lt;p&gt;I think that every talented programmer starts out as duct-tape guy. And then
some of the things he tapes together come crashing down on him (or on the
customer). And then he learns. But the dichotomy you&amp;#8217;re proposing is wrong,
its not either duct-tape or over-engineering. &lt;span class=&quot;caps&quot;&gt;IMHO&lt;/span&gt;, there is a lot of middle
ground. Just as an example (one is enough) &amp;#8211; &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;/&lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt; practice is to &amp;#8216;do the
simplest thing that can possibly work&amp;#8217;. This one sentence has saved me years
of mental effort that would ultimately have been invisible to the customer.&lt;/p&gt;
&lt;p&gt;The real work is to write working software. Over-engineering and building 
&lt;a href=&quot;http://en.wikipedia.org/wiki/Second-system_effect&quot;&gt;a second system&lt;/a&gt; 
is just (busy-work) work evasion. But the duct tape approach is evading work
as well, by being lazy in the sort of way clever people are.&lt;/p&gt;
&lt;p&gt;What I&amp;#8217;ve been wondering. Are you doing Jamie Zawinski any kind of justice
with your article?&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;footnote&quot; id=&quot;fnr1&quot;&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; &amp;#8216;Hate his guts&amp;#8217; is just more colorful than &amp;#8216;take issues with&amp;#8217; – No, I 
wouldn&amp;#8217;t hate anyones guts. That is very rare.&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;footnote&quot; id=&quot;fnr2&quot;&gt;&lt;a href=&quot;#fn2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; I guess that is just a &lt;a href=&quot;http://en.wikipedia.org/wiki/Inheritance_(computer_science)&quot;&gt;typo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;footnote&quot; id=&quot;fnr3&quot;&gt;&lt;a href=&quot;#fn3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; About one third of IT projects get cancelled before completing. The other
two thirds sometimes overrun their budget by as much as twice the original
estimate. (ie: &amp;#8216;The Standish Group Report&amp;#8217;, &lt;em&gt;The Standish Group&lt;/em&gt;, 1995.
&lt;a href=&quot;http://www.projectsmart.co.uk/docs/chaos-report.pdf&quot;&gt;pdf&lt;/a&gt;) We can&amp;#8217;t pretend
this isn&amp;#8217;t happening and we need to feel responsible for the state of the
industry.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="smart boys" label="smart boys" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="over-engineering" label="over-engineering" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="duct tape" label="duct tape" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="lazy" label="lazy" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="bdd" label="bdd" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="tdd" label="tdd" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="testing" label="testing" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="delivery" label="delivery" />
   
 </entry>
 
 <entry>
   <title>How to prevent class unloading in Ruby on Rails</title>
   <link href="http://blog.absurd.li/2009/09/16/how_to_prevent_class_reloading_in_rails.html"/>
   <updated>2009-09-16T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2009/09/16/how_to_prevent_class_reloading_in_rails</id>
   <content type="html">&lt;p&gt;Let&amp;#8217;s assume you have a class that holds a connection to an external system, 
and you don&amp;#8217;t want Rails auto(un)loading to mess with that. The advice the 
rails documentation gives you in this case is simple and correct: Just
don&amp;#8217;t let rails autoload your class, instead, require it yourself.&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  require 'my_persistent_class'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is &lt;em&gt;one gotcha&lt;/em&gt; to this, and a gotcha that conflicts with the natural 
ordering tendency that every programmer should have. Let&amp;#8217;s say you&amp;#8217;re extending
a rails model with &lt;em&gt;FeatureX&lt;/em&gt;. It will come natural to you to name that module
&lt;em&gt;RailsModel::FeatureX&lt;/em&gt;. This has consequences.&lt;/p&gt;
&lt;p&gt;There is no real way to &amp;#8216;load&amp;#8217; that &lt;em&gt;RailsModel&lt;/em&gt; by using a require &amp;#8211; when
would you do it? During initialization process, this fails because rails 
obviously isn&amp;#8217;t in place yet. And later on – rails will be in place and the
&lt;em&gt;RailsModel&lt;/em&gt; class will already be in the fangs of autoloading.&lt;/p&gt;
&lt;p&gt;And the next time rails autounloads/ autoloads classes, &lt;em&gt;RailsModel&lt;/em&gt; – and
with it &lt;em&gt;FeatureX&lt;/em&gt; – will be reloaded as well. &lt;strong&gt;Darn&lt;/strong&gt;. The solution to this is
really simple, but it took me a while to figure this out: Just don&amp;#8217;t include
the &lt;em&gt;FeatureX&lt;/em&gt; class in the namespace of &lt;em&gt;RailsModel&lt;/em&gt;. Then doing this in 
your &lt;em&gt;environment.rb&lt;/em&gt; will ensure that your &lt;em&gt;FeatureX&lt;/em&gt; isn&amp;#8217;t unloaded:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
  config.after_initialize do
    require 'feature_x'
    
    FeatureX.set_some_persistent_attribute :foo =&amp;gt; :bar
  end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Btw: Global variables are really evil.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="rails" label="rails" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="ruby" label="ruby" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="gotcha" label="gotcha" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="class reloading" label="class reloading" />
   
 </entry>
 
 <entry>
   <title>Code Style issues with Real World Haskell</title>
   <link href="http://blog.absurd.li/2009/09/14/real_world_haskell_style_issues.html"/>
   <updated>2009-09-14T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2009/09/14/real_world_haskell_style_issues</id>
   <content type="html">&lt;p&gt;I am reading the book &amp;#8220;Real World Haskell&amp;#8221;&lt;sup class=&quot;footnote&quot; id=&quot;fnr1&quot;&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; – and enjoying it to my
surprise. What I find really hard to understand is why the authors chose a
code style this opaque. My message to you: 
&lt;em&gt;Code really is read more than it is written.&lt;/em&gt; Here&amp;#8217;s an example straight from the book:&lt;/p&gt;
&lt;pre class=&quot;sh_haskell&quot;&gt;&lt;code&gt;
  liftP2 q f g w x y z = f w x y z `q` g w x y z
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&amp;#8217;s a &lt;strong&gt;series of 18 lower case letters&lt;/strong&gt; in a row, lightened up by a few
cryptic line noise like dots and dashes. My growing fondness of the language
might come to an abrupt end if I wake up to a community that writes this kind
of code&amp;#8230;&lt;/p&gt;
&lt;p&gt;But to end this post on an upbeat note, I really would like to congratulate
the authors of the book. &lt;em&gt;Real World Haskell&lt;/em&gt; really is up there with the
programming language introductions that make you want to pick up the tool and
rewrite an operating system in it. It reads nicely from the start to the end, 
and if you manage to skimp/skip/plow through the examples like the one I 
gave above, you&amp;#8217;ll find a lot of nice code as well. Worth reading!&lt;/p&gt;
&lt;p&gt;&lt;sup class=&quot;footnote&quot; id=&quot;fnr1&quot;&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; &lt;em&gt;Real World Haskell&lt;/em&gt; (Bryan O&amp;#8217;Sullivan, John Goerzen, Don Stewart)&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="haskell" label="haskell" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="programming languages" label="programming languages" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="books" label="books" />
   
 </entry>
 
 <entry>
   <title>Perceived Advantages of Writing the Specification first</title>
   <link href="http://blog.absurd.li/2009/09/07/perceived_advantages_of_bdd.html"/>
   <updated>2009-09-07T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2009/09/07/perceived_advantages_of_bdd</id>
   <content type="html">&lt;p&gt;I will try to summarize some of the perceived advantages of writing
specifications first. The word &amp;#8216;perceived&amp;#8217; indicates that I don&amp;#8217;t mean to say
that the ideas presented here are hard facts. Rather, they are based on the
anecdotal evidence of my senses and my experience. I&amp;#8217;ll talk about&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;How Specs are documentation (&lt;em&gt;this post&lt;/em&gt;)&lt;/li&gt;
	&lt;li&gt;How testable code has clean interfaces&lt;/li&gt;
	&lt;li&gt;How testing forces you to think&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Specs are the documentation&lt;/h2&gt;
&lt;p&gt;If you apply some sort of quality control on your specifications, they will be
readable. They should also reflect what you or (to a varying degree) your
customer expect from the code. That said: Look at your specs as the only up to
date documentation for the code.&lt;/p&gt;
&lt;p&gt;Having those specs makes your situation a lot better than having only the
code. While you can&amp;#8217;t refactor code and keep it at the same time (for
documentation purposes on what you already have), you &lt;em&gt;can&lt;/em&gt; refactor code and
keep the specifications.&lt;/p&gt;
&lt;p&gt;Specs encode all the choices you&amp;#8217;ve made during writing code. People that
don&amp;#8217;t write specs have also made these same choices. &lt;em&gt;But only mentally&lt;/em&gt;. And
then forgotten about it before lunch. It doesn&amp;#8217;t feel differently, the code
commits might even be exactly the same. Except, some time later, you (the guy
who does &lt;a href=&quot;http://rspec.info&quot;&gt;&lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt;&lt;/a&gt;) will still have a record of what you thought
of (or didn&amp;#8217;t) when writing the code.&lt;/p&gt;
&lt;p&gt;I had to maintain code that looked like this once:&lt;/p&gt;
&lt;pre class=&quot;sh_java&quot;&gt;&lt;code&gt;
public int someFunction(int p1, int p2) {
  // Some code 
  // Some more code
  
  if (p2 == 23) { // (1)
    return -1;
  }
  
  // Other code
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above snippet is anonymized to protect the innocent. The comment at (1)
said something like &amp;#8216;this is a special case&amp;#8217; or &amp;#8217;I&amp;#8217;ve had to introduce this,
otherwise it wouldn&amp;#8217;t work&amp;#8217;. While I appreciate the comment, it doesn&amp;#8217;t help
at all.&lt;/p&gt;
&lt;p&gt;My task was to clean up this piece of code and to rewrite some of it. As it
happens, no tests/specs were available, making that thin comment everything I
could hang myself on. In situations like these, you have two choices: Delete
the whole exception and wait for things to break or leave it in and hope
someone else breaks it later. Either way, this is a liability that waits to
bite you the next time around. Having to remember a functions with a positive
image may return a special negative value that indicates mystery going on
makes reasoning about the system a complex task.&lt;/p&gt;
&lt;p&gt;It would have been an altogether different matter if I had had specifications
like these:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
describe &quot;someFunction&quot; do
  it &quot;should return -1 (exceptionally) when flab hits the fob&quot; do
    obj.someFunction(1, 2).should == -1
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In that case, I might have left the code as it was. There&amp;#8217;s a clear reason
for why this ugly snippet has come to be. And I even have a choice: I let it
stand as it is (for working code can&amp;#8217;t be all bad) or I rip it out with some
confidence in what I am doing.&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s a
&lt;a href=&quot;http://www.ted.com/talks/bill_stone_explores_the_earth_and_space.html&quot;&gt;guy&lt;/a&gt;
who wants to fly to the moon without the fuel to get back. My job isn&amp;#8217;t like
that. I want to be able to go back and revise my choices. That&amp;#8217;s why I write
them down.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="bdd" label="bdd" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="specification" label="specification" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="opinion" label="opinion" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="mocks" label="mocks" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="stubs" label="stubs" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="philosophy" label="philosophy" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="long" label="long" />
   
 </entry>
 
 <entry>
   <title>Confession: I am somewhat of a tester</title>
   <link href="http://blog.absurd.li/2009/09/02/i_am_somewhat_of_a_tester.html"/>
   <updated>2009-09-02T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2009/09/02/i_am_somewhat_of_a_tester</id>
   <content type="html">&lt;p&gt;I can&amp;#8217;t deny it. After only minutes of writing real code I long for the snug
comfort of well written behavioural specifications (also known as tests).&lt;/p&gt;
&lt;h2&gt;Writing specifications first&lt;/h2&gt;
&lt;p&gt;Any yes, to really get your coder level up, you will need to write
specifications before you write the code. This sounds terribly hard and at
first it is.&lt;/p&gt;
&lt;p&gt;Why is it hard? Because &lt;em&gt;you need to know what you are going to write before you do.&lt;/em&gt; 
But that&amp;#8217;s another blog post there.&lt;/p&gt;
&lt;h1&gt;Frequently seen stereotypes (&lt;span class=&quot;caps&quot;&gt;FSS&lt;/span&gt;)&lt;/h1&gt;
&lt;p&gt;A few stereotypes and my answers:&lt;/p&gt;
&lt;h2&gt;But .. some things can&amp;#8217;t be tested&lt;/h2&gt;
&lt;p&gt;No. You are not asking the right question. It&amp;#8217;s not: &amp;#8220;can it be tested
automatically?&amp;#8221;, its &amp;#8220;how much does it cost?&amp;#8221;, weighted against the benefit of
having tests. That discussion tends to be sharper around the edges.&lt;/p&gt;
&lt;p&gt;Also, you might want to consider &lt;em&gt;stubbing&lt;/em&gt; and &lt;em&gt;mocking&lt;/em&gt;, two &amp;#8211; no, really
just one &amp;#8211; essential tool(s) in any developers toolbox. Then you should
look at &lt;a href=&quot;http://mockingobjects.com&quot;&gt;mockingobjects.com&lt;/a&gt; and a few other sites
and practice daily.&lt;/p&gt;
&lt;p&gt;To be fair: Some things can be pretty hard to test. &lt;strong&gt;Be stubborn&lt;/strong&gt;. If you can
show how it pays off to have a test, you can test it. Take a look at the
consumer product industry: A simple childs toy is tested more thoroughly than
the average piece of code. If all else fails, use a robotic arm that pounds
your keyboard like a wild monkey, looking for wear and inflammability.&lt;/p&gt;
&lt;h2&gt;Its all just a waste of time, I can write my code just right&lt;/h2&gt;
&lt;p&gt;That probably used to be the case. Or even is the case. It&amp;#8217;s just .. I hear
this a lot from people who mostly work alone. And on small(ish) projects.&lt;/p&gt;
&lt;p&gt;Working in teams is another thing altogether. You will not be able to keep 
all details in your mind like you used to. Plus, people break stuff. Mostly by
making something else better. You need something to tie these forces together, 
making them visible.&lt;/p&gt;
&lt;p&gt;Oh and&amp;#8230; if you still think you can write code without tests just fine &amp;#8211; go 
and ask the next guy how much time he spends reading your code before he can
modify it. That is: modify it and still be sure that nothing breaks.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="automated testing" label="automated testing" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="bdd" label="bdd" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="confession" label="confession" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="stubs" label="stubs" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="mocks" label="mocks" />
   
 </entry>
 
 <entry>
   <title>To the what and _why of opening a new blog</title>
   <link href="http://blog.absurd.li/2009/09/01/welcome_to_my_potential_reader.html"/>
   <updated>2009-09-01T00:00:00+02:00</updated>
   <id>http://blog.absurd.li/2009/09/01/welcome_to_my_potential_reader</id>
   <content type="html">&lt;p&gt;This is a welcome to you, dear potential reader. Again, I take the jump &amp;#8211; 
opening a blog, blossoming like a flower come spring, trusting a new friend, 
write a new specification.&lt;/p&gt;
&lt;p&gt;Or like Hermann Hesse said:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Wie jede Blüte welkt
und jede Jugend dem Alter weicht,
blüht jede Lebensstufe,
blüht jede Weisheit auch und jede Tugend
zu ihrer Zeit und darf nicht ewig dauern.
Es muss das Herz bei jedem Lebensrufe
bereit zum Abschied sein und Neubeginne,
um sich in Tapferkeit und ohne Trauern
in and&amp;#8217;re, neue Bindungen zu geben.
&lt;strong&gt;Und jedem Anfang wohnt ein Zauber inne,
der uns beschützt und der uns hilft zu leben.&lt;/strong&gt;
Wir sollen heiter Raum um Raum durchschreiten,
an keinem wie an einer Heimat hängen,
der Weltgeist will nicht fesseln uns und engen,
er will uns Stuf&amp;#8217; um Stufe heben, weiten!
Kaum sind wir heimisch einem Lebenskreise
und traulich eingewohnt,
so droht Erschlaffen!
Nur wer bereit zu Aufbruch ist und Reise,
mag lähmender Gewohnheit sich entraffen.
Es wird vielleicht auch noch die Todesstunde
uns neuen Räumen jung entgegen senden:
des Lebens Ruf an uns wird niemals enden.
Wohlan denn, Herz, nimm Abschied und gesunde!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And because this is really going to be a blog about programming, here&amp;#8217;s a 
code snippet:&lt;/p&gt;
&lt;pre class=&quot;sh_ruby&quot;&gt;&lt;code&gt;
00000000001111111111222222222233333333334444444444555555555566666666666777777777788888888
# This is totally unrelated to anything, but better than foo and bar.
# Voila. I give you: The identity line filter. 
class LineFilter
  def filter(line)
    line
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Oh and .. like you might have figured out by now: This is a test entry that
only serves to populate an otherwise empty design. Like those really shiny new
buildings where no one has lived – beautiful but empty, a new shirt.&lt;/p&gt;</content>
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="philosophy" label="philosophy" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="snafu" label="snafu" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="welcome" label="welcome" />
   
     <category scheme="http://edward.oconnor.cx/tags/"
               term="tagging_is_random" label="tagging_is_random" />
   
 </entry>
 
 
</feed>