<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Late to the Party: Category Programming</title>
    <link>http://cwilliams.textdriven.com/articles/category/programming</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Ruby. Rails. Stuff.</description>
    <item>
      <title>Aptana Studio 1.0 Released!</title>
      <description>&lt;p&gt;Wow it's been quite a while since I last posted. In the meantime I've been working hard on RDT and RadRails at Aptana and the job has been great. I'm very lucky to have found a way to work on the open source projects I love full-time.&lt;/p&gt;

&lt;p&gt;In that vein I'd like to announce that &lt;a href="http://www.aptana.com/blog/?p=200?diff=y"&gt;we've released the 1.0 of Aptana&lt;/a&gt;. This release is important for a number of reasons. First, we think the product is good-to-go for everyone. Second, we're announcing &lt;a href="http://www.aptana.com/products/studio_professional.php"&gt;a Pro version of the IDE&lt;/a&gt;. This version is for users who want to support the project so we can keep going, or who want the extra features and perks that come with a license: nightly build access, priority support, IE Javascript Debugger, SFTP/FTPS support and all sorts of other goodies. The support, nightly builds, SVN access also apply to the other components of what we're now calling Aptana Studio: &lt;a href="http://radrails.org/"&gt;RadRails&lt;/a&gt;, iPhone, PHP and AIR. So if you want to be on the bleeding edge of RadRails/RDT development you'll probably want to look into getting a license.&lt;/p&gt;

&lt;p&gt;Keep in mind that while we do offer a pro version for those who'd like to support us or the extra stuff, we are still shipping the same codebase (minus the commercial features) as &lt;a href="http://www.aptana.com/products/studio_community.php"&gt;an open source project under GPL&lt;/a&gt;. And we plan to remain an open-source company with an open source product.  Here's hoping that model will work for us!&lt;/p&gt;</description>
      <pubDate>Tue, 30 Oct 2007 12:41:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:494d8149-4863-4cca-bf1b-6c1d84350478</guid>
      <author>chris.a.williams@gmail.com (Chris)</author>
      <link>http://cwilliams.textdriven.com/articles/2007/10/30/aptana-studio-1-0-released</link>
      <category>Programming</category>
      <category>Personal</category>
      <category>Rails</category>
      <category>aptana</category>
      <category>RDT</category>
      <category>radrails</category>
      <category>Rails</category>
      <category>ide</category>
    </item>
    <item>
      <title>Aptana backs RDT, hires me</title>
      <description>&lt;p&gt;I'm proud to announce today that &lt;a href="http://www.aptana.com"&gt;Aptana&lt;/a&gt; has hired me to work full-time on &lt;a href="http://rubyeclipse.sourceforge.net"&gt;RDT&lt;/a&gt;, RadRails and integrating that work with their existing Aptana IDE which focuses on CSS, HTML and Javascript.&lt;/p&gt;

&lt;div style="background-color: white; text-align: center;"&gt;&lt;a href="http://www.aptana.com/rdt.html"&gt;&lt;img src="/images/aptana_radrails_rdt_ajax_rails_blue.gif" alt=""aptana-radrails-rdt ajax on rails/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;This announcement means that RDT will now have commercial backing (but will remain open-source and free!) and that you should see RDT and RadRails move forward at a much quicker pace than in the past.&lt;/p&gt;

&lt;p&gt;This is also great news for RadRails users and Rails developers in general as integrating the two will give you code completion, outlines, help, debugging and much more across the entire stack - from model to controller to the HTML, ruby code, CSS and Javascript that make up your views.&lt;/p&gt;

</description>
      <pubDate>Sat, 21 Apr 2007 16:41:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:c68f2859-5c20-4685-a61e-da26f1583f63</guid>
      <author>chris.a.williams@gmail.com (Chris)</author>
      <link>http://cwilliams.textdriven.com/articles/2007/04/21/aptana-backs-rdt-hires-me</link>
      <category>Programming</category>
      <category>Personal</category>
      <category>Web design</category>
      <category>Ruby</category>
      <category>Rails</category>
      <category>aptana</category>
      <category>ruby</category>
      <category>Rails</category>
      <category>commercial</category>
      <category>sponsor</category>
      <category>RDT</category>
      <category>radrails</category>
      <category>ide</category>
      <category>eclipse</category>
      <category>announcement</category>
    </item>
    <item>
      <title>RadRails dying off?</title>
      <description>&lt;p&gt;Kyle Shank of the &lt;a href="http://www.radrails.org/"&gt;RadRails&lt;/a&gt; team has mentioned that he and Matt are both working on a web startup. &lt;a href="http://www.radrails.org/blog/2007/3/5/radrails-future_1173078407"&gt;Looks like the priority of RadRails is lower&lt;/a&gt; for them - after all, RadRails doesn't make money.&lt;/p&gt;

&lt;p&gt;It's a shame that this sort of thing happens, but I can't say I'm all that surprised. I've been working on &lt;a href="http://rubyeclipse.sourceforge.net"&gt;RDT&lt;/a&gt; for nearly 4 years now and I can definitely say that people just don't pay for free things. You can beg for donations, but you shouldn't expect them. Given the amount of time and effort - and the sheer number of downloads - it just doesn't pay the bills to run an open source project that passively solicits donations. I estimate the per-user donations for RDT to be at about 1.4 cents*. And if we take out the one large donor?  .00071 cents per user.&lt;/p&gt;

&lt;p&gt;That doesn't quite cut it for rent and food, unless of course you get the entire world to use your product.&lt;/p&gt;

&lt;p&gt;I wish Kyle and Matt well and hope that others from the community step forward and help lead the project onward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: Looks like RadRails isn't dying off - it's &lt;a href="http://www.crn.com/software/197801078"&gt;getting new ownership&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;* This estimate assumes we count RadRails users as RDT users, because RadRails contains RDT. It also uses just the raw zip downloads from Sourceforge for both projects. There is a large number of users we are not counting here who have downloaded via Eclipse's update site mechanism, and who use RDT from other distributions available.&lt;/em&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 06 Mar 2007 14:02:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:fb4bb0b3-a040-4804-90fe-bc0f0bb369bb</guid>
      <author>chris.a.williams@gmail.com (Chris)</author>
      <link>http://cwilliams.textdriven.com/articles/2007/03/06/radrails-dying-off</link>
      <category>Programming</category>
      <category>Personal</category>
      <category>Ruby</category>
      <category>Java</category>
      <category>RDT</category>
      <category>radrails</category>
      <category>open</category>
      <category>source</category>
    </item>
    <item>
      <title>SVN and SVK</title>
      <description>&lt;p&gt;Dear Lazyweb:&lt;/p&gt;

&lt;p&gt;I would like to take an existing SVN repository of a project (like say, Typo), check out a tagged version, create local modifications and save the modified version in a local/home SVN repository(my blog). Later, I'd like to sync up the local version to a new tagged version of the original repository (Typo), handle any merges locally and then check in the result into my local repository again. Rinse and repeat, ad infinitum.&lt;/p&gt;

&lt;p&gt;Is SVK the right job for this?  Has anybody done something like this? Essentially its the equivalent of creating a branch on a SVN repository but having that branch in an entirely separate SVN repository instance. I don't have experience with this, so I'd greatly appreciate any pointers anybody out there might have.&lt;/p&gt;</description>
      <pubDate>Fri, 16 Feb 2007 13:38:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:968541c0-bb7a-4799-8dfe-b5816bf02cf7</guid>
      <author>chris.a.williams@gmail.com (Chris)</author>
      <link>http://cwilliams.textdriven.com/articles/2007/02/16/svn-and-svk</link>
      <category>Programming</category>
      <category>Personal</category>
      <category>svn</category>
      <category>svk</category>
      <category>scm</category>
      <category>repository</category>
      <category>programming</category>
      <category>development</category>
      <category>subversion</category>
    </item>
    <item>
      <title>RDT gets Refactoring support</title>
      <description>&lt;p&gt;Well the &lt;a href="http://jutopia.tirsen.com/articles/2007/01/30/and-you-didnt-think-it-could-be-done"&gt;cat is out&lt;/a&gt; &lt;a href="http://on-ruby.blogspot.com/2007/02/ruby-refactoring-rubicon.html"&gt;of the bag&lt;/a&gt;: &lt;a href="http://r2.ifsoftware.ch/trac"&gt;Mirko Stocker and his cohorts&lt;/a&gt; have committed their refactoring support to &lt;a href="http://rubyeclipse.sourceforge.net/"&gt;&lt;abbr title="Ruby Development Tool"&gt;RDT&lt;/abbr&gt;&lt;/a&gt;'s Subversion repository.&lt;/p&gt;

&lt;p&gt;This means we'll be able to roll out 0.9.0 with this support. Right now we're working to get it integrated into the build process, so that it will begin showing up in our new builds. I'm pretty excited myself, because I've had little chance to try out their work.&lt;/p&gt;

&lt;p&gt;This refactoring support joins other recent work in RDT which allows us to do some occurence marking of variables, code completion and other exciting features (thanks &lt;a href="http://jayunit.net/"&gt;Jason&lt;/a&gt;!). There's certainly a long way yet to go to get the tools polished - for instance we still have a hard time doing code completion (or much else) on a file which is being edited while the syntax is temporarily incorrect (the &lt;a href="http://www.jruby.org"&gt;JRuby&lt;/a&gt; parser is great, but not so forgiving) - but we're constantly marching forward.&lt;/p&gt;

&lt;p&gt;Look for &lt;a href="http://rubyeclipse.mktec.com/cgi-bin/trac.py/roadmap"&gt;0.9.0 to come out sometime this month (we're aiming for the 15th)&lt;/a&gt;!&lt;/p&gt;</description>
      <pubDate>Tue, 06 Feb 2007 16:37:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:1af8c68c-4cb7-4341-a638-b8e396d9f737</guid>
      <author>chris.a.williams@gmail.com (Chris)</author>
      <link>http://cwilliams.textdriven.com/articles/2007/02/06/rdt-gets-refactoring-support</link>
      <category>Programming</category>
      <category>Personal</category>
      <category>Ruby</category>
      <category>Java</category>
      <category>refactoring</category>
      <category>ruby</category>
      <category>eclipse</category>
      <category>ide</category>
    </item>
    <item>
      <title>Patterns in Ruby: Decorator revisited</title>
      <description>&lt;p&gt;A while back I wrote an article describing some possible ways to implement a 
&lt;a href="http://cwilliams.textdriven.com/articles/2006/10/27/patterns-in-ruby-template-method"&gt;Decorator pattern in Ruby&lt;/a&gt;. 
I've stumbled across several mentions of 
yet another idiom used so often in the Rails codebase that they've extracted 
it into the latest ActiveSupport. That idiom is 
&lt;a href="http://weblog.rubyonrails.org/2006/4/26/new-in-rails-module-alias_method_chain"&gt;&lt;code&gt;alias_method_chain&lt;/code&gt;&lt;/a&gt;,
and it's a good example of a decorator implementation.&lt;/p&gt;

&lt;p&gt;This idiom is a codified example of using the alias approach I briefly mentioned in the earlier article. In that 
article we aliased the original implementation with anew name, and set up a new implementation of our method 
(often delegating to the original) with the original's name. A quick example makes this clear:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Window&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;draw&lt;/span&gt;
    &lt;span class="comment"&gt;# do some drawing here...&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="comment"&gt;# some code...&lt;/span&gt;

&lt;span class="comment"&gt;# creates a 'copy' of draw method, but gives it&lt;/span&gt;
&lt;span class="comment"&gt;# the name/selector 'original_draw'&lt;/span&gt;
  &lt;span class="keyword"&gt;alias&lt;/span&gt; &lt;span class="symbol"&gt;:original_draw&lt;/span&gt; &lt;span class="symbol"&gt;:draw&lt;/span&gt; 

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;draw&lt;/span&gt;
    &lt;span class="ident"&gt;draw_vertical_scrollbar&lt;/span&gt;
    &lt;span class="ident"&gt;original_draw&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;&lt;code&gt;alias_method_chain&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;In &lt;a href="http://weblog.rubyonrails.org/2006/4/26/new-in-rails-module-alias_method_chain"&gt;Rails 1.2 (ActiveSupport specifically)&lt;/a&gt;, the Rails core team found many instances of this pattern 
and codified a new method on the class Module, &lt;code&gt;alias_method_chain&lt;/code&gt;. This class-level method encapsulates this 
pattern of wrapping existing methods with additional behavior.&lt;/p&gt;

&lt;p&gt;Here's a specific example, showing how they would wrap rendering with layouts:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;alias_method&lt;/span&gt; &lt;span class="symbol"&gt;:render_with_no_layout&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:render&lt;/span&gt;
&lt;span class="ident"&gt;alias_method&lt;/span&gt; &lt;span class="symbol"&gt;:render&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:render_with_a_layout&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this small code snippet, they are creating a small chain of methods to wrap the existing render behavior. 
Now calls to render will be routed to &lt;code&gt;render_with_a_layout&lt;/code&gt; and then on to the original render implementation 
(which is now aliased to &lt;code&gt;render_with_no_layout&lt;/code&gt;). So they coded up &lt;code&gt;alias_method_chain&lt;/code&gt; which simply does 
the wrapping for them (using naming conventions):&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Module&lt;/span&gt;
  &lt;span class="comment"&gt;# Encapsulates the common pattern of:&lt;/span&gt;
  &lt;span class="comment"&gt;#&lt;/span&gt;
  &lt;span class="comment"&gt;#   alias_method :foo_without_feature, :foo&lt;/span&gt;
  &lt;span class="comment"&gt;#   alias_method :foo, :foo_with_feature&lt;/span&gt;
  &lt;span class="comment"&gt;#&lt;/span&gt;
  &lt;span class="comment"&gt;# With this, you simply do:&lt;/span&gt;
  &lt;span class="comment"&gt;#&lt;/span&gt;
  &lt;span class="comment"&gt;#   alias_method_chain :foo, :feature&lt;/span&gt;
  &lt;span class="comment"&gt;#&lt;/span&gt;
  &lt;span class="comment"&gt;# And both aliases are set up for you.&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;alias_method_chain&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;target&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;feature&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;alias_method&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{target}&lt;/span&gt;_without_&lt;span class="expr"&gt;#{feature}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="ident"&gt;target&lt;/span&gt;
    &lt;span class="ident"&gt;alias_method&lt;/span&gt; &lt;span class="ident"&gt;target&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{target}&lt;/span&gt;_with_&lt;span class="expr"&gt;#{feature}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Please note that if they were to replace their existing two calls to &lt;code&gt;alias_method&lt;/code&gt; above, they would need to tweak the naming a little
(the methods would become &lt;code&gt;render_without_layout&lt;/code&gt; and &lt;code&gt;render_with_layout&lt;/code&gt; as opposed to
&lt;code&gt;render_with_no_layout&lt;/code&gt; and &lt;code&gt;render_with_a_layout&lt;/code&gt; respectively).&lt;/p&gt;</description>
      <pubDate>Tue, 26 Dec 2006 18:38:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:42654a54-afbd-4e14-932e-8ef2ce31b561</guid>
      <author>chris.a.williams@gmail.com (Chris)</author>
      <link>http://cwilliams.textdriven.com/articles/2006/12/26/patterns-in-ruby-decorator-revisited</link>
      <category>Programming</category>
      <category>Ruby</category>
      <category>Rails</category>
      <category>decorator</category>
      <category>patterns</category>
      <category>ruby</category>
      <category>alias</category>
      <category>chain</category>
      <category>method</category>
    </item>
    <item>
      <title>Patterns in Ruby: Observer Pattern</title>
      <description>&lt;p&gt;Another easy to implement pattern in Ruby is the &lt;a href="http://en.wikipedia.org/wiki/Observer_pattern"&gt;Observer pattern&lt;/a&gt;.
The Observer pattern is a publish/subscribe mechanism where an objects can register to be notified of state changes (or &lt;em&gt;observe&lt;/em&gt; changes) on another &lt;em&gt;observed&lt;/em&gt; object. This pattern may often become refactored into a more general event framework (where objects fire events off into queues to which there are listeners subscribed).&lt;/p&gt;

&lt;h2&gt;The basic implementation&lt;/h2&gt;

&lt;p&gt;Here's a look at a simple ruby implementation:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Observable&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;
    &lt;span class="attribute"&gt;@listeners&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[]&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;register_listener&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;listener&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@listeners&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="ident"&gt;listener&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;unregister_listener&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;listener&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@listeners&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;remove&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;listener&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;run&lt;/span&gt;
    &lt;span class="ident"&gt;notify_listeners&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Hello!&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="ident"&gt;protected&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;notify_listeners&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;event&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@listeners&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;l&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;l&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;notify&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;event&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Listener&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;observable&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;observable&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;register_listener&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;notify&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;event&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Notified of '&lt;span class="expr"&gt;#{event}&lt;/span&gt;'&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="ident"&gt;observable&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Observable&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;
&lt;span class="ident"&gt;listener&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Listener&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;observable&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;observable&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;run&lt;/span&gt;                        &lt;span class="comment"&gt;#=&amp;gt; Notified of 'Hello!'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The pattern itself in this form is pretty general. So general, in fact, that there is a module mixin of Observer inside the standard ruby library (observer.rb).
There's some good documentation in there, and it provides a simpler path to this implementation:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;observer&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;TV&lt;/span&gt;
  &lt;span class="ident"&gt;include&lt;/span&gt; &lt;span class="constant"&gt;Observable&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;channel&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@channel&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;channel&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;up&lt;/span&gt;
    &lt;span class="attribute"&gt;@channel&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;
    &lt;span class="ident"&gt;changed&lt;/span&gt;
    &lt;span class="ident"&gt;notify_observers&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="attribute"&gt;@channel&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;ChannelWatcher&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;tv&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;tv&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;add_observer&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;update&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;channel&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Changed channel to &lt;span class="expr"&gt;#{channel}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="ident"&gt;tv&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;TV&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;160&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;watcher&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;ChannelWatcher&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;tv&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;tv&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;up&lt;/span&gt;                              &lt;span class="comment"&gt;#=&amp;gt; Changed channel to 161&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Please be aware that the API is a little different from my initial example.&lt;/p&gt;

&lt;h2&gt;Moving towards events&lt;/h2&gt;

&lt;p&gt;Both of the above implementations rely on a generic observer pattern, but the Observer pattern can often evolve into a simple event mechanism. The difference is that instead of firing a generic event object via a generic notify method, the move towards events uses unique method names, and filters events to notify only those interested in the type of event occurring.&lt;/p&gt;

&lt;p&gt;Let's see a TV example where we move towards a more specialized event firing version of the pattern:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;observer&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;TV&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;channel&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@channel&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;channel&lt;/span&gt;
    &lt;span class="attribute"&gt;@listeners&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[]&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;add_listener&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;listener&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@listeners&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="ident"&gt;listener&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;up&lt;/span&gt;
    &lt;span class="attribute"&gt;@channel&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;
    &lt;span class="attribute"&gt;@listeners&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;l&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;l&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;channel_increased&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="attribute"&gt;@channel&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;down&lt;/span&gt;
    &lt;span class="attribute"&gt;@channel&lt;/span&gt; &lt;span class="punct"&gt;-=&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;
    &lt;span class="attribute"&gt;@listeners&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;l&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;l&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;channel_decreased&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="attribute"&gt;@channel&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;ChannelUpWatcher&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;tv&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;tv&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;add_listener&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;channel_increased&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;channel&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Changed channel to &lt;span class="expr"&gt;#{channel}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;channel_decreased&lt;/span&gt;
    &lt;span class="comment"&gt;# do nothing...&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="ident"&gt;tv&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;TV&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;160&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;watcher&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;ChannelUpWatcher&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;tv&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;tv&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;up&lt;/span&gt;                              &lt;span class="comment"&gt;#=&amp;gt; Changed channel to 161&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this instance we can fire off events for surfing the Tv upwards or downwards (in channels) separately, though we still register listeners into a generic pool, and listeners are expected to contain both event methods. Variations of this can be done to register listeners into sub-groups upon registration by calling unique methods names for each registration, or by passing in a Filter object that can be used to filter to the events the listener cares about. In filtering at registration we can avoid listeners having to implement every event firing method and minimize the number of events fired off.&lt;/p&gt;

&lt;p&gt;One illustration of this observer based event model is the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/event/package-summary.html"&gt;Java Swing events API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Extending the pattern towards this event firing mechanism even further we'd likely move into using queues and firing events off to the queues themselves rather than directly to observers. Observers would then become subscribers to the queues.&lt;/p&gt;

&lt;h2&gt;Using blocks and procs&lt;/h2&gt;

&lt;p&gt;The Observer pattern as described above is the typical pattern followed in most languages without closures, lambdas or functors.
In Ruby we have the ability to throw around closures/blocks so we can take the pattern a little further. &lt;/p&gt;

&lt;p&gt;Let's revisit our original implementation, but let's add the ability to register the callback function to be performed upon notification.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Observable&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;
    &lt;span class="attribute"&gt;@listeners&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[]&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;register_listener&lt;/span&gt;&lt;span class="punct"&gt;(&amp;amp;&lt;/span&gt;&lt;span class="ident"&gt;blk&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@listeners&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="ident"&gt;blk&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;unregister_listener&lt;/span&gt;&lt;span class="punct"&gt;(&amp;amp;&lt;/span&gt;&lt;span class="ident"&gt;blk&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@listeners&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;remove&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;blk&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;run&lt;/span&gt;
    &lt;span class="ident"&gt;notify_listeners&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Hello!&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="ident"&gt;protected&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;notify_listeners&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;event&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@listeners&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;l&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;l&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;event&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Listener&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;observable&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;observable&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;register_listener&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;event&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Notified of '&lt;span class="expr"&gt;#{event}&lt;/span&gt;'&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;}&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="ident"&gt;observable&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Observable&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;
&lt;span class="ident"&gt;listener&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Listener&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;observable&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;observable&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;run&lt;/span&gt;                        &lt;span class="comment"&gt;#=&amp;gt; Notified of 'Hello!'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is the model illustrated in the &lt;a href="http://www.ruby-doc.org/stdlib/libdoc/tk/rdoc/index.html"&gt;Tk bindings for Ruby&lt;/a&gt; - you can see examples of usage in &lt;a href="http://www.rubycentral.com/book/ext_tk.html#S3"&gt;Programming Ruby's section on binding events in Tk&lt;/a&gt;. That section and &lt;a href="http://www.rubycentral.com/book/tut_containers.html#UG"&gt;their section on blocks as closures&lt;/a&gt; begin to broach the how closures capture the context in which they were defined - allowing for some very interesting and complex behavior in using blocks and procs as event or observer callbacks (allowing you to refer to objects available at the scope of the block definition, not when the callback/block execution occurs).&lt;/p&gt;</description>
      <pubDate>Thu, 02 Nov 2006 20:10:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:d8f25c41-047b-4a66-ab91-c18dd814ebe4</guid>
      <author>chris.a.williams@gmail.com (Chris)</author>
      <link>http://cwilliams.textdriven.com/articles/2006/11/02/patterns-in-ruby-observer-pattern</link>
      <category>Programming</category>
      <category>Ruby</category>
      <category>ruby</category>
      <category>patterns</category>
      <category>observer</category>
      <category>programming</category>
      <category>design</category>
    </item>
    <item>
      <title>Patterns in Ruby: Singleton Pattern</title>
      <description>&lt;p&gt;The &lt;a href="http://en.wikipedia.org/wiki/Singleton_pattern"&gt;Singleton pattern&lt;/a&gt; is the black sheep of the pattern family. 
It was easy to grasp, developers everywhere applied it liberally, and an inevitable backlash came against its overuse.&lt;/p&gt;

&lt;p&gt;I won't make any judgments or reccomendations on when to use it - but I will show you just how easy it is to apply in Ruby.&lt;/p&gt;

&lt;p&gt;The literal translation of the pattern is to create a class level instance method and to hide the &lt;code&gt;new&lt;/code&gt; method.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;    
&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Example&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;
    &lt;span class="comment"&gt;# do something?&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;self.instance&lt;/span&gt;
    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="attribute"&gt;@@instance&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;defined?&lt;/span&gt; &lt;span class="attribute"&gt;@@instance&lt;/span&gt;
    &lt;span class="attribute"&gt;@@instance&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;new&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="ident"&gt;private_class_method&lt;/span&gt;  &lt;span class="symbol"&gt;:new&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="constant"&gt;Example&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;instance&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;object_id&lt;/span&gt;  &lt;span class="comment"&gt;#=&amp;gt; 21783380&lt;/span&gt;
&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="constant"&gt;Example&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;instance&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;object_id&lt;/span&gt;  &lt;span class="comment"&gt;#=&amp;gt; 21783380&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This example gives you the basic idea, but it doesn't cover many cases you'd like to handle, like cloning or &lt;code&gt;dup&lt;/code&gt;ing the singleton. It also doesn't hide the class level &lt;code&gt;allocate&lt;/code&gt; method, which means a sneaky coder could still create another instance through some hacking.
Lastly, it's not thread safe.&lt;/p&gt;

&lt;p&gt;Luckily, Ruby already provides a module for making classes singletons. It's in the standard library, inside 'singleton.rb'.
Here's how you use it:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;    
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;singleton&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Example&lt;/span&gt;
  &lt;span class="ident"&gt;include&lt;/span&gt; &lt;span class="constant"&gt;Singleton&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This module will do the same thing as my example above but will also handle hiding &lt;code&gt;allocate&lt;/code&gt;, overriding the &lt;code&gt;clone&lt;/code&gt; and &lt;code&gt;dup&lt;/code&gt; methods, and is thread safe. The library file itself contains a bunch of examples of its usage, and those interested should definitely read through it.&lt;/p&gt;

&lt;p&gt;One thing to note about these implementations is that the instance method takes no arguments, so none are passed on to the object's constructor. This makes sense because the first time instance is called those will be the arguments used for this global instance. Setters are typically more appropriate for most singletons.&lt;/p&gt;

&lt;p&gt;Since singletons are global in nature setters should be at the class level. As an extra bonus here's the implementation of the class level &lt;code&gt;attr_&lt;/code&gt; methods to generate the vanilla getter/setter methods (stolen from &lt;a href="http://www.rubyonrails.org"&gt;Rails&lt;/a&gt;).&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Class&lt;/span&gt; &lt;span class="comment"&gt;# :nodoc:&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;cattr_reader&lt;/span&gt;&lt;span class="punct"&gt;(*&lt;/span&gt;&lt;span class="ident"&gt;syms&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;syms&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;flatten&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;sym&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;class_eval&lt;/span&gt;&lt;span class="punct"&gt;(&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="constant"&gt;EOS&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;__FILE__&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;__LINE__&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;span class="string"&gt;
        unless defined? @@&lt;span class="expr"&gt;#{sym}&lt;/span&gt;
          @@&lt;span class="expr"&gt;#{sym}&lt;/span&gt; = nil
        end

        def self.&lt;span class="expr"&gt;#{sym}&lt;/span&gt;
          @@&lt;span class="expr"&gt;#{sym}&lt;/span&gt;
        end

        def &lt;span class="expr"&gt;#{sym}&lt;/span&gt;
          @@&lt;span class="expr"&gt;#{sym}&lt;/span&gt;
        end
&lt;/span&gt;&lt;span class="constant"&gt;      EOS&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;cattr_writer&lt;/span&gt;&lt;span class="punct"&gt;(*&lt;/span&gt;&lt;span class="ident"&gt;syms&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;syms&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;flatten&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;sym&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;class_eval&lt;/span&gt;&lt;span class="punct"&gt;(&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="constant"&gt;EOS&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;__FILE__&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;__LINE__&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;span class="string"&gt;
        unless defined? @@&lt;span class="expr"&gt;#{sym}&lt;/span&gt;
          @@&lt;span class="expr"&gt;#{sym}&lt;/span&gt; = nil
        end

        def self.&lt;span class="expr"&gt;#{sym}&lt;/span&gt;=(obj)
          @@&lt;span class="expr"&gt;#{sym}&lt;/span&gt; = obj
        end

        def &lt;span class="expr"&gt;#{sym}&lt;/span&gt;=(obj)
          @@&lt;span class="expr"&gt;#{sym}&lt;/span&gt; = obj
        end
&lt;/span&gt;&lt;span class="constant"&gt;      EOS&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;cattr_accessor&lt;/span&gt;&lt;span class="punct"&gt;(*&lt;/span&gt;&lt;span class="ident"&gt;syms&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;cattr_reader&lt;/span&gt;&lt;span class="punct"&gt;(*&lt;/span&gt;&lt;span class="ident"&gt;syms&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;cattr_writer&lt;/span&gt;&lt;span class="punct"&gt;(*&lt;/span&gt;&lt;span class="ident"&gt;syms&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now we can create a more realistic singleton:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;    
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;singleton&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;JimmyGrimble&lt;/span&gt;
  &lt;span class="ident"&gt;include&lt;/span&gt; &lt;span class="constant"&gt;Singleton&lt;/span&gt;
  &lt;span class="ident"&gt;cattr_reader&lt;/span&gt; &lt;span class="symbol"&gt;:boots&lt;/span&gt;
  &lt;span class="ident"&gt;cattr_accessor&lt;/span&gt; &lt;span class="symbol"&gt;:football&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <pubDate>Tue, 31 Oct 2006 14:26:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:9087a930-fcc2-46d1-9852-37f5528f4c57</guid>
      <author>chris.a.williams@gmail.com (Chris)</author>
      <link>http://cwilliams.textdriven.com/articles/2006/10/31/patterns-in-ruby-singleton-pattern</link>
      <category>Programming</category>
      <category>Ruby</category>
      <category>design</category>
      <category>patterns</category>
      <category>ruby</category>
      <category>singleton</category>
      <category>programming</category>
    </item>
    <item>
      <title>Patterns in Ruby: Decorator Pattern</title>
      <description>&lt;p&gt;I've been a fan of the work that was done by the Gang of Four on &lt;a href="http://www.amazon.com/gp/product/0201633612?ie=UTF8&amp;amp;tag=latetothepart-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0201633612"&gt;Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley Professional Computing Series)&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=latetothepart-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0201633612" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;, Martin Fowler's &lt;a href="http://www.amazon.com/gp/product/0201485672?ie=UTF8&amp;amp;tag=latetothepart-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0201485672"&gt;Refactoring: Improving the Design of Existing Code&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=latetothepart-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0201485672" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt; and the bridge book by Joshua Kerievsky, &lt;a href="http://www.amazon.com/gp/product/0321213351?ie=UTF8&amp;amp;tag=latetothepart-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0321213351"&gt;Refactoring to Patterns&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=latetothepart-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0321213351" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;. 
I haven't seen a lot of information out there on how Ruby changes the game: ways to apply these patterns using Ruby idioms, new patterns that show up, patterns that fall away. So I've decided that as I go along I'll try and document the new twists as I see them.&lt;/p&gt;

&lt;p&gt;Today's article is the twist on the &lt;a href="http://www.exciton.cs.rice.edu/JavaResources/DesignPatterns/DecoratorPattern.htm"&gt;Decorator pattern&lt;/a&gt;. The Decorator pattern wraps the original object in a new one which will add functionality to some of the methods and then delegate to the original object. The prototypical example is decorating a window object.&lt;/p&gt;

&lt;h2&gt;A Decorator Example&lt;/h2&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_java "&gt;public interface Window {
  public void draw();
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In Java, we'd probably use a decorator to add scroll bars.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_java "&gt;public Class VerticalScrollWindow implements Window {
  private Window window;

  public VerticalScrollWindow(Window window) {
    this.window = window;
  }

  public void draw() {
    drawScrollBar();
    window.draw();
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The basic concept is that we'll usually want to be adding some behavior around a particular method call to extend behavior, while retaining the same interface.&lt;/p&gt;

&lt;h2&gt;Ruby&lt;/h2&gt;

&lt;p&gt;In ruby, we have a number of options to achieve this pattern. First, let's define our original Window in Ruby code:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Window&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;draw&lt;/span&gt;
    &lt;span class="comment"&gt;# do some drawing here...&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Translating the pattern literally&lt;/h3&gt;

&lt;p&gt;Given ruby's duck-typing nature, we could easily create a VerticalScrollWindow that wraps the original Window when we create the original window object, and pass that around. In fact we could patch only the single method and add a method_missing implementation that always delegated to the original Window.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;VerticalScrollWindow&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;window&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@window&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;window&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;draw&lt;/span&gt;
    &lt;span class="ident"&gt;draw_vertical_scrollbar&lt;/span&gt;
    &lt;span class="ident"&gt;window&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;draw&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;method_missing&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;method&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ident"&gt;block&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@window&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;method&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ident"&gt;block&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This approach could be evolved to a much higher level using method_missing tricks and dynamic modifications. One could create a generic Proxy class which took a target class and intercepted all method calls, executing pre- and post- method blocks for specific methods. I'll leave that as an exercise for the reader for now...&lt;/p&gt;

&lt;h3&gt;Using Alias&lt;/h3&gt;

&lt;p&gt;Another option we have is to "monkeypatch" the original class (or specific instances of it). The idea here is to rename the old implementation of the method, insert a new implementation and have that refer to the renamed original.&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Window&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;draw&lt;/span&gt;
    &lt;span class="comment"&gt;# do some drawing here...&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="comment"&gt;# some code...&lt;/span&gt;

  &lt;span class="keyword"&gt;alias&lt;/span&gt; &lt;span class="symbol"&gt;:original_draw&lt;/span&gt; &lt;span class="symbol"&gt;:draw&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;draw&lt;/span&gt;
    &lt;span class="ident"&gt;draw_vertical_scrollbar&lt;/span&gt;
    &lt;span class="ident"&gt;original_draw&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Building pre and post hooks&lt;/h3&gt;

&lt;p&gt;Our last option is to build pre and post method hooks into the original class definition. Obviously, this approach requires the original class' author to explicitly build in callback hooks. This approach can be found in Capistrano (you can add tasks which get executed before or after well known tasks), or in ActiveRecord (lifecycle type callbacks - i.e. before_save, after_destroy).&lt;/p&gt;

&lt;p&gt;This option is a bit more advanced and differs in the approach taken. To learn how Capistrano does it, dive into &lt;a href="http://dev.rubyonrails.org/svn/rails/tools/capistrano/lib/capistrano/actor.rb"&gt;capistrano/actor.rb&lt;/a&gt;, line 118. Each task is defined as a method which explicitly calls before and after methods if they exist.&lt;/p&gt;

&lt;p&gt;For ActiveRecord, please refer to &lt;a href="http://dev.rubyonrails.org/svn/rails/trunk/activerecord/lib/active_record/callbacks.rb"&gt;activerecord/callback.rb&lt;/a&gt;. ActiveRecord goes a little further by allowing class level methods to add pre- and post- code blocks to be executed which will be inherited down the class hierarchy. They also allow instance level methods to be defined for each hook which would not be inherited.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update&lt;/em&gt;: Francisco points us to a &lt;a href="http://www.lukeredpath.co.uk/2006/9/6/decorator-pattern-with-ruby-in-8-lines"&gt;great article on Decorator showing some other possible Ruby implementations&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Fri, 27 Oct 2006 17:08:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:f15c1b54-ff82-4082-b570-7488baf649c9</guid>
      <author>chris.a.williams@gmail.com (Chris)</author>
      <link>http://cwilliams.textdriven.com/articles/2006/10/27/patterns-in-ruby-template-method</link>
      <category>Programming</category>
      <category>Ruby</category>
      <category>patterns</category>
      <category>ruby</category>
      <category>programming</category>
      <category>idioms</category>
    </item>
    <item>
      <title>Getting Capistrano to play with Oracle on Red Hat Enterprise Linux</title>
      <description>&lt;p&gt;I've been working on an internal project that connects to a legacy Oracle database. The process of getting the driver and client set up was a bit annoying, but I'd done it before and I managed to get through it again. (For those of you braving it, be sure you don't include a trailing slash on your ORACLE_HOME environment variable).&lt;/p&gt;

&lt;p&gt;The Oracle driver and client are like most Oracle products - unnecessarily complex. One of its requirements is that you set an ORACLE_HOME environment variable. I'd managed to do this and add it to my .bashrc file so that when I manually logged into the app server via SSH I could get the rails app up and running. The problems was that remotely deploying via &lt;a href="http://manuals.rubyonrails.com/read/book/17"&gt;Capistrano&lt;/a&gt; was causing errors - anything that loaded the rails framework, and therefore the Oracle driver, would die with a stack trace about an undefined method. Luckily in my past troubles with the driver, I knew that meant that it didn't have the ORACLE_HOME environment variable set.&lt;/p&gt;

&lt;p&gt;In case anyone else is running into this (or I do again), here's a patch:&lt;/p&gt;

&lt;p&gt;First, add the following to your deploy.rb recipe:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;set :use_sudo, false
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next, modify your capistrano/actor.rb file to force all run commands through bash with BASH_ENV set:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;alias :run_without_env :run
def run(cmd, options={}, &amp;amp;block)
  cmd = &amp;lt;&amp;lt;-CMD
  BASH_ENV=.bashrc /bin/bash -c -- "#{cmd}"
  CMD
  run_without_env cmd, options, &amp;amp;block
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These two changes will force the environment to be loaded and also make all command be run as the original user (which should have rights to do so).&lt;/p&gt;

&lt;p&gt;You can read more about it &lt;a href="http://groups-beta.google.com/group/capistrano/browse_thread/thread/2afdf5f09482cde3"&gt;on the Google group for Capistrano&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Fri, 27 Oct 2006 15:29:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:dc3e923c-025d-4457-961f-688ced4f0d77</guid>
      <author>chris.a.williams@gmail.com (Chris)</author>
      <link>http://cwilliams.textdriven.com/articles/2006/10/27/getting-capistrano-to-play-with-oracle-on-red-hat-enterprise-linux</link>
      <category>Programming</category>
      <category>Ruby</category>
      <category>raisl</category>
      <category>deployment</category>
      <category>capistrano</category>
      <category>oracle</category>
      <category>redhat</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
