<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>require 'brain'</title>
	<atom:link href="http://szeryf.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://szeryf.wordpress.com</link>
	<description>The blog with the bug.</description>
	<lastBuildDate>Fri, 17 Jul 2009 10:39:07 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='szeryf.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/79fcb6ce01512e0455936969e753f53b?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>require 'brain'</title>
		<link>http://szeryf.wordpress.com</link>
	</image>
			<item>
		<title>The simplest way to set-up a &#8220;we&#8217;ll be back shortly&#8221; page</title>
		<link>http://szeryf.wordpress.com/2009/07/10/simplest-way-to-set-up-a-well-be-back-shortly-page/</link>
		<comments>http://szeryf.wordpress.com/2009/07/10/simplest-way-to-set-up-a-well-be-back-shortly-page/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 15:29:16 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[503]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[seo]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=206</guid>
		<description><![CDATA[If you&#8217;re going to have to stop your site for a maintenance or deploy break and care about your users (and SEO!), you should setup a custom 503 page. AskApache provides some documentation on this, but the examples require creating a PHP page. One of the commenters proposed a non-PHP version, but it&#8217;s complicated and [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=206&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>If you&#8217;re going to have to <strong>stop your site for a maintenance or deploy break</strong> and care about your users (and <a href="http://en.wikipedia.org/wiki/Search_engine_optimization" title="Search engine optimization - Wikipedia, the free encyclopedia">SEO</a>!), you should setup a <strong>custom <a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes" title="Wikipedia Entry: List of HTTP status codes">503</a> page</strong>. <a href="http://www.askapache.com/" title="AskApache - Crazy Advanced Web Development for server admins, WordPress bloggers, programmers, and hackers with topics and tools for Htaccess Rewrites, Linux and bash, PHP networking with cURL, SEO.">AskApache</a> provides <a href="http://www.askapache.com/htaccess/503-service-temporarily-unavailable.html" title="503 Status Code Search Engine SEO">some documentation on this</a>, but the examples require creating a PHP page. One of the commenters proposed a non-PHP version, but it&#8217;s complicated and didn&#8217;t work for me.</p>
<p>So, this is the <strong>simplest way to set-up a custom &#8220;we&#8217;ll be back shortly&#8221; error page in Apache 2</strong> that also tells <a href="http://en.wikipedia.org/wiki/Googlebot" title="Googlebot - Wikipedia, the free encyclopedia">Googlebots</a> to retry after 1 hour:</p>
<pre class="brush: bash;">
ErrorDocument 503 /503.html
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/503.html$
Header always set Retry-After &quot;3600&quot;
RewriteRule .* - [R=503]
</pre>
<p>Read on for explanation and a more advanced example.</p>
<p><span id="more-206"></span></p>
<p>The above lines should be placed in you Apache&#8217;s site config file (e.g. <code>/etc/apache2/vhosts.d/&lt;your-site-name&gt;_vhost.conf</code>) somewhere under <code>DocumentRoot</code> directive. The first line sets a custom file for HTTP 503 status. The path you provide here is <strong>relative to <code>DocumentRoot</code></strong>, so if you have: </p>
<pre class="brush: bash;">
DocumentRoot /var/sites/my_site/current/public
ErrorDocument 503 /503.html
</pre>
<p>then the file should be at <code>/var/sites/my_site/current/public/503.html</code>. Having a regular HTML means that you do not need <strong>anything except Apache itself to serve it</strong>. Inside it you can provide a message about the cause of the break and when you expect your site to be back up.</p>
<p>Next line (line #2 in first example) turns the <a href="http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html" title="Apache module mod_rewrite">RewriteEngine</a> on, which is needed to process the following directives. Line #3 excludes from processing all the requests that go to our 503 page. Without it we would get an endless loop of redirections (which would not be endless in Apache, of course, but after exceeding the redirection limit would cause an error instead of producing the page). </p>
<p>Line #4 sets Retry-After header for bots, which is set here for <a href="http://wiki.answers.com/Q/How_many_minutes_are_in_3600_seconds" title="WikiAnswers - How many minutes are in 3600 seconds">3600 seconds</a>. If you expect your break to be much shorter, you can use a lower value. The last line sets a 503 response for all requests that made it up to here (i.e. not excluded by line #2). </p>
<h2>Let the developers in</h2>
<p>Often you need to allow some people (the developers or the client) to <strong>play with site even if it&#8217;s unavailable</strong> to the rest of the Internet. To do so, you can exclude them from getting the 503 page by <strong>entering their IPs</strong>:</p>
<pre class="brush: bash;">
ErrorDocument 503 /503.html
RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^1.2.3.4$
RewriteCond %{REQUEST_URI} !^/503.html$
Header always set Retry-After &quot;3600&quot;
RewriteRule .* - [R=503]
</pre>
<p>The only thing new here is line #3, which excludes all requests coming from IP 1.2.3.4. You can use this directive as many times as you need.</p>
<h2>Troubleshooting</h2>
<p>If the above doesn&#8217;t work, first try following:</p>
<ul>
<li><strong>Double-check</strong> the 503 file location.</li>
<li>Assure that the owner of apache process can <strong>access and read this file</strong>.</li>
<li>Make sure that you have <strong>mod_headers and mod_rewrite activated</strong>.</li>
</ul>
 Tagged: 503, apache, mod_rewrite, seo <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/206/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/206/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/206/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/206/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/206/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/206/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=206&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2009/07/10/simplest-way-to-set-up-a-well-be-back-shortly-page/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>
	</item>
		<item>
		<title>A very simple persistent consumer-producer queue</title>
		<link>http://szeryf.wordpress.com/2009/06/17/a-very-simple-persistent-consumer-producer-queue/</link>
		<comments>http://szeryf.wordpress.com/2009/06/17/a-very-simple-persistent-consumer-producer-queue/#comments</comments>
		<pubDate>Wed, 17 Jun 2009 14:57:29 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[queue]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=202</guid>
		<description><![CDATA[This is my take on implementing a very simple persistent consumer-producer style queue using database table. The producers insert records to the table and consumers process them. There can be many producers and/or consumers working simultaneously. They can be separate processes or threads. There is no explicit locking.

First, a disclaimer: if you want a robust, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=202&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>This is my take on implementing a very simple <strong>persistent consumer-producer style queue</strong> using database table. The producers insert records to the table and consumers process them. There can be many producers and/or consumers working <strong>simultaneously</strong>. They can be separate processes or threads. There is no <strong>explicit locking</strong>.</p>
<p><span id="more-202"></span></p>
<p>First, a disclaimer: if you want a robust, stable and efficient queue, you should probably use a <a href="http://activemq.apache.org/" title="Apache ActiveMQ -- Index">full fledged</a> <a href="http://www.rubyinside.com/starling-and-rudeq-persistent-ruby-queues-958.html" title="Starling: A Ruby Persistent Queue Server That Speaks Memcached">queue mechanism</a>. The following code works with <a href="http://rubyonrails.org/" title="Ruby on Rails">Ruby on Rails</a> and <a href="http://www.mysql.com/">MySQL</a>.</p>
<p>The queue table should contain two additional columns that will be used by the queue mechanism: <code>STATUS</code> and <code>PID</code>. The <code>STATUS</code> column defines a processing status for each record &#8212; we need at least three:</p>
<pre class="brush: ruby;">
class Thing &lt; ActiveRecord::Base
  STATUS_READY       = 1
  STATUS_IN_PROGRESS = 2
  STATUS_DONE        = 3
  ...
</pre>
<p><code>STATUS_READY</code> means that the record is ready for processing by a consumer, <code>STATUS_IN_PROGRESS</code> is set when a consumer is working on this record and after that it&#8217;s <code>STATUS_DONE</code>. Alternatively, the consumer could just remove the record, it doesn&#8217;t matter for the algorithm.</p>
<p>The <code>PID</code> column is the key to this concept. I assume that each consumer can be identified with a <strong>unique number</strong>. If you use separate processes, this can be the operating system&#8217;s PID (<code>$$</code> in Ruby). For threads, you can use <code>Thread.current.object_id</code>. If none of these is available you get any number for each customer as long as your scheme guarantees that each number will be unique across all simultaneously working consumers.</p>
<p>The producers part in this algorithm is trivial: they just have to insert records with <code>STATUS_READY</code>. </p>
<p>The queue mechanism must ensure that each record will be <strong>processed by only one consumer</strong>. That&#8217;s what the <code>PID</code> is used for:</p>
<pre class="brush: ruby;">
class Thing &lt; ActiveRecord::Base
  ...
  def self.get_for_processing pid
    update_all(
      { :status =&gt; STATUS_IN_PROGRESS,
           :pid =&gt; pid },
      { :status =&gt; STATUS_READY },
      { :limit  =&gt; 1 })
    find_by_status_and_pid STATUS_IN_PROGRESS, pid
  end
  ...
</pre>
<p>The above method first updates one record from <code>STATUS_READY</code> to <code>STATUS_IN_PROGRESS</code> and sets <code>PID</code> column to given value. This means that the record is reserved for the consumer identified by this <code>PID</code>. Then the reserved record is returned by <code>find_by_status_and_pid</code> call. This is equivalent to issuing following SQL queries:</p>
<pre class="brush: sql;">
UPDATE things
   SET status = &lt;STATUS_IN_PROGRESS&gt;,
       pid    = &lt;pid&gt;
 WHERE status = &lt;STATUS_READY&gt;
 LIMIT 1;

SELECT *
  FROM things
 WHERE status = &lt;STATUS_IN_PROGRESS&gt;
   AND pid    = &lt;pid&gt;;
</pre>
<p>The <code>UPDATE</code> is <strong>atomic</strong> so there should be no collisions. It reserves one record if there are any available. The reserved record will not be reserved by any other consumer.</p>
<p>One important thing: each consumer must <strong>change the status of processed record</strong> to <code>STATUS_DONE</code> (or remove it) before it asks for another one. Otherwise the <code>find_by_status_and_pid</code> will return the same record over and over again (although <code>update_all</code> will reserve another record with each call).</p>
<p>When there are no more records to be processed, <code>get_for_processing</code> returns <code>nil</code>. It&#8217;s up to consumer to decide what to do then (wait, raise an exeception, etc.)</p>
<p>If you want the records processed in an order other than default (which is lowest-id-first for MySQL), you can use <code>:order</code> clause, for example to implement a <a href="http://en.wikipedia.org/wiki/LIFO_(computing)">LIFO queue</a>:</p>
<pre class="brush: ruby;">
class Thing &lt; ActiveRecord::Base
  ...
  def self.get_for_processing pid
    update_all(
      { :status =&gt; STATUS_IN_PROGRESS,
           :pid =&gt; pid },
      { :status =&gt; STATUS_READY },
      { :limit  =&gt; 1,
        :order  =&gt; 'created_at asc' })
    find_by_status_and_pid STATUS_IN_PROGRESS, pid
  end
  ...
</pre>
 Tagged: queue, sql <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/202/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/202/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/202/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=202&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2009/06/17/a-very-simple-persistent-consumer-producer-queue/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>
	</item>
		<item>
		<title>Finally getting GetText to work with Rails 2.2</title>
		<link>http://szeryf.wordpress.com/2009/03/07/finally-getting-gettext-to-work-with-rails-22/</link>
		<comments>http://szeryf.wordpress.com/2009/03/07/finally-getting-gettext-to-work-with-rails-22/#comments</comments>
		<pubDate>Fri, 06 Mar 2009 23:13:58 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[gettext]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=165</guid>
		<description><![CDATA[I18n layer, introduced in Rails 2.2, is said to be &#8220;the simplest thing that ever could work&#8221;. Too bad they didn&#8217;t go for &#8220;the simplest thing that could be practical to use&#8221;. These two can be very far apart. I have a hard time imagining a real-world app using only bare Rails&#8217; I18n engine.
Another unpleasant thing [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=165&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I18n layer, introduced in Rails 2.2, is said to be <a href="http://www.artweb-design.de/2008/7/18/finally-ruby-on-rails-gets-internationalized">&#8220;the simplest thing that ever could work&#8221;</a>. Too bad they didn&#8217;t go for &#8220;the simplest thing that could be practical to use&#8221;. These two can be very far apart. I have a hard time imagining a real-world app using only bare Rails&#8217; I18n engine.</p>
<p>Another unpleasant thing is that Rails 2.2 broke GetText compatibility, which prevents many projects from migrating to Rails 2.2 or later versions.</p>
<p>Well, not anymore. Thanks to clever guys <a href="http://github.com/mutoh">Masao Mutoh</a> and <a href="http://github.com/grosser">Michael Grosser</a>, it&#8217;s finally possible to get Rails 2.2 running with GetText. Read on for details.<br />
<span id="more-165"></span><br />
This post is only a compilation of information that can be found at <a href="http://github.com/mutoh/gettext/tree/master">http://github.com/mutoh/gettext/tree/master</a>, <a href="http://github.com/grosser/fast_gettext/tree/master">http://github.com/grosser/fast_gettext/tree/master</a>, <a href="http://github.com/grosser/gettext_i18n_rails/tree/master">http://github.com/grosser/gettext_i18n_rails/tree/master</a> and some other pages. These are by all means excellent pages, yet at some places imprecise or contradicting each other. It took me quite some time to make it work together, hence this post.</p>
<p>Warning: I assume basic knowledge of how GetText is used in Rails project, what are .po and .mo files etc. This post is not a tutorial on using GetText in general. You can find excellent tutorials by Masao Mutoh at <a href="http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html">http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html</a>.</p>
<h1>Installing</h1>
<h2>GNU gettext</h2>
<p>First, install a version of <a href="http://www.gnu.org/software/gettext/gettext.html">GNU gettext</a> in a version suitable for your machine (Mutoh&#8217;s page says version 0.10.35 or later, at this moment the current stable version is 0.17 and for MSWin you can use precompiled version 0.14.4 from <a href="http://gnuwin32.sourceforge.net/packages/gettext.htm">GnuWin32 project</a>). Make sure gettext&#8217;s bin directory is added to your <code>$PATH</code>!</p>
<h2>Racc</h2>
<p><a href="http://www.ruby-lang.org/raa/list.rhtml?name=racc">Racc</a> is Ruby yacc, i.e. a parser generator. I&#8217;m not sure if it&#8217;s necessary, so you can skip it at your own risk. If you decide to install it, download <a href="http://i.loveruby.net/archive/racc/racc-1.4.5-all.tar.gz">http://i.loveruby.net/archive/racc/racc-1.4.5-all.tar.gz</a>, untar and follow instructions in README.</p>
<h2>Gems</h2>
<p>Add following to your <code>config/environment.rb</code>:</p>
<pre class="brush: ruby;">
Rails::Initializer.run do |config|
  #...
  config.gem &quot;locale&quot;
  config.gem &quot;grosser-gettext&quot;,
     :version =&gt; '2.0.0', :lib =&gt; 'gettext', :source =&gt; &quot;http://gems.github.com&quot;
  config.gem &quot;grosser-fast_gettext&quot;,
     :version =&gt; '0.2.8', :lib =&gt; 'fast_gettext', :source =&gt; &quot;http://gems.github.com&quot;
end
</pre>
<p>and run</p>
<pre>rake gems:install</pre>
<p>If anything fails, try installing manually, i.e. with</p>
<pre>sudo gem install ...</pre>
<p><strong>Warning:</strong> installing GetText 2.0 gem breaks earlier versions of GetText gem you might have installed. You can probably get the following to work with GetText 1.93, but I didn&#8217;t try it.</p>
<h2>gettext_i18n_rails plugin</h2>
<p>Install it with</p>
<pre>script/plugin install git://github.com/grosser/gettext_i18n_rails.git</pre>
<h1>Configuring</h1>
<h2>Initialization</h2>
<p>Create a new file <code>config/initializers/fast_gettext.rb</code> and put this in it:</p>
<pre class="brush: ruby;">
FastGettext.add_text_domain 'app',
    :path =&gt; File.join(RAILS_ROOT, 'locale')
</pre>
<p>(or stick it at the end of <code>config/environment.rb</code> if you&#8217;re lazy).</p>
<p><code>RAILS_ROOT/locale</code> is where GetText assumes to find its .po and .mo files and it&#8217;s better to leave it this way. The text domain name (<code>'app'</code> above) can be any other name &#8212; preferably the name of your project &#8212; but remember to change it in the following examples, too.</p>
<h2>ApplicationController</h2>
<p>Add this to your <code>ApplicationController</code>:</p>
<pre class="brush: ruby;">
  include FastGettext::Translation
  before_filter :set_gettext_locale
protected
  def set_gettext_locale
    FastGettext.text_domain = 'app'
    FastGettext.available_locales = ['en','pl'] #all you want to allow
    super
  end
</pre>
<p>Line 1 makes all the GetText functions (the <code>_</code>, <code>n_</code>, <code>N_</code> etc.) available to your controllers. Line 2 installs a filter to setup FastGettext for each request. Remember to edit the list of available locales in line 6. Finally, the <code>super</code> call in line sets the <code>FastGettext.locale</code> based on:</p>
<ul>
<li><code>params[:locale]</code>,</li>
<li><code>session[:locale]</code>,</li>
<li><code>cookies[:locale]</code>,</li>
<li>request header <code>HTTP_ACCEPT_LANGUAGE</code> (in that order)</li>
</ul>
<p>Once determined, locale is saved in <code>session[:locale]</code>.</p>
<h2>ApplicationHelper</h2>
<p>In order to have GetText functions available in your helpers and views, add this to <code>app/helpers/application_helper.rb</code>:</p>
<pre class="brush: ruby;">
  include FastGettext::Translation
</pre>
<h2>TestHelper/SpecHelper</h2>
<p>Add this to your <code>test/test_helper.rb</code> (or <code>spec/spec_helper.rb</code>) to make your tests/specs work:</p>
<pre class="brush: ruby;">
FastGettext.text_domain = 'app'
FastGettext.available_locales = ['en','pl'] #all you want to allow
</pre>
<h2>Haml support</h2>
<p>GetText does not support Haml &#8216;out of the box&#8217;, so if you happen to use Haml, there&#8217;s one more thing to configure (otherwise you can skip this step). Create a new file <code>lib/haml_parser.rb</code> and put this in it:</p>
<pre class="brush: ruby;">
require 'gettext/utils'
require 'gettext/tools/rgettext'

begin
  require &quot;#{RAILS_ROOT}/vendor/plugins/haml/lib/haml&quot;
rescue LoadError
  require 'haml'  # From gem
end

module HamlParser
  module_function

  def target?(file)
    File.extname(file) == '.haml'
  end

  def parse(file, ary = [])
    haml = Haml::Engine.new(IO.readlines(file).join)
    code = haml.precompiled.split(/$/)
    GetText::RubyParser.parse_lines(file, code, ary)
  end
end
GetText::RGetText.add_parser(HamlParser)
</pre>
<p>Now GetText is able to parse Haml, too!</p>
<h1>Running</h1>
<p>You&#8217;re finally ready to test if your configuration really works. Add something like:</p>
<pre class="brush: ruby;">
&lt;%= _('Hello World') %&gt;
</pre>
<p>in any of your views. Then run:</p>
<blockquote><p><code>rake gettext:find</code></p></blockquote>
<p>If you get an error</p>
<blockquote><p><code>Could not find RubyGem gettext (&gt;= 2.0.0)</code></p></blockquote>
<p>edit <code>vendor/plugins/gettext_i18n_rails/tasks/gettext_rails_i18n.rake</code> and comment out the line 3 that says</p>
<pre class="brush: ruby;">
gem 'gettext', '&gt;=2.0.0'
</pre>
<p>(you already have gettext gem, but it&#8217;s called grosser-gettext).</p>
<p>On successful run you should get a message that GetText created a template file <code>locales/app.pot</code>. Now create subdirectories in <code>locales/</code> for each locale you want to support and copy this file into it, changing the extension to <code>.po</code>. So, for English and Polish, you would do:</p>
<pre>$ mkdir en
$ cp app.pot en/app.po
$ mkdir pl
$ cp app.po pl/app.po</pre>
<p>After that, edit the .po files and provide translations of your text in respective languages (I assume you&#8217;re familiar with .po file format). Then:</p>
<pre>$ rake gettext:pack
locale/en/app.po -&gt; locale/en/LC_MESSAGES/app.mo ... Done.
locale/pl/app.po -&gt; locale/pl/LC_MESSAGES/app.mo ... Done.</pre>
<blockquote><p>As a side note, you might want to add <code>locale/*/LC_MESSAGES/*.mo</code> files to <code>.gitignore</code> or <code>svn:ignore</code> since they are generated by GetText but be sure to add any .po files you create to your code repository.</p></blockquote>
<p>Now, restart your web server (changes in .mo files are not automatically reloaded) and navigate to the page where you used the <code>_()</code> function. You should see your text translated to your default locale. If your application does not yet feature any elegant way to switch locale, add <code>?locale=..</code> to URL and reload. Your text should now be translated to the new language.</p>
<p>That&#8217;s all, folks. Hope it works for you. If you find anything missing or incorrect, please let me know.</p>
 Tagged: gettext, i18n, rails <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/165/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/165/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/165/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/165/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/165/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/165/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=165&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2009/03/07/finally-getting-gettext-to-work-with-rails-22/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>
	</item>
		<item>
		<title>Error while installing Postgresql 8.3 on Windows XP</title>
		<link>http://szeryf.wordpress.com/2009/02/22/error-while-installing-postgresql-83-on-windows-xp/</link>
		<comments>http://szeryf.wordpress.com/2009/02/22/error-while-installing-postgresql-83-on-windows-xp/#comments</comments>
		<pubDate>Sun, 22 Feb 2009 15:42:29 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[Solutions]]></category>
		<category><![CDATA[error.installing.runtimes]]></category>
		<category><![CDATA[installation]]></category>
		<category><![CDATA[one-click installer]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[scripting host]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=151</guid>
		<description><![CDATA[I tried to install PostgreSQL on Windows XP using &#8220;PostgreSQL One-Click Installer&#8221; and got a cryptic message box telling about &#8220;error.installing.runtimes&#8221;. Googling for this message yielded nothing helpful so I thought I&#8217;d post my solution of this problem. I checked Windows&#8217; Event Log and under System tab found a failure event from Windows Scripting Host [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=151&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I tried to install PostgreSQL on Windows XP using &#8220;PostgreSQL One-Click Installer&#8221; and got a cryptic message box telling about &#8220;error.installing.runtimes&#8221;. Googling for this message yielded nothing helpful so I thought I&#8217;d post my solution of this problem. I checked Windows&#8217; Event Log and under System tab found a failure event from Windows Scripting Host telling that, basically, I tried to run a script but the host is inactive.</p>
<p>Well, to tell the truth, I inactivated it myself, using the xp-antispy proggy. The solution is to run xp-antispy, find &#8220;Deactivate Scripting Host&#8221; under &#8220;Misceallaneous Settings&#8221; and turn it off (make it red). After that PostgreSQL installs without errors.</p>
<p>After installation you can deactivate Scripting Host again, it looks that it&#8217;s not needed once PostgreSQL is installed.</p>
 Tagged: error.installing.runtimes, installation, one-click installer, postgresql, scripting host, windows <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/151/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/151/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/151/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=151&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2009/02/22/error-while-installing-postgresql-83-on-windows-xp/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>
	</item>
		<item>
		<title>How to: turn off ANSI codes in Rails console</title>
		<link>http://szeryf.wordpress.com/2009/02/02/how-to-turn-off-ansi-codes-in-rails-console/</link>
		<comments>http://szeryf.wordpress.com/2009/02/02/how-to-turn-off-ansi-codes-in-rails-console/#comments</comments>
		<pubDate>Sun, 01 Feb 2009 22:34:33 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[console]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=143</guid>
		<description><![CDATA[Small tip: when you happen to be running Rails in a console that doesn&#8217;t understand ANSI codes (those pesky  ←[4;36;1m and ←[0;1m that clutter your display), like for example Windows&#8217; cmd, you can turn them off with:

if RUBY_PLATFORM =~ /mswin32/
  ActiveRecord::Base.colorize_logging = false
end

Put this in config/environments/development.rb and restart script/server.
Took me a while to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=143&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Small tip: when you happen to be running Rails in a console that doesn&#8217;t understand ANSI codes (those pesky <code> ←[4;36;1m</code> and <code>←[0;1m</code> that clutter your display), like for example Windows&#8217; <code>cmd</code>, you can turn them off with:</p>
<pre class="brush: ruby;">
if RUBY_PLATFORM =~ /mswin32/
  ActiveRecord::Base.colorize_logging = false
end
</pre>
<p>Put this in <code>config/environments/development.rb</code> and restart <code>script/server</code>.</p>
<p>Took me a while to find it, so I thought I&#8217;d post it for posterity :)</p>
 Tagged: console, ruby on rails <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/143/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=143&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2009/02/02/how-to-turn-off-ansi-codes-in-rails-console/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>
	</item>
		<item>
		<title>Launch first, audit later</title>
		<link>http://szeryf.wordpress.com/2008/11/07/launch-first-audit-later/</link>
		<comments>http://szeryf.wordpress.com/2008/11/07/launch-first-audit-later/#comments</comments>
		<pubDate>Fri, 07 Nov 2008 10:32:24 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[audit]]></category>
		<category><![CDATA[code quality]]></category>
		<category><![CDATA[software metrics]]></category>
		<category><![CDATA[startup]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=125</guid>
		<description><![CDATA[Some time ago my boss told me that two of his colleagues are building their top secret, Next-Big-Thing site in Rails. They asked him if we (the company) could audit their code. This struck me as a really strange thing to do, given they are nowhere near launching their site. I told my boss: &#8220;Sure, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=125&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Some time ago my boss told me that two of his colleagues are building their top secret, Next-Big-Thing site in Rails. They asked him if we (the company) could audit their code. This struck me as a really strange thing to do, given they are nowhere near launching their site. I told my boss: &#8220;Sure, we can audit their code, but do they really want to waste their money on this right now?&#8221;</p>
<p>Don&#8217;t get me wrong, I do care about code quality more than most programmers. I&#8217;m all for <a href="http://www.codeproject.com/KB/architecture/onunittesting.aspx" title="The benefits of automated unit testing. Free source code and programming help">automated</a> <a href="http://en.wikipedia.org/wiki/Unit_test" title="Unit testing - Wikipedia, the free encyclopedia">unit testing</a>, high <a href="http://en.wikipedia.org/wiki/Code_coverage" title="Code coverage - Wikipedia, the free encyclopedia">test coverage</a>, using <a href="http://en.wikipedia.org/wiki/Software_metric" title="Software metric - Wikipedia, the free encyclopedia">code metrics</a>, profiling, automating builds with <a href="http://martinfowler.com/articles/continuousIntegration.html" title="Continuous Integration">continuous integration</a> and so on. We practice most of these things here at <a href="http://jarorcon.pl">Jarorcon</a>. And I would be more than happy to examine someone&#8217;s code and point the problems in it (and get paid for it).</p>
<p><span id="more-125"></span></p>
<h2>Cost-benefit analysis</h2>
<p>But still, when you do these things (like maintaining 100% test coverage) you have to <strong>take both costs and benefits into account</strong>. You can&#8217;t get fanatic about it. If it&#8217;s easy and enjoyable for you, great. But if you spend several hours struggling to get that one last line of your code tested, you&#8217;re probably <strong>overdoing it</strong>. Ask yourself what is the cost of those hours of your work (in terms of your employer&#8217;s money or in terms of lost opportunities if working for yourself)? Is having <a href="http://www.infoq.com/news/2007/05/100_test_coverage" title="100% Test Coverage?">100% test coverage</a> going to benefit you more that it costs?</p>
<h2>The definition of success</h2>
<p>How do you <strong>define the success</strong> of the site you&#8217;re building? Is it great code quality? Is it 100% test coverage? I think it&#8217;s rather <strong>having many users that like the site</strong> or, even better, <strong>having many <em>paying</em> users</strong>. Do you think your users will appreciate the perfect quality of your code? I hate to say it but most of them couldn&#8217;t care less about it, as long as your site works reasonably fast and is reasonably stable. And if you&#8217;re motivated and competent enough, you&#8217;re going to make it.</p>
<h2>Launch first, worry later</h2>
<p>Launch first. Worry later. Make your code work. Make sure somebody is going to use it. Check if people like your idea. See whether <strong>you can get profitable</strong> from it. Then worry about auditing the quality of your code, optimizing its performance, beautifying the design, adding more features and so on. Why waste money on audits if you know that <a href="http://www.google.com/search?q=most+startups+fail" title="most startups fail - Google Search">most startups fail</a>? This is the same as <a href="http://en.wikipedia.org/wiki/Optimization_(computer_science)#When_to_optimize" title="Optimization (computer science)">premature optimization</a>. <strong>First make it work, then optimize</strong> (for performance or quality).</p>
<p>Of course, if you&#8217;re a beginner, there are many things that you could (or even should) do. <strong>Learn as much as you can</strong>. Read documentation, blogs, forums, books. Experiment. Ask for advice. Try to solve real problems (like: your site comes to a grinding halt with five concurrent users). Fix errors and bugs. Look for security vulnerabilities. Practice <a href="http://en.wikipedia.org/wiki/Test-driven_development" title="Test-driven development - Wikipedia, the free encyclopedia">TDD</a> or <a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development" title="Behavior Driven Development - Wikipedia, the free encyclopedia">BDD</a> if you feel like it. Set up continuous integration and measure test coverage if you care about it. But don&#8217;t overdo it. <strong>Don&#8217;t prematurely optimize for quality</strong>. Remember: your success will not depend on the quality of your code alone.</p>
<p>And just one thing: audit sounds very enterprisey. It&#8217;s extremely funny when a two-person startup asks for an audit.</p>
 Tagged: audit, code quality, software metrics, startup <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/125/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/125/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/125/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/125/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/125/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=125&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2008/11/07/launch-first-audit-later/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>
	</item>
		<item>
		<title>Relation from RailsConf Europe, day 3</title>
		<link>http://szeryf.wordpress.com/2008/09/14/relation-from-railsconf-europe-day-3/</link>
		<comments>http://szeryf.wordpress.com/2008/09/14/relation-from-railsconf-europe-day-3/#comments</comments>
		<pubDate>Sun, 14 Sep 2008 09:52:50 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[RailsConf]]></category>
		<category><![CDATA[RailsConf Europe]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=104</guid>
		<description><![CDATA[Welcome to the final part of my RailsConf Europe 2008 coverage. On the third day I attended Ruby and Rails Symposium: Versions, Implementations, and the Future, Genomes on Rails and Small Things, Loosely Joined and Written Fast. The keynote was a little bit disappointing, but the other talks were both inspiring, albeit in different ways.

Ruby [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=104&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Welcome to the final part of my <a href="http://en.oreilly.com/railseurope2008/public/content/home" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">RailsConf Europe 2008</a> coverage. On the third day I attended <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/4919" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">Ruby and Rails Symposium: Versions, Implementations, and the Future</a>, <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/3495" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">Genomes on Rails</a> and <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/3554" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">Small Things, Loosely Joined and Written Fast</a>. The keynote was a little bit disappointing, but the other talks were both inspiring, albeit in different ways.</p>
<p><span id="more-104"></span></p>
<h2>Ruby and Rails Symposium: Versions, Implementations, and the Futures</h2>
<p>David Black&#8217;s keynote, or a <a href="http://dablog.rubypal.com/2008/9/6/back-from-railsconf-europe-2008" title="DABlog  Back from RailsConf Europe 2008">Symposimi, as he called it</a>, started with a show of hands. David asked what version of Ruby are people using on their production site. Almost all of the audience raised hands for 1.8.6, I noticed only one guy using 1.8.7 and maybe two using 1.9.0. This is not that surprising as <a href="http://www.ruby-forum.com/topic/136553" title="Ruby 1.9.0 is released - Ruby Forum">1.9.0 is a &#8220;development release&#8221;</a>, not intended to be run in production environments. It&#8217;s more interesting why 1.8.7 didn&#8217;t achieve more popularity. It&#8217;s supposed to be <a href="http://www.ruby-lang.org/en/news/2008/05/31/ruby-1-8-7-has-been-released/" title="Ruby 1.8.7 has been released">stable, backwards compatible, has many bugfixes and some new features backported from 1.9.0</a>. There have been also <a href="http://www.ruby-lang.org/en/news/2008/08/08/multiple-vulnerabilities-in-ruby/" title="Multiple vulnerabilities in Ruby">many vulnerabilities</a> discovered in Ruby, so everybody should recently have installed some new version and why not 1.8.7? But I digress.</p>
<div id="attachment_113" class="wp-caption aligncenter" style="width: 457px"><a href="http://szeryf.files.wordpress.com/2008/09/p9040061.jpg"><img src="http://szeryf.files.wordpress.com/2008/09/p9040061.jpg?w=447&#038;h=298" alt="Live coding session during David Black&#39;s keynote" title="Live coding session during David Black&#39;s keynote" width="447" height="298" class="size-large wp-image-113" /></a><p class="wp-caption-text">Live coding session during David Black's keynote</p></div>
<p>David showed then some more prominent differences between 1.8.6 and 1.9 version in a live coding session. These included:</p>
<ul>
<li>differences in block parameters handling (1.9 doesn&#8217;t overwrite previously existing local variables when a block happens to have identically named parameters),</li>
<li>new lambda syntax, i.e. the <code>-&gt;</code> operator, which allows lambdas to have optional parameters as in <code>func = -&gt;(a,b=1){puts a + b}</code>,</li>
<li>enumerators,</li>
<li>new hash syntax: <code>{a: 1, b: 2, c: 3}</code> which is equivalent to <code>{:a=&gt;1, :b=&gt;2, :c=&gt;3}</code>, i.e. creates a hash with symbols as keys.</li>
</ul>
<p>This is hardly news for anybody not living under the rock for the last few months, there have been many announcements and blog posts on the upcoming features. I think it would be more interesting to hear something about Ruby 2.0.</p>
<h2>Genomes on Rails</h2>
<p><a href="http://www.greenisgood.co.uk/" title="software, science, etc">Matt Wood</a> started with introducing the <a href="http://www.sanger.ac.uk/" title="The Wellcome Trust Sanger Institute">Wellcome Trust Sanger Institute</a>, where he works. The institute was involved in <a href="http://en.wikipedia.org/wiki/Human_Genome_Project" title="Human Genome Project - Wikipedia, the free encyclopedia">Human Genome Project</a> and is currently running many other scientific projects about genomes, DNA and other things that generally require massive computation on even more massive data. </p>
<p>Human genome took 15 years to decode and was comparable with decoding a 3 billion letters message. The project costs were about $3 billion. To date they have decoded genomes of 40 species. They are also trying to find cures for various diseases, from diabetes to malaria. </p>
<p>Rails is used to power the web pages that provide access to research results. Matt told us that most of the models consist of &#8220;virtual fields&#8221;, that is key-value pairs stored in separate table. This is not that hard and that slow as it may seem and has several advantages, like the ability to automatically generate the UI based on the database contents. Since they query large tables in their Rails apps, they use their own plugin called <a href="http://github.com/mza/denormalizer/tree/master" title="mza's denormalizer at master &mdash; GitHub">denormalizer</a>.</p>
<div id="attachment_106" class="wp-caption alignright" style="width: 234px"><img src="http://szeryf.files.wordpress.com/2008/09/p9040067.jpg?w=224&#038;h=300" alt="Me, enjoying the desserts" title="Me, enjoying the desserts" width="224" height="300" class="size-medium wp-image-106" /><p class="wp-caption-text">Me, enjoying the desserts</p></div>
<p>At the end of the presentation somebody from the audience asked the question that I&#8217;m sure everybody wanted to ask: &#8220;Do you do any of those computations in Ruby?&#8221; &#8220;No.&#8221; Matt replied, &#8220;that would be crazy. The computations are done in C. Ruby (and Perl) are used to instrument the processes and for the web pages.&#8221; Be sure to check out <a href="http://www.slideshare.net/mza/genomes-on-rails-486498" title="Genomes On Rails">Matt&#8217;s presentation</a>.</p>
<h2>Advanced RESTful Rails</h2>
<p>This was the second talk by Ben Scofield that I have been to. I think it was very valuable for anyone doing RESTful applications in Rails. Ben started with showing some situations that might not be easy to handle RESTfully. These include singleton resources, namespaces, nesting, polymorphism and custom routes. </p>
<p>RESTful development consists of two steps: identifying resources and selecting methods to expose. Ben offered some tips for identifying resources. Firstly, <em>when in doubt add a resource</em>. It is better to have too many of them that too little. Secondly, <em>respect the middleman</em>. So, a many-to-many relation (like friendship) is almost certainly a resource, even if you don&#8217;t have a model for it. And lastly, <em>resources are not identical with models</em>. Most of the models are resources but not all resources have models.</p>
<p>In the next part, Ben showed some example solutions for things like password resets, homepages, previews (as in preview comment before posting), searching, wizards (multi-step actions), bulk actions (updating many resources at once) or transactions. Check out his <a href="http://www.culann.com/2008/09/and-session-aftermath" title="culann.com  &raquo; Blog Archive   &raquo; And&#8230; Session Aftermath">presentation</a> if you&#8217;re interested.</p>
<h2>Small Things, Loosely Joined and Written Fast</h2>
<p>This was one of most entertaining talks on the RailsConf. Justin Gehtland put on quite a show, with lost of running, waving hands and screaming (don&#8217;t be afraid, not <a href="http://www.youtube.com/watch?v=wvsboPUjrGc" title="YouTube - Steve Ballmer going crazy">Steve Ballmer style</a>). He had also very funny slides with references to Star Wars. He compared big, complicated applications with the Death Star: they are heavy, costly, have too many responsibilities and easily break. Then he showed the Rebel Fleet &#8211; a chaotic cloud of small, cooperating ships playing different roles. Of course, some of them can get hit but it&#8217;s much more difficult to destroy the whole fleet than one ship, even as big as the Death Star. And it&#8217;s easy to replace the small ships with new ones.</p>
<p>Justin proceeded then to show us what this &#8220;Rebel Fleet approach&#8221; could look like in case of Rails applications. His example was a simple students portal with two functions: lectures enroller and dormitory picker. Those two functions were implemented as separate Rails apps, sharing as little as possible (students data and their preferences). Justin also set up a Single Sign-On server for them (a RubyCAS server) and a message queue (ActiveMQ) for communication between the apps. If this sounds to you as interesting and inspiring as to me, be sure to check out <a href="http://blog.thinkrelevance.com/2008/9/3/small-things-loosely-joined-written-fast" title="Small Things, Loosely Joined, Written Fast">Justin&#8217;s blog entry</a> with code from the talk and setup instructions.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/szeryf.wordpress.com/104/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/szeryf.wordpress.com/104/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/104/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=104&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2008/09/14/relation-from-railsconf-europe-day-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>

		<media:content url="http://szeryf.files.wordpress.com/2008/09/p9040061.jpg?w=447" medium="image">
			<media:title type="html">Live coding session during David Black&#39;s keynote</media:title>
		</media:content>

		<media:content url="http://szeryf.files.wordpress.com/2008/09/p9040067.jpg?w=224" medium="image">
			<media:title type="html">Me, enjoying the desserts</media:title>
		</media:content>
	</item>
		<item>
		<title>Relation from RailsConf Europe 2008, day 2</title>
		<link>http://szeryf.wordpress.com/2008/09/07/relation-from-railsconf-europe-2008-day-2/</link>
		<comments>http://szeryf.wordpress.com/2008/09/07/relation-from-railsconf-europe-2008-day-2/#comments</comments>
		<pubDate>Sun, 07 Sep 2008 08:11:38 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[RailsConf]]></category>
		<category><![CDATA[RailsConf Europe]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=94</guid>
		<description><![CDATA[It seems that I got too carried away writing about DHH keynote and forgot to mention other session I&#8217;ve been to that day. The first one was Hacking the Mid-End: Unobtrusive Scripting and Advanced UI Techniques in Rails, then Rails Software Metrics and Modeling Denormalization &#8211; The Speed You Need, the Order You Crave. I&#8217;m [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=94&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>It seems that I got too carried away writing about DHH keynote and forgot to mention other session I&#8217;ve been to that day. The first one was <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/3545" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">Hacking the Mid-End: Unobtrusive Scripting and Advanced UI Techniques in Rails</a>, then <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/3394" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">Rails Software Metrics</a> and <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/3504" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">Modeling Denormalization &#8211; The Speed You Need, the Order You Crave</a>. I&#8217;m going to cover each one below.</p>
<p><span id="more-94"></span></p>
<h2>Hacking the Mid-End</h2>
<p>In <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/3545" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">Hacking the Mid-End: Unobtrusive Scripting and Advanced UI Techniques in Rails</a> Michael Bleigh argued that there is a growing area between back-end (which is Model &amp; Controller layers in MVC) and front-end (which is View) that he calls Mid-End. In most Web 2.0 applications, the architecture is really something like MVC+I, where I is for Interaction. This area contains all the non-trivial code in the presentation layer that usually can&#8217;t be done by HTML/CSS designers. This includes various AJAX calls, progress bars, fancy file uploaders, drag&#8217;n'drop support and so on. </p>
<div id="attachment_96" class="wp-caption alignright" style="width: 310px"><a href="http://szeryf.files.wordpress.com/2008/09/p9040073.jpg"><img src="http://szeryf.files.wordpress.com/2008/09/p9040073.jpg?w=300&#038;h=224" alt="RailsConf message board" title="RailsConf message board" width="300" height="224" class="size-medium wp-image-96" /></a><p class="wp-caption-text">RailsConf message board</p></div>
<p>Michael said that Mid-End developer facilitates cooperation between front-end and back-end, providing helpers and tools for the front-end designer and building on a structures provided by back-end developers. Mid-end developers goals are to make the application <em>Fast, Accessible, Intuitive, and Responsive</em>. Then he showed two examples of what he understands by that. The first was about making some slow action more responsive. In the original version after clicking the link the user had to wait about 10 seconds before the resulting page loaded.</p>
<p>Michael&#8217;s recipe was to make the link take the user to another page that displayed a warning that you might have to wait a little bit for the results. The page loaded the results in background using AJAX call and then displayed them. For the sake of accessibility, if JavaScript was unavailable, the page presented a link to &#8216;Continue&#8217;. </p>
<p>The second example was about making simple dynamic tabs. When user has JS enabled only one of the tabs is visible and clicking a tab header switches the visible part. With no JS all the information is displayed as a list of sections with headlines and clicking a tab header jumps to the appropriate section.</p>
<p>Be sure to check out <a href="http://intridea.com/2008/9/3/railsconf-europe-2008-hacking-the-mid-end" title="Hacking the Mid-End">Michael&#8217;s presentation</a> if you&#8217;re interested in mid-end and UJS (Unobtrusive JavaScript).</p>
<h2>Rails Software Metrics</h2>
<p>Next session was <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/3394" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">Rails Software Metrics</a>, presented by Roderick von Domburg. Roderick started with saying that he talks only about tools, not some prescribed best practices. The first tool he covered was, quite surprisingly, <code>rake stats</code>. The results provided by this tool are not very interesting as such, but the key here is that you should graph them over time to make them much more useful. </p>
<p>Roderick showed graphs of lines of code, test-to-code ratio, average methods and lines per class or average lines per methods, all provided by <code>rake stats</code>. Combining the graphs of these metrics may tell you many useful things about your code (you are testing too little or too much, your methods are too long) without installing any other tools.</p>
<p>The next tool covered was <a href="http://ruby.sadi.st/Flog.html" title="Confessions of a Ruby Sadist - sudo gem install flog">flog</a>, which measures code complexity. Flog works in a &#8220;decidedly unscientific&#8221; way, assigning arbitrarily chosen values to various constructs (6 points per <code>eval</code>, 1.2 point per <code>if</code>) and reporting totals and averages for your classes and methods. And again, while results of running flog once are useful (you can see whether there are methods that require immediate refactoring), it becomes really cool when graphed over time. You can observe negative tendencies and take countermeasures when appropriate.</p>
<div id="attachment_102" class="wp-caption alignleft" style="width: 250px"><a href="http://www.flickr.com/photos/x180/2824306247/in/set-72157607077916014/"><img src="http://szeryf.files.wordpress.com/2008/09/tshirt.jpg?w=240&#038;h=160" alt="One of the registration hostesses with the RailsConf Europe T-Shirt" title="One of the registration hostesses with the RailsConf Europe T-Shirt" width="240" height="160" class="size-full wp-image-102" /></a><p class="wp-caption-text">One of the registration hostesses with the RailsConf Europe T-Shirt</p></div>
<p><a href="http://eigenclass.org/hiki.rb?rcov" title="code coverage for Ruby">Rcov</a> was next but since we use it in all our projects, there was nothing new for me. I&#8217;m always surprised when people say (like Roderick did) that it&#8217;s really hard to get 100% code coverage (I sometimes suspect they didn&#8217;t really try it, they just think it&#8217;s too hard) and you really shouldn&#8217;t try too hard because it&#8217;s not worth it and 100% code coverage doesn&#8217;t prove anything anyway. They say that with 100% code coverage you test many trivial pieces of code that are not worth it anyway while many other non-trivial pieces are covered only accidentally. </p>
<p>This is mostly true except for the &#8220;it&#8217;s too hard&#8221; part. My team uses TDD methodology and we have no problems with achieving 100% code coverage. We don&#8217;t find it too hard or too wasteful either. Oh, and by the way, it&#8217;s much easier to keep coverage at 100% if you have 100% from the start.</p>
<p>Roderick then covered briefly <a href="http://ruby.sadi.st/Heckle.html" title="Confessions of a Ruby Sadist - sudo gem install heckle">heckle</a>, which mutates your code and checks if tests fail. Heckle is still in experimental phase and it&#8217;s not something you would want to run on every build but it&#8217;s fun to play with, nonetheless. The next tool was <a href="http://saikuro.rubyforge.org/" title="A Cyclomatic Complexity Analyzer">saikuro</a>, which is a cyclomatic complexity analyzer. It&#8217;s similar to flog but has a more scientific approach. It also generates nice HTML reports similar to rcov&#8217;s, so you can inspect any code that generates warnings.</p>
<p>The last tool covered was <a href="http://metric-fu.rubyforge.org/" title="A Rails Plugin for Easy Metric Report Generation">metric_fu</a>, a plugin (or set of rake tasks to be precise) for <a href="http://cruisecontrolrb.thoughtworks.com/" title="CruiseControl.rb">CruiseControl.rb</a> that runs all or selected metrics on your projects. I&#8217;m definitely going to have a look at it.</p>
<h2>Modeling Denormalization</h2>
<p>In <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/3504" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">Modeling Denormalization &#8211; The Speed You Need, the Order You Crave</a> <a href="http://www.dweebd.com/" title="duncanbeevers' dweebd">Duncan Beevers</a> from <a href="http://www.kongregate.com/" title="Play free games online">Kongregate</a> talked about how to use denormalization techniques to make your data retrievable faster. Denormalization means duplicating data from one model to another and storing the results of each calculation in the database once you calculate it. This technique is present in Rails in form of <a href="http://wiki.rubyonrails.org/rails/pages/MagicFieldNames" title="MagicFieldNames in Ruby on Rails">counter caches</a>.</p>
<p>If your application is write-heavy, you should not go overboard with adding index. Each index slows down writes. Another advice was that real tables with calculated data are better than triggers and views. The problem with triggers is that one update can fire several triggers and you don&#8217;t have control about it. It becomes a real issue when you have 20,000 users updating their statistics each second (if I remember the number Duncan gave right). In this case batch processing is much better. </p>
<p>Duncan&#8217;s presentation had a little unexpected ending because he fainted after showing the last slide. Some people from the first rows helped him up and gave him a glass of water and he was OK in a minute. That accident awarded him much more cheerful reception from the audience.</p>
<p>I don&#8217;t know if this is of any interest to you, but most of this article was written while traveling back from Berlin to Wrocław after the conference. Ah, the joys of modern technology.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/szeryf.wordpress.com/94/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/szeryf.wordpress.com/94/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/94/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/94/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/94/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/94/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/94/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/94/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/94/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/94/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/94/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/94/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=94&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2008/09/07/relation-from-railsconf-europe-2008-day-2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>

		<media:content url="http://szeryf.files.wordpress.com/2008/09/p9040073.jpg?w=300" medium="image">
			<media:title type="html">RailsConf message board</media:title>
		</media:content>

		<media:content url="http://szeryf.files.wordpress.com/2008/09/tshirt.jpg" medium="image">
			<media:title type="html">One of the registration hostesses with the RailsConf Europe T-Shirt</media:title>
		</media:content>
	</item>
		<item>
		<title>Relation from RailsConf Europe 2008, DHH keynote</title>
		<link>http://szeryf.wordpress.com/2008/09/04/relation-from-railsconf-europe-2008-dhh-keynote/</link>
		<comments>http://szeryf.wordpress.com/2008/09/04/relation-from-railsconf-europe-2008-dhh-keynote/#comments</comments>
		<pubDate>Thu, 04 Sep 2008 08:16:23 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[DHH keynote]]></category>
		<category><![CDATA[RailsConf]]></category>
		<category><![CDATA[RailsConf Europe]]></category>
		<category><![CDATA[legacy software]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=64</guid>
		<description><![CDATA[The second day of RailsConf Europe 2008 started with David Heinemeier Hansson&#8217;s keynote on legacy software and was by far the most interesting and enlightening of the talks that I&#160;attended yesterday. DHH was mainly talking about legacy but I&#160;think the main message he was trying to get through was that a programmer should never stop [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=64&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>The second day of RailsConf Europe 2008 started with <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/4869" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">David Heinemeier Hansson&#8217;s keynote on legacy software</a> and was by far the most interesting and enlightening of the talks that I&nbsp;attended yesterday. DHH was mainly talking about legacy but I&nbsp;think the main message he was trying to get through was that a programmer should never stop learning, and I&nbsp;totally agree with that. I&nbsp;really regret I&nbsp;haven&#8217;t written about this before because now it will look like another DHH fanboy desperately trying to get to the me-too camp. Nonetheless, a couple of my own thoughts first and then on with the show.</p>
<p><span id="more-64"></span></p>
<p>What do you feel when you look at the code you wrote 3 years ago? 6 months ago? A&nbsp;month ago? Do you feel the need to throw up? Do you think to yourself: &#8220;What a mess! Who wrote it?&#8221; If yes, there&#8217;s no need to be ashamed. You should be proud of yourself, because that reaction shows that you have grown up, that you have learned, that you now see there are problems with your code you haven&#8217;t seen 6 months ago. This means that the code you write now is much better. And, hopefully, 6 months from now you will look at the code you wrote today and have the same reaction of disgust.</p>
<p>A&nbsp;really funny thing happened to me not too long ago. While I&nbsp;was browsing the codebase of one of our projects, I&nbsp;noticed a truly awful piece of code. A&nbsp;nightmare from hell. A&nbsp;couple of lines screaming REFACTOR ME NOW (which I&nbsp;did immediately) at the top of their lungs. After refactoring I&nbsp;wrote an email to our team showing the original code, explaining what was wrong with it and asking to never do it again. I&nbsp;made it clear that I&nbsp;wasn&#8217;t blaming anyone, I&nbsp;only wanted to educate them. After sending the email I&nbsp;decided to run <code>svn blame</code> to see who did that. I&nbsp;kept telling myself I&nbsp;only did it so I&nbsp;can maybe help or educate the poor guy, but the real cause of anxiety probably was &#8220;who is such a stupid loser?&#8221; So I&nbsp;ran <code>svn blame</code> and you know who was it? Me. 4 months ago.</p>
<p><div id="attachment_75" class="wp-caption alignright" style="width: 110px"><a href="http://www.flickr.com/photos/x180/2823890375/in/set-72157607077916014/"><img src="http://szeryf.files.wordpress.com/2008/09/dhh2.jpg?w=100&#038;h=67" alt="A scientific legacy diagram" title="A scientific legacy diagram" width="100" height="67" class="size-full wp-image-75" /></a><p class="wp-caption-text">A scientific legacy diagram</p></div>
<p>OK, back to RailsConf keynote. DHH started with asking: what is legacy software? Then came several definitions: <em>Legacy is not a specific technology</em> (DHH quotes italicized), which means you write legacy software in any technology, including Ruby on Rails. <em>Legacy is a function of you (your perception, tastes, knowledge) over time</em>, so the same code may be legacy to some people but perfectly good for other. In short <em>legacy is &#8220;an old stuff we don&#8217;t like&#8221;</em>. </p>
<p>DHH showed next a hand-sketched diagram of how a feeling of legacy rises in him in every project he works on and I&nbsp;think most of us can relate. When you start a new project, you feel you write <em>best code ever</em> but as time passes you evolve to <em>this sucks</em> feeling and then to <em>I&nbsp;can&#8217;t take it any more</em>. Eventually you think the best option would be to <em>rewrite</em> it from scratch. Is the code at fault? Does it really rot just by itself? No. <em>The code doesn&#8217;t really change, your perception changes</em>. Which is good, because <em>Legacy shows you that you have grown</em>.</p>
<p><div id="attachment_71" class="wp-caption alignleft" style="width: 110px"><a href="http://www.flickr.com/photos/x180/2823891043/in/set-72157607077916014/"><img src="http://szeryf.files.wordpress.com/2008/09/dhh.jpg?w=100&#038;h=67" alt="What you write today will become legacy" title="DHH keynote" width="100" height="67" class="size-full wp-image-71" /></a><p class="wp-caption-text">What you write today will become legacy</p></div>
<p>If you want to develop your skills and feel happy about yourself at the same time, you must acknowledge and embrace that <em>What you write today will become legacy</em>. It&#8217;s even worse when you&#8217;re starting to learn some new technology, because <em>When you&#8217;re green, everything turns legacy over night</em>. You learn so much every day that it kind of obsoletes what you wrote yesterday. This may be a problem to some people but <em>There&#8217;s no other way</em>. What to do when it bothers you? Just try to get over it and remember: you will not be a noob for ever.</p>
<p><div id="attachment_77" class="wp-caption alignright" style="width: 170px"><a href="http://www.flickr.com/photos/x180/2824731406/in/set-72157607077916014/"><img src="http://szeryf.files.wordpress.com/2008/09/dhh3.jpg?w=160&#038;h=240" alt="&quot;The name GlobalController is almost as good as ApplicationHelper&quot; - DHH" title="DHH talking about his own code" width="160" height="240" class="size-full wp-image-77" /></a><p class="wp-caption-text">'The name GlobalController is almost as good as ApplicationHelper' - DHH</p></div>
<p>DHH switched then to an editor and showed us some old code he wrote for Basecamp. He talked about what was wrong with that and what  would he do now to refactor it. A&nbsp;big chapeaux-bas for courage and honesty. Then he came back to the presentation and talked a little bit what to do when you happen to work with a project you feel is a legacy. He mentioned that Broken Window Syndrome from Pragmatic Programmer may be a little devious here, because you may not be able to &#8220;fix&#8221; all the problems with legacy software at once. Instead you should try to fix and refactor problems one by one, while developing new features etc.</p>
<p>One of the opinions that I&nbsp;sometimes semi-jokingly quote is that &#8220;every software project constantly gravitates towards a point where complete rewrite is necessary&#8221;. And yet, as DHH quotes Joel Spolsky, &#8220;the single worst strategic mistake a software company can make: rewrite the code from scratch.&#8221; I&nbsp;agree with both statements. So, what to do? Embrace!</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/szeryf.wordpress.com/64/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/szeryf.wordpress.com/64/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/64/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=64&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2008/09/04/relation-from-railsconf-europe-2008-dhh-keynote/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>

		<media:content url="http://szeryf.files.wordpress.com/2008/09/dhh2.jpg" medium="image">
			<media:title type="html">A scientific legacy diagram</media:title>
		</media:content>

		<media:content url="http://szeryf.files.wordpress.com/2008/09/dhh.jpg" medium="image">
			<media:title type="html">DHH keynote</media:title>
		</media:content>

		<media:content url="http://szeryf.files.wordpress.com/2008/09/dhh3.jpg" medium="image">
			<media:title type="html">DHH talking about his own code</media:title>
		</media:content>
	</item>
		<item>
		<title>Relation from RailsConf Europe 2008, day 1</title>
		<link>http://szeryf.wordpress.com/2008/09/03/relation-from-railsconf-europe-2008-day-1/</link>
		<comments>http://szeryf.wordpress.com/2008/09/03/relation-from-railsconf-europe-2008-day-1/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 14:25:32 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[RailsConf]]></category>
		<category><![CDATA[RailsConf Europe]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=59</guid>
		<description><![CDATA[p>The first day was a registration and tutorial day. The registration went smoothly, there was no gigantic queue that people waited in for half an hour like last year. My feeling is that there is less people this year but probably the organization is also better. Read on for a relation on the tutorials I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=59&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><div id="attachment_86" class="wp-caption alignright" style="width: 110px"><a href="http://www.flickr.com/photos/x180/2822417901/in/set-72157607077916014/"><img src="http://szeryf.files.wordpress.com/2008/09/panel.jpg?w=100&#038;h=67" alt="Panel discussion with DHH and Rails Core Team members" title="Panel discussion with DHH and Rails Core Team members" width="100" height="67" class="size-full wp-image-86" /></a><p class="wp-caption-text">Panel discussion with DHH and Rails Core Team members</p></div>
<p>The first day was a registration and tutorial day. The registration went smoothly, there was no gigantic queue that people waited in for half an hour like last year. My feeling is that there is less people this year but probably the organization is also better. Read on for a relation on the tutorials I attended and evening&#8217;s panel discussion.</p>
<p><span id="more-59"></span></p>
<p>The first tutorial, <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/2556" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">Better Living Through Resourceful Plugins</a> was very interesting. Ben Scofield talked about how to solve one of the biggest pains with Rails development (at least in my experience): problems with reusing bigger chunks of functionality. Ben&#8217;s solution is to use &#8220;Resourceful Plugins&#8221; which basically are ordinary plugins with some clever generators and included modules. This way we can have all the layers in the plugin (the models, controllers and views) and still be able to customize them in the app. You can take a look at Ben&#8217;s example resourceful plugin <a href="http://github.com/vigetlabs/bloget/tree/master" title="vigetlabs's bloget at master &mdash; GitHub">Bloget</a>. This technique will certainly make my life easier.</p>
<p>The second tutorial was even more interesting. In the brillant and witty <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/3552" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">Meta-programming Ruby for Fun &amp; Profit</a> Neal Ford talked about programmable programs, humane interfaces, using <code>method_missing</code> and <code>const_missing</code> (the latter for a dynamic class factory), implementing various design patterns and aspect orientation (which is easy to achieve with meta-programming) or how to mimic features from other languages that are not available in Ruby (like Java&#8217;s <code>final</code> keyword to prevent extending a class). Be sure to check <a href="http://nealford.com/mypastconferences.htm" title="Neal's Past Conference Appearances">Neal&#8217;s presentation</a> for funny and clever, Matrix inspired slides. </p>
<p>I was also very glad to notice that Neal used an example of generating test methods in a loop that was very similar in idea to my old <a href="http://szeryf.wordpress.com/2007/09/26/looping-in-a-no-mans-land/" title="Looping in a no man&#8217;s land &laquo; require &#8216;brain&#8217;">Looping in a no man’s land</a> post.</p>
<p>In the second part of the tutorial, Pat Farley took over and dug into gory details of Ruby implementation that are important when using meta-programming techniques. This part was much more difficult and not that attractive as Neal&#8217;s part, but also interesting. Pat showed many fragments of Ruby&#8217;s implementation C source, each time preceding them with a slide with a woman bleeding from her eyes. My favorite quote from Pat&#8217;s talk: the superclass of a metaclass is the metaclass of the superclass.</p>
<p><div id="attachment_88" class="wp-caption aligncenter" style="width: 457px"><a href="http://www.flickr.com/photos/x180/2823260238/in/set-72157607077916014/"><img src="http://szeryf.files.wordpress.com/2008/09/panel2.jpg?w=447&#038;h=298" alt="David Heinemeier Hansson, Jeremy Kemper and Michael Koziarski" title="David Heinemeier Hansson, Jeremy Kemper and Michael Koziarski" width="447" height="298" class="size-full wp-image-88" /></a><p class="wp-caption-text">David Heinemeier Hansson, Jeremy Kemper and Michael Koziarski</p></div>
<p>The day ended with a <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/4873" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">panel discussion featuring David Heinemeier Hansson, Michael Koziarski and Jeremy Kemper</a>. I was a little bit disappointed, because it mostly consisted of chaotic and superficial answers to unrelated questions from the audience. There were some interesting thoughts but I expected a little bit more from a &#8220;panel discussion&#8221;.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/szeryf.wordpress.com/59/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/szeryf.wordpress.com/59/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/59/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=59&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2008/09/03/relation-from-railsconf-europe-2008-day-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>

		<media:content url="http://szeryf.files.wordpress.com/2008/09/panel.jpg" medium="image">
			<media:title type="html">Panel discussion with DHH and Rails Core Team members</media:title>
		</media:content>

		<media:content url="http://szeryf.files.wordpress.com/2008/09/panel2.jpg" medium="image">
			<media:title type="html">David Heinemeier Hansson, Jeremy Kemper and Michael Koziarski</media:title>
		</media:content>
	</item>
		<item>
		<title>I will be at RailsConf Europe 2008</title>
		<link>http://szeryf.wordpress.com/2008/08/31/i-will-be-at-railsconf-europe-2008/</link>
		<comments>http://szeryf.wordpress.com/2008/08/31/i-will-be-at-railsconf-europe-2008/#comments</comments>
		<pubDate>Sun, 31 Aug 2008 20:09:35 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[RailsConf Europe]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=55</guid>
		<description><![CDATA[Thanks to my employer Jarorcon, I will be attending RailsConf Europe 2008 in Berlin, Germany. Hopefully it will be at least as good as last year. I also hope to get some more t-shirts than last year (only one).
I&#8217;m especially looking forward to attending the tutorials: Better Living Through Resourceful Plugins and Meta-programming Ruby for [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=55&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Thanks to my employer <a href="http://jarorcon.pl/front_content.php" title="jarorcon">Jarorcon</a>, I will be attending <a href="http://en.oreilly.com/railseurope2008/public/content/home" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">RailsConf Europe 2008</a> in Berlin, Germany. Hopefully it will be at least as good as last year. I also hope to get some more t-shirts than last year (only one).</p>
<p>I&#8217;m especially looking forward to attending the tutorials: <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/2556" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">Better Living Through Resourceful Plugins</a> and <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/3552" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">Meta-programming Ruby for Fun &amp; Profit</a>. The <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/3432" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">Object Databases with Ruby on Rails</a> and <a href="http://en.oreilly.com/railseurope2008/public/schedule/detail/3604" title="RailsConf Europe 2008 - O'Reilly Conferences, 02 September - 04, 2008, Berlin, Germany">Extending Ruby with Class</a> talks also look very interesting. There is of course plenty of other interesting talks but I&#8217;m still undecided which ones to attend.</p>
<p>I will be also present at <a href="http://bratwurst-on-rails.com/" title="Bratwurst On Rails - A Pre-RailsConf Europe Socializing Event">Bratwurst on Rails</a> for some serious beer quaffing. I hope the wurst will be better than last time. Don&#8217;t hesitate to come up and chat with me if you want.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/szeryf.wordpress.com/55/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/szeryf.wordpress.com/55/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/55/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/55/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/55/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/55/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/55/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/55/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=55&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2008/08/31/i-will-be-at-railsconf-europe-2008/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>
	</item>
		<item>
		<title>Breadcrumbs II: the Internationalization</title>
		<link>http://szeryf.wordpress.com/2008/07/23/breadcrumbs-ii-the-internationalization/</link>
		<comments>http://szeryf.wordpress.com/2008/07/23/breadcrumbs-ii-the-internationalization/#comments</comments>
		<pubDate>Wed, 23 Jul 2008 13:00:09 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[before_filter]]></category>
		<category><![CDATA[breadcrumb]]></category>
		<category><![CDATA[filters]]></category>
		<category><![CDATA[gettext]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[internationalization]]></category>
		<category><![CDATA[l10n]]></category>
		<category><![CDATA[localization]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[breadcrumbs]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=50</guid>
		<description><![CDATA[This is a quick followup to my breadcrumb solution. If your application is internationalized, I think you might be interested in the code presented below. If not, stick with the original version. 

Without further ado, here&#8217;s how to make breadcrumbs work nicely with Ruby-GetText:

class ApplicationController &#60; ActionController::Base
  ...
protected
  def add_breadcrumb_without_translation name, path = [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=50&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>This is a quick followup to my <a href="http://szeryf.wordpress.com/2008/06/13/easy-and-flexible-breadcrumbs-for-rails/" title="Easy and flexible breadcrumbs for Rails &laquo; require &#8216;brain&#8217;">breadcrumb solution</a>. If your application is internationalized, I think you might be interested in the code presented below. If not, stick with the <a href="http://szeryf.wordpress.com/2008/06/13/easy-and-flexible-breadcrumbs-for-rails/" title="Easy and flexible breadcrumbs for Rails &laquo; require &#8216;brain&#8217;">original version</a>. </p>
<p><span id="more-50"></span></p>
<p>Without further ado, here&#8217;s how to make breadcrumbs work nicely with <a href="http://www.yotabanana.com/hiki/ruby-gettext.html?ruby-gettext" title="Ruby-GetText-Package - YotaLab Storage">Ruby-GetText</a>:</p>
<pre class="brush: ruby;">
class ApplicationController &lt; ActionController::Base
  ...
protected
  def add_breadcrumb_without_translation name, path = ''
    @breadcrumbs ||= []
    path = eval(path) if path =~ /_path|_url|@/
    @breadcrumbs &lt;&lt; [name, path]
  end

  def add_breadcrumb name, path = ''
    add_breadcrumb_without_translation _(name), path
  end

  def self.add_breadcrumb name, path, options = {}
    before_filter options do |controller|
      controller.send(:add_breadcrumb, name, path)
    end
  end
end
</pre>
<p>As we can see, there are three methods now. We have the <code>add_breadcrumb_without_translation</code> method in case we wanted to add something like <code>@category.name</code> to the breadcrumb trail. The other method, <code>add_breadcrumb</code> uses GetText&#8217;s <code>_()</code> function to translate the <code>name</code> parameter. The third method, which defines a filter, is same as before.</p>
<p>And here&#8217;s how you would use it:</p>
<pre class="brush: ruby;">
class ApplicationController &lt; ActionController::Base
  add_breadcrumb N_('Home'), '/'
  ...
end
class ThingsController &lt; ApplicationController
  add_breadcrumb N_('Things'), 'things_path'
  add_breadcrumb N_('Create a new thing'), '', :only =&gt; [:new, :create]
  add_breadcrumb N_('Edit a thing'), '', :only =&gt; [:edit, :update]

  def show
    @thing = Thing.find(params[:id])
    add_breadcrumb_without_translation @thing.name, ''
  end
  ...
end
</pre>
<p>Caveat: this works with <a href="http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html" title="Ruby-GetText-Package HOWTO for Ruby on Rails - YotaLab Storage">GetText</a> only. If you want to use any <a href="http://wiki.rubyonrails.org/rails/pages/InternationalizationComparison" title="InternationalizationComparison in Ruby on Rails">other I18N framework</a>, you need to replace GetText&#8217;s <code>_()</code> and <code>N_()</code> functions with your framework&#8217;s equivalents. The <code>_('string')</code> function provides the translation of given string in current locale, while the <code>N_('string')</code> just declares to GetText that the string is one of the translation keys, but it should not be translated right here. This is required when breadcrumbs are defined at the top of the controller class, because this code is interpreted while the class is being loaded, but we need the translation to occur for each processed request with appropriate locale. </p>
<p>As far as I know, <a href="http://www.globalize-rails.org/" title="Globalize">Globalize</a>&#8217;s equivalent for <code>_('string')</code> is <code>'string'.t</code>, but I have no idea how to replace <code>N_()</code>. I&#8217;d appreciate any comments from people using Globalize and other frameworks on how to make this work with those frameworks.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/szeryf.wordpress.com/50/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/szeryf.wordpress.com/50/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/50/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=50&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2008/07/23/breadcrumbs-ii-the-internationalization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>
	</item>
		<item>
		<title>Blast from the past: Compaq commercials with John Cleese</title>
		<link>http://szeryf.wordpress.com/2008/07/09/blast-from-the-past-compaq-commercials-with-john-cleese/</link>
		<comments>http://szeryf.wordpress.com/2008/07/09/blast-from-the-past-compaq-commercials-with-john-cleese/#comments</comments>
		<pubDate>Wed, 09 Jul 2008 21:17:40 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[Compaq]]></category>
		<category><![CDATA[John Cleese]]></category>
		<category><![CDATA[commercials]]></category>
		<category><![CDATA[funny]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=47</guid>
		<description><![CDATA[Being a long time Monty Python fan, I couldn&#8217;t resist to share these hilarious mid-80&#8217;s Compaq commercials with John Cleese.
I Wouldn&#8217;t Watch This Commercial

&#8230;made from 386 chips and 32 bits of a bus!

How To Spell Compaq

Computers Often Make People Quite Angry!
Portable 2 Compared to This Fish

The fish weighs 22 pounds, which makes it extremely portable&#8230; [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=47&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Being a long time Monty Python fan, I couldn&#8217;t resist to share these hilarious mid-80&#8217;s Compaq commercials with John Cleese.</p>
<h2>I Wouldn&#8217;t Watch This Commercial</h2>
<p><span style="text-align:center; display: block;"><a href="http://szeryf.wordpress.com/2008/07/09/blast-from-the-past-compaq-commercials-with-john-cleese/"><img src="http://img.youtube.com/vi/FGj56PLYUSI/2.jpg" alt="" /></a></span></p>
<p style="text-align:center;">&#8230;made from 386 chips and 32 bits of a bus!</p>
<p><span id="more-47"></span></p>
<h2>How To Spell Compaq</h2>
<p><span style="text-align:center; display: block;"><a href="http://szeryf.wordpress.com/2008/07/09/blast-from-the-past-compaq-commercials-with-john-cleese/"><img src="http://img.youtube.com/vi/mF0rmeRq12g/2.jpg" alt="" /></a></span></p>
<p style="text-align:center;">Computers Often Make People Quite Angry!</p>
<h2>Portable 2 Compared to This Fish</h2>
<p><span style="text-align:center; display: block;"><a href="http://szeryf.wordpress.com/2008/07/09/blast-from-the-past-compaq-commercials-with-john-cleese/"><img src="http://img.youtube.com/vi/RlmzwZXa-Ww/2.jpg" alt="" /></a></span></p>
<p>The fish weighs 22 pounds, which makes it extremely portable&#8230; (can anyone tell me what joke John Cleese says at about 0:50, before bursting in hysterical laughter?)</p>
<h2>BORING!</h2>
<p><span style="text-align:center; display: block;"><a href="http://szeryf.wordpress.com/2008/07/09/blast-from-the-past-compaq-commercials-with-john-cleese/"><img src="http://img.youtube.com/vi/8s3OFxrfVug/2.jpg" alt="" /></a></span></p>
<h2>That Trendy Computer</h2>
<p><span style="text-align:center; display: block;"><a href="http://szeryf.wordpress.com/2008/07/09/blast-from-the-past-compaq-commercials-with-john-cleese/"><img src="http://img.youtube.com/vi/dm7gLKZcmhM/2.jpg" alt="" /></a></span></p>
<p style="text-align:center;">My horoscope advises against travel!</p>
<h2>The Finger Trick</h2>
<p><span style="text-align:center; display: block;"><a href="http://szeryf.wordpress.com/2008/07/09/blast-from-the-past-compaq-commercials-with-john-cleese/"><img src="http://img.youtube.com/vi/MWCgsf5wbTE/2.jpg" alt="" /></a></span></p>
<p style="text-align:center;">Instead, I&#8217;m going to take off top two joints of my index finger.</p>
<h2>I&#8217;ve Got A Reputation!</h2>
<p><span style="text-align:center; display: block;"><a href="http://szeryf.wordpress.com/2008/07/09/blast-from-the-past-compaq-commercials-with-john-cleese/"><img src="http://img.youtube.com/vi/CMeE6lc7KG4/2.jpg" alt="" /></a></span></p>
<h2>Intro to Ads</h2>
<p><span style="text-align:center; display: block;"><a href="http://szeryf.wordpress.com/2008/07/09/blast-from-the-past-compaq-commercials-with-john-cleese/"><img src="http://img.youtube.com/vi/euMIjKnvJXY/2.jpg" alt="" /></a></span></p>
<p style="text-align:center;">&#8230;but Cheese will do.</p>
<h2>Does It Have A Handle?</h2>
<p><span style="text-align:center; display: block;"><a href="http://szeryf.wordpress.com/2008/07/09/blast-from-the-past-compaq-commercials-with-john-cleese/"><img src="http://img.youtube.com/vi/OMU3GQsNB1k/2.jpg" alt="" /></a></span></p>
<h2>WE Have Bruno</h2>
<p><span style="text-align:center; display: block;"><a href="http://szeryf.wordpress.com/2008/07/09/blast-from-the-past-compaq-commercials-with-john-cleese/"><img src="http://img.youtube.com/vi/nWmygys6rbI/2.jpg" alt="" /></a></span></p>
<h2>Forget All Our Earlier Commercials</h2>
<p><span style="text-align:center; display: block;"><a href="http://szeryf.wordpress.com/2008/07/09/blast-from-the-past-compaq-commercials-with-john-cleese/"><img src="http://img.youtube.com/vi/ciXNWAzmL3s/2.jpg" alt="" /></a></span></p>
<h2>One Million Pound Ransom!</h2>
<p><span style="text-align:center; display: block;"><a href="http://szeryf.wordpress.com/2008/07/09/blast-from-the-past-compaq-commercials-with-john-cleese/"><img src="http://img.youtube.com/vi/WQAxr3eAte0/2.jpg" alt="" /></a></span></p>
<p style="text-align:right;">Via <a href="http://www.darkroastedblend.com/" title="Dark Roasted Blend">Dark Roasted Blend</a>.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/szeryf.wordpress.com/47/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/szeryf.wordpress.com/47/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/47/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/47/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/47/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/47/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/47/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=47&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2008/07/09/blast-from-the-past-compaq-commercials-with-john-cleese/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>

		<media:content url="http://img.youtube.com/vi/FGj56PLYUSI/2.jpg" medium="image" />

		<media:content url="http://img.youtube.com/vi/mF0rmeRq12g/2.jpg" medium="image" />

		<media:content url="http://img.youtube.com/vi/RlmzwZXa-Ww/2.jpg" medium="image" />

		<media:content url="http://img.youtube.com/vi/8s3OFxrfVug/2.jpg" medium="image" />

		<media:content url="http://img.youtube.com/vi/dm7gLKZcmhM/2.jpg" medium="image" />

		<media:content url="http://img.youtube.com/vi/MWCgsf5wbTE/2.jpg" medium="image" />

		<media:content url="http://img.youtube.com/vi/CMeE6lc7KG4/2.jpg" medium="image" />

		<media:content url="http://img.youtube.com/vi/euMIjKnvJXY/2.jpg" medium="image" />

		<media:content url="http://img.youtube.com/vi/OMU3GQsNB1k/2.jpg" medium="image" />

		<media:content url="http://img.youtube.com/vi/nWmygys6rbI/2.jpg" medium="image" />

		<media:content url="http://img.youtube.com/vi/ciXNWAzmL3s/2.jpg" medium="image" />

		<media:content url="http://img.youtube.com/vi/WQAxr3eAte0/2.jpg" medium="image" />
	</item>
		<item>
		<title>Easy and flexible breadcrumbs for Rails</title>
		<link>http://szeryf.wordpress.com/2008/06/13/easy-and-flexible-breadcrumbs-for-rails/</link>
		<comments>http://szeryf.wordpress.com/2008/06/13/easy-and-flexible-breadcrumbs-for-rails/#comments</comments>
		<pubDate>Fri, 13 Jun 2008 12:06:06 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[before_filter]]></category>
		<category><![CDATA[breadcrumb]]></category>
		<category><![CDATA[filters]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[breadcrumbs]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=45</guid>
		<description><![CDATA[Most projects I work on require some implementation of breadcrumbs. Unfortunately most solutions that I found take the very simplistic approach: they split the URL and present each part as a link. I really have a hard time imagining that this can be sufficient for any non-trivial app.
I also found session-based implementation, but according to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=45&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Most projects I work on require some implementation of <a href="http://en.wikipedia.org/wiki/Breadcrumb_(navigation)" title="Breadcrumb (navigation) - Wikipedia, the free encyclopedia">breadcrumbs</a>. Unfortunately <a href="http://joshhuckabee.com/simple-breadcrumb-ruby-rails" title="Simple Breadcrumb in Ruby on Rails | Josh Huckabee">most</a> <a href="http://blog.craig-mackenzie.com/2007/08/09/simple-bread-crumbs-in-ruby-on-rails/" title="metal &amp; gin &raquo; simple bread crumbs in ruby on rails">solutions</a> <a href="http://rubysnips.com/url-based-breadcrumbs" title="Ruby Snips  URL-based Breadcrumbs">that I found</a> take the very simplistic approach: they <strong>split the URL and present each part as a link</strong>. I really have a hard time imagining that this can be sufficient for any non-trivial app.</p>
<p>I also found <a href="http://vishk.wordpress.com/2007/07/31/a-breadcrumb-trail-for-rails-application/" title="A Breadcrumb trail for Rails Application &laquo; Tech Notes, Snippets, Trends and Business">session-based implementation</a>, but according to the above mentioned Wikipedia article classification these are path-style breadcrumbs, while I need location-style with a little bit of attribute-style mixed in where needed. That is, the <strong>breadcrumbs should normally reflect the page&#8217;s location in some (virtual) website hierarchy</strong>. Sometimes, while browsing things that are naturally hierarchical (like forum threads/posts, category trees and so on), the <strong>breadcrumb trail should also reflect this hierarchy</strong>. Read on to see my take on this problem.</p>
<p><span id="more-45"></span></p>
<h1>The requirements</h1>
<p>First, let&#8217;s formulate the requirements for the breadcrumbs solution.</p>
<ol>
<li>It should be a <strong>list of links with descriptions</strong>, except for the last element, which should not be clickable because it represents current page.</li>
<li>It should have syntax that is <strong>easy to use</strong>, ideally something like: <code>add_breadcrumb 'Description', some_path</code></li>
<li>It should allow us to <strong>add arbitrary number of elements</strong>, both statically and dynamically.</li>
<li>The static parts should be similar to filters:
<ol>
<li><strong>declared at one place</strong> (e.g. at the top of the controller) not littered around actions or views,</li>
<li><strong>inheritable</strong> (so you can declare home link only once, in your <code>ApplicationController</code>),</li>
<li>with easily recognizable <strong>order</strong>,</li>
<li>and support for <strong>filter options</strong> like <code>:only</code> or <code>:except</code>.</li>
</ol>
</li>
<li>The dynamic parts can be added at <strong>any time during the request processing</strong>, from actions, filters of views, if necessary.</li>
</ol>
<p>Looks like a lot of hard work? Maybe. But my priority was <strong>flexibility and ease of use</strong>, not necessarily ease of implementation. I want to be able to do things like this:</p>
<h2>Simple example</h2>
<pre class="brush: ruby;">
class ApplicationController &lt; ActionController::Base
  add_breadcrumb 'Home', '/'
  ...
end
class ThingsController &lt; ApplicationController
  add_breadcrumb 'Things', 'things_path'
  add_breadcrumb 'Create a new thing', '', :only =&gt; [:new, :create]
  add_breadcrumb 'Edit a thing', '', :only =&gt; [:edit, :update]

  def show
    @thing = Thing.find(params[:id])
    add_breadcrumb @thing.name, ''
  end
  ...
end
</pre>
<p>With this setup, we get breadcrumbs like <em>Home &gt; Things</em> for things index, <em>Home &gt; Things &gt; Create a new thing</em> for new thing or <em>Home &gt; Things &gt; some name</em> for show action. </p>
<h2>Notes</h2>
<ul>
<li>We need to <strong>quote <code>*_path</code> and <code>*_url</code> (like this: <code>'things_path'</code>) when outside of actions</strong> due to the way these methods are implemented in Rails. I stretched requirement #2 here but I think this is really only a minor inconvenience. When you forget to do this, you&#8217;ll get an undefined method error. The quoted string will be <code>eval</code>-ed when the request is processed, which is of course not the cleanest solution, but works for me.</li>
<li>When the added element is guaranteed to be the last, we don&#8217;t have to provide the URL for it.</li>
<li>Although it may seem that <code>:new</code> is sufficient for the new thing form, we need to add <code>:create</code> to have the breadcrumb defined when the validation fails and the form is redisplayed (same for <code>:edit</code> and <code>:update</code>, respectively). This may look like a redundancy but that&#8217;s how Rails works. Alternatively you can add the breadcrumb from the <code>new.html.erb</code> template or inside the <code>:create</code> action. But I prefer to have them declared in one place if only possible.</li>
<li><strong>If you use <code>add_breadcrumb</code> in your <code>ApplicationController</code>, you must do it after the methods are defined (it should be under those methods)</strong>.</li>
</ul>
<h2>Dynamic example</h2>
<p>Now for something a little bit more dynamic, let&#8217;s assume we have a hierarchy of categories and while browsing a category we want the breadcrumb to show all the ancestor categories:</p>
<pre class="brush: ruby;">
class CategoriesController &lt; ApplicationController
  add_breadcrumb 'Categories', 'categories_path'

  def show
    @category = Category.find(params[:id])
    set_breadcrumb_for @category
  end
  ...
private
  def set_breadcrumb_for cat
    set_breadcrumb_for cat.parent if cat.parent
    add_breadcrumb cat.name, &quot;category_path(#{cat.id})&quot;
  end
end
</pre>
<p>This lets us have breadcrumbs like <em>Home &gt; Categories &gt; Root &gt; Parent &gt; Child</em> for tree-like category hierarchies. The <code>set_breadcrumb_for</code> method traverses all the parents of the category recursively until it finds the root category. I agree that the <code>"category_path(#{cat.id})"</code> part looks a little bit messy, but I couldn&#8217;t find any cleaner way to do this with the <code>eval</code> solution I mentioned above. Any suggestions welcome.</p>
<h1>The implementation</h1>
<p>Now for the implementation. It&#8217;s really quite trivial for the above defined set of the requirements. Just drop these two methods in your <code>ApplicationController</code>: </p>
<pre class="brush: ruby;">
class ApplicationController &lt; ActionController::Base
  ...
protected
  def add_breadcrumb name, url = ''
    @breadcrumbs ||= []
    url = eval(url) if url =~ /_path|_url|@/
    @breadcrumbs &lt;&lt; [name, url]
  end

  def self.add_breadcrumb name, url, options = {}
    before_filter options do |controller|
      controller.send(:add_breadcrumb, name, url)
    end
  end
end
</pre>
<p>We need two versions of <code>add_breadcrumb</code> method. The first one (which is an instance method) is <strong>responsible for constructing the actual breadcrumb list</strong>. It is called several times during request processing. As we can see <code>@breadcrumbs</code> is just a list of two element lists, containing description and a URL.</p>
<p>The second version is a class method that we can use in declarations at the top of our controllers. It just <strong>defines an unnamed <code>before_filter</code></strong> which, when called, uses the first version to add breadcrumb element. This way we get all the goodies (<code>:only</code>, <code>:except</code>, ordering) for free.</p>
<p>How to display the breadcrumbs? Put something like below to your layout and add HTML tags and styles as needed.</p>
<pre class="brush: xml;">
&lt;% if @breadcrumbs %&gt;
  You are here:
  &lt;% @breadcrumbs[0..-2].each do |txt, path| %&gt;
    &lt;%= link_to(h(txt), path) %&gt; &gt;
  &lt;% end %&gt;
  &lt;%= h(@breadcrumbs.last.first) %&gt;
&lt;% end %&gt;
</pre>
<p>And that&#8217;s it. I hope it works for you. Any suggestions and improvements welcome.</p>
<p><strong>UPDATE</strong>: I just posted a <a href="http://szeryf.wordpress.com/2008/07/23/breadcrumbs-ii-the-internationalization/" title="the Internationalization &laquo; require &#8216;brain&#8217;">followup about how to make breadcrumbs work in an internationalized application</a>.</p>
<p><strong>UPDATE #2</strong>: you can have problems with using <code>add_breadcrumb</code> in your <code>ApplicationController</code>, as noted by Vinay in the comments below. See notes above how to fix this.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/szeryf.wordpress.com/45/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/szeryf.wordpress.com/45/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/45/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=45&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2008/06/13/easy-and-flexible-breadcrumbs-for-rails/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>
	</item>
		<item>
		<title>Eliminating code duplication with metaprogramming</title>
		<link>http://szeryf.wordpress.com/2008/06/05/eliminating-code-duplication-with-metaprogramming/</link>
		<comments>http://szeryf.wordpress.com/2008/06/05/eliminating-code-duplication-with-metaprogramming/#comments</comments>
		<pubDate>Thu, 05 Jun 2008 11:23:49 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[DRY]]></category>
		<category><![CDATA[metaprogramming]]></category>
		<category><![CDATA[method_missing]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=44</guid>
		<description><![CDATA[Duplication of code is one of the worst code smells. It should be refactored in order to keep DRY if only possible. This is generally easy. But what if the code itself is not duplicated, but its structure is? That could be a little bit more difficult, but with Ruby&#8217;s metaprogamming facilities it&#8217;s not that [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=44&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Duplication of code is one of the worst <a href="http://en.wikipedia.org/wiki/Code_smell" title="Code smell - Wikipedia, the free encyclopedia">code smells</a>. It should be refactored in order to keep <a href="http://en.wikipedia.org/wiki/DRY" title="Don't repeat yourself">DRY</a> if only possible. This is generally easy. But what if the <strong>code itself is not duplicated, but its structure is</strong>? That could be a little bit more difficult, but with <a href="http://en.wikipedia.org/wiki/Ruby_%28programming_language%29">Ruby</a>&#8217;s <a href="http://en.wikipedia.org/wiki/Metaprogramming" title="Metaprogramming - Wikipedia, the free encyclopedia">metaprogamming</a> facilities it&#8217;s not that hard. Read on to see how.</p>
<p><span id="more-44"></span></p>
<h1>The problem</h1>
<p>In our project, we have a module called <code>Factory</code> that produces object needed by tests. It generally contains pairs of methods, <code>new_something</code> and <code>create_something</code>, like this:</p>
<pre class="brush: ruby;">
module Factory
  def self.new_user options={}
    User.new({
      # some default values
    }.merge(options))
  end

  def self.create_user options
    u = new_user options
    u.save!
    u
  end

  def self.new_role options={}
    Role.new({
      # some default values
    }.merge(options))
  end

  def self.create_role options
    r = new_role options
    r.save!
    r
  end

  def self.new_permission options={}
    Permission.new({
      # some default values
    }.merge(options))
  end

  def self.create_permission options
    p = new_permission options
    p.save!
    p
  end

  def self.new_group options={}
    Group.new({
      # some default values
    }.merge(options))
  end

  def self.create_group options
    g = new_group options
    g.save!
    g
  end
  # ...snip...
end
</pre>
<p>Basically, the <code>new_something</code> methods merge provided and default options and <strong>return new, unsaved objects</strong>. In place of &#8220;some default values&#8221; there is always a list of attribute values that are needed for an object to pass validation (like login and password for user). This list is of course different for each type.</p>
<p>Notice the pattern with <code>create_something</code> methods?<a href="#footnote1"><sup>1</sup></a><a name="back1"></a> Yes, <strong>they always do the same thing</strong>: call the paired <code>new_something</code> method, save the object and return it (although the type of the object is different). How to refactor this pattern and remove the duplication? There are several ways to do it. Let&#8217;s look at one of them.</p>
<h1>The solution</h1>
<p>My proposed solution is <strong>not to write the <code>create_something</code> methods</strong> at all. Instead, provide a <strong><a href="http://www.ruby-doc.org/core/classes/Kernel.html#M001060"><code>method_missing</code></a> implementation that will take care of creating objects</strong>. Like this:</p>
<pre class="brush: ruby;">
module Factory
  def self.method_missing name, *args
    if name.to_s =~ /^create_(.+)/
      obj = self.send(&quot;new_#{$1}&quot;, *args)
      obj.save!
      obj
    end
  end

  # ...snip...
end
</pre>
<p>Now, if we intercept a call to <code>create_something</code>, we extract the &#8217;something&#8217; with a regular expression and call the appropriate <code>new_something</code> method, passing all the arguments just as the original methods did. Then the object is saved and returned, as before. This part is 3 lines of code, but we can make it one line:</p>
<pre class="brush: ruby;">
module Factory
  def self.method_missing name, *args
    if name.to_s =~ /^create_(.+)/
      returning(self.send(&quot;new_#{$1}&quot;, *args)) { |o| o.save! }
    end
  end

  # ...snip...
end
</pre>
<p>Or, if we (ab)use the <a href="http://invisibleblocks.wordpress.com/2008/03/28/ruby-facets-symbolto_proc-classto_proc/" title="Symbol.to_proc, Class.to_proc &laquo; Invisible Blocks">Symbol#to_proc idiom</a> (and forsake a little bit of readability), we can shorten it further to: </p>
<pre class="brush: ruby;">
module Factory
  def self.method_missing name, *args
    if name.to_s =~ /^create_(.+)/
      returning self.send(&quot;new_#{$1}&quot;, *args), &amp;:save!
    end
  end

  # ...snip...
end
</pre>
<p>What if one of the <code>create_something</code> methods differs from the pattern? E.g. <code>create_user</code> method might need to assign the created user to a role in order to let it login into the application. That&#8217;s no problem at all. Just <strong>write your <code>create_user</code> method as before</strong> and let it do all you need it to do. The <code>method_missing</code> method will not be called when <code>create_user</code> is <strong>not missing</strong>. The general rule is: <strong><code>method_missing</code> handles the typical cases and <code>create_something</code> methods are necessary only when something extra is needed</strong>.</p>
<hr />
<p><a name="footnote1"></a><a href="#back1"><sup>1</sup></a> <font size="1">There is also a pattern in the <code>new_something</code> methods, of course, but eliminating it is left as an exercise for the reader (and you still have to provide the default values somewhere).</font></p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/szeryf.wordpress.com/44/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/szeryf.wordpress.com/44/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/44/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/44/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/44/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=44&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2008/06/05/eliminating-code-duplication-with-metaprogramming/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>
	</item>
		<item>
		<title>Small TextMate tip</title>
		<link>http://szeryf.wordpress.com/2008/05/20/small-textmate-tip/</link>
		<comments>http://szeryf.wordpress.com/2008/05/20/small-textmate-tip/#comments</comments>
		<pubDate>Tue, 20 May 2008 08:37:22 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[TextMate]]></category>
		<category><![CDATA[keyword completion]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[word selection]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=43</guid>
		<description><![CDATA[Here&#8217;s a small TextMate tip I discovered today. Normally, some TextMate functions don&#8217;t work too well with Ruby code. Word selection and keyword completion  ignore Ruby-specific characters like : or ? or !. For example, if you used somewhere method like blank? and then you type bl and press Esc, TextMate will complete it [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=43&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Here&#8217;s a small TextMate tip I discovered today. Normally, some TextMate functions don&#8217;t work too well with Ruby code. <strong>Word selection and keyword completion  ignore Ruby-specific characters</strong> like <code>:</code> or <code>?</code> or <code>!</code>. For example, if you used somewhere method like <code>blank?</code> and then you type <code>bl</code> and press <code>Esc</code>, TextMate will complete it as <code>blank</code>, ignoring the <code>?</code> at the end. And don&#8217;t even get me started about when you double click <code>blank?</code> and the <code>?</code> is not selected.</p>
<p>To change it, go to the <i>Preferences</i> (<code>CMD-,</code>) and select <i>Text Editing</i> tab. At the bottom, there&#8217;s an editbox  labeled <i>Word characters</i> containing a single <code>_</code> by default. Add  characters <code>:?!</code> to this editbox, close the window and you&#8217;re done. Enjoy!</p>
<p>There&#8217;s one <i>caveat</i>, however. This setting is <strong>global and affects word selection and keyword completion in all files</strong>. If you edit many other types of files, that could be a problem.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/szeryf.wordpress.com/43/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/szeryf.wordpress.com/43/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/43/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/43/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=43&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2008/05/20/small-textmate-tip/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>
	</item>
		<item>
		<title>Who do you want to be when you grow up?</title>
		<link>http://szeryf.wordpress.com/2008/03/25/who-do-you-want-to-be-when-you-grow-up/</link>
		<comments>http://szeryf.wordpress.com/2008/03/25/who-do-you-want-to-be-when-you-grow-up/#comments</comments>
		<pubDate>Tue, 25 Mar 2008 21:46:15 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[career]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=42</guid>
		<description><![CDATA[So, you&#8217;re young and you&#8217;re a programmer. Maybe even a successful one. You have a cool job: the salary is good, the tasks are challenging and your coworkers are both intelligent and funny. Perhaps you&#8217;re not &#8220;just&#8221; a programmer, maybe your job title is something like &#8220;developer/designer&#8221; or &#8220;leading programmer&#8221;. I bet your parents are [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=42&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>So, you&#8217;re young and you&#8217;re a programmer. Maybe even a successful one. You have a cool job: the salary is good, the tasks are challenging and your coworkers are both intelligent and funny. Perhaps you&#8217;re not &#8220;just&#8221; a programmer, maybe your job title is something like &#8220;developer/designer&#8221; or &#8220;leading programmer&#8221;. I bet your parents are proud of you and most of your non-geek friends envy you. You have probably already created something you&#8217;re proud of: some cool app or a web framework. But&#8230;</p>
<p><span id="more-42"></span></p>
<p>Have you ever thought who do you want to be when you&#8217;re 35 years old? When you&#8217;re 50? Are you sure you&#8217;d still be passionate about churning code and keeping up with latest technologies when you&#8217;re 50 or older? Think about it: how many programmers do you know that are a) younger than 30, b) older than 40? I&#8217;m certain &#8220;a&#8221; is much larger than &#8220;b&#8221;. Have you ever thought why is it so? Is there something about programming that makes most people grow out of it?</p>
<p>Maybe programming is too exhaustive and people grow weary of it and burn themselves out after 10 or more years? Maybe you loose the ability to create and manipulate large abstract structures in your mind when you grow older? Maybe it&#8217;s the need to constantly learn? What if there&#8217;s a point beyond which you&#8217;re simply not able to learn any new language or technology?</p>
<p>Maybe it&#8217;s just, paradoxically, the boredom? When you think about it, most developers spend big part of their time doing tedious, repeatable tasks (and I&#8217;m not talking here about Java developers only). Or maybe our profession is so young that people born too early simply missed the opportunity to become programmers? (I would like to read some research on this topic but couldn&#8217;t find any.)</p>
<p>Whatever it is, most programmers seem to leave programming and switch to other activities somewhere between 35 and 40. I&#8217;m 34 and I still have enough passion for programming to sustain next couple of years, but then what? If you&#8217;re someone like the person described in first paragraph, perhaps you should sometimes think about next step of your career? What can you do to make it as pleasant and satisfying as your current job? Let&#8217;s iterate through some options:</p>
<h1>Management</h1>
<p>Quite popular &#8220;career path&#8221;, especially in bigger companies. You could be promoted to &#8220;team leader&#8221;, then to &#8220;director of I.T. department&#8221; or even CTO. It all depends how many levels of hierarchy are currently above you. Another direction, if your company prefers some kind of <a HREF="http://en.wikipedia.org/wiki/Matrix_management">matrix management</a>, is becoming a <a HREF="http://en.wikipedia.org/wiki/Software_project_management">PM (Project Manager)</a>, but I&#8217;m not sure if many programmers would consider that a promotion.</p>
<p>However, most programmers lack the skills that a good manager should posses, especially interpersonal skills (some people think that &#8220;programmer&#8221; and &#8220;sociopath&#8221; are synonymous). On the other hand, it&#8217;s easier to become pals with an ex-programmer and such a manager will have better understanding of your difficulties.</p>
<h1>Start your own business</h1>
<p>A manager and a programmer, all in one. There is <a HREF="http://www.paulgraham.com/start.html">plenty</a> <a HREF="http://www.paulgraham.com/boss.html">of</a> <a HREF="http://www.readwriteweb.com/archives/36_startup_tips.php">information</a> <a HREF="http://www.joelonsoftware.com/articles/VC.html">how</a> <a HREF="http://www.miketaber.net/articles/SoftwareStartupMythsDebunked.aspx">to</a> <a HREF="http://www.paulgraham.com/notnot.html">start a start-up</a>. And founding a successful start-up that is later bought for big bucks is a new version of American dream. The biggest downside of this is that <a HREF="http://www.randsinrepose.com/archives/2006/04/20/10.html">most start-ups fail</a>.</p>
<h1>Consulting</h1>
<p>Not really esteemed profession. In theory, consultants are experienced developers that help other companies in case of trouble with their software. In practice, consulting often means just parachuting some suicidal commando programmers in attempt to rescue a sinking project. Most of the time, to miserable effect. And the phrase &#8220;code written by consultants&#8221; has become a synonym for <a HREF="http://thedailywtf.com/">WTF</a>.</p>
<h1>A security (encryption, SEO, &#8230;) expert</h1>
<p>A much better esteemed version of consulting. If you are really an expert in some field of IT, you could earn a nice income by freelance consulting or working for some big company. See also next one.</p>
<h1>Write books, speak at conferences</h1>
<p>Really nice and easy job (or so I heard), but only if you have something to say. Having a widely recognized name helps, too. If you&#8217;re an author of popular application, framework or library, good for you. At the very least, write a popular blog.</p>
<h1>Translator</h1>
<p>As most of the world&#8217;s IT literature is written in English, this is only applicable in non-English speaking countries. But this is quite an easy job (been there, done that), and you don&#8217;t have to have anything to say, unlike the previous one.</p>
<h1>Architect</h1>
<p>Mostly present only at enterprise class systems development. A man with a vision, projecting the architecture, choosing technologies, planning the overall technical structure, writing the code conventions and similar important documents that make you totally enterprisey. A PITA in general, especially if not participating in everyday code development.</p>
<h1>Business analyst</h1>
<p>If you have no problems with talking to business people (not very common among programmers), grok UML and like to &#8220;write programs in English&#8221;, you could go for <a HREF="http://en.wikipedia.org/wiki/Business_analyst">business analyst</a>.</p>
<h1>Tester, sysadmin, deployment specialist</h1>
<p>These people normally coexist with programmers, especially in bigger companies. But I haven&#8217;t heard of any programmers becoming one of them, while they quite often become programmers.</p>
<h1>Scientist</h1>
<p>If you&#8217;re theoretically inclined and grok things like <a HREF="http://en.wikipedia.org/wiki/Big_O_notation">Big-O notation</a> or <a HREF="http://en.wikipedia.org/wiki/NP-complete">NP completeness</a>, that could be a fulfilling job for you. <a HREF="http://en.wikipedia.org/wiki/Computer_science">Computer science</a> is still young and there&#8217;s probably still much to be discovered.</p>
<h1>Full switch</h1>
<p>You can quit programming and start doing something completely different. It&#8217;s up to you. I&#8217;ve read that nowadays people should be prepared to change their profession several times in their lifetime. Who knows, maybe programming will be obsolete in 10 or 20 years from now?</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/szeryf.wordpress.com/42/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/szeryf.wordpress.com/42/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/42/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=42&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2008/03/25/who-do-you-want-to-be-when-you-grow-up/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>
	</item>
		<item>
		<title>Tales from the WTF company, part II</title>
		<link>http://szeryf.wordpress.com/2008/03/20/tales-from-the-wtf-company-part-ii/</link>
		<comments>http://szeryf.wordpress.com/2008/03/20/tales-from-the-wtf-company-part-ii/#comments</comments>
		<pubDate>Thu, 20 Mar 2008 09:36:49 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[WTF]]></category>
		<category><![CDATA[funny]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=41</guid>
		<description><![CDATA[Welcome to the followup of my Tales from the WTF company. If you haven&#8217;t read the first part yet, I&#8217;d suggest you do. Otherwise you&#8217;ll miss important background info and a really funny story, too. This part starts where the last part ended, around noon of the second day.

Let me introduce you to our manager: [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=41&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Welcome to the followup of my <a HREF="http://szeryf.wordpress.com/2008/02/28/tales-from-the-wtf-company-part-i/">Tales from the WTF company</a>. If you haven&#8217;t read <a HREF="http://szeryf.wordpress.com/2008/02/28/tales-from-the-wtf-company-part-i/">the first part</a> yet, I&#8217;d suggest you do. Otherwise you&#8217;ll miss important background info and a really funny story, too. This part starts where the last part ended, around noon of the second day.</p>
<p><span id="more-41"></span></p>
<p>Let me introduce you to our manager: Jola (name changed), a woman in her late thirties with <strong>no technical or managing education</strong>. She was earlier providing HR and legal services for the company, but shortly before I started work there she was asked by Johann (name changed), our German CEO, to become the manager.</p>
<p>I guess that Jola was brought to the company because the CEO was not satisfied with the achievements of his Polish branch: <strong>their application was slow, massive, bug-ridden and adding new features took ages</strong> (he told me about this on the recruitment interview). He also told me that he was looking for a more experienced developer to mend their ways and that was going to be my role after employment.</p>
<h1>Tuesday</h1>
<p>Around noon of the second day Jola called my team to a meeting. She told us that she received a phone call from Johann and he expected our team to do following tasks ASAP: make changes to the layout of some email sent by the application and make some report (that was already done) accessible from their webpage. The guys had some questions about the details of those tasks but she couldn&#8217;t answer them. Instead, <strong>she noted the questions word for word and said she was going to call Johann to ask him</strong> and then she would give us the answers.</p>
<p>After the meeting we went back to our normal activities: I resumed browsing the project source and they resumed chatting about movies on TV, watching game trailers and funny flics on <a HREF="http://youtube.com">youtube.com</a>, showing me the webpage selling some paintball guns they bought recently and other fun activities. I wondered when they were going to start working on the tasks they were given, but I figured that those tasks was probably so easy they can do them anytime. At the end of that day I asked my mentor if he could give some task so I could help them finish faster and he said he would look for something appropriate.</p>
<h1>Wednesday</h1>
<p>Next morning I was assigned my first task: check to see if a particular utility class could be made faster. This class was <strong>another piece of classic <a HREF="http://thedailywtf.com/">WTF</a>-ery</strong>. Its main purpose was to parse XML file the hard way, because who needs any stinking <a HREF="http://docs.python.org/lib/markup.html">built-in</a> <a HREF="http://pyxml.sourceforge.net/">Python</a> classes when you can use <a HREF="http://en.wikipedia.org/wiki/Regular_expression">regexps</a> and individual character manipulations? After parsing the contents of XML file were stuffed into nested instances of this class that exposed a dictionary-like interface.</p>
<p>I started by making a suite of <a HREF="http://en.wikipedia.org/wiki/Characterization_Test">characterization tests</a> first as not to break anything unintentionally. This was the first time that any tests were created for their system so it took me a while setting them up. I asked them why there were no tests and their answer was: <strong>tests are a waste of time</strong>. When I started arguing (being a <a HREF="http://en.wikipedia.org/wiki/Test-driven_development">TDD</a> fan myself), my mentor just cut short the discussion with: <em>when Johann calls you and starts yelling at you, you won&#8217;t have time to write those stupid tests.</em></p>
<p>The yelling part left me with no further arguments and I really started wondering what a mess I have gotten myself into (it was only my third day of work at this company). I resumed my work and by the end of the day I managed to make retrieving values from the above mentioned XML parsing class <strong>about 20 times faster on average</strong>. It was really easy, though, because this class stored the data internally in a dictionary but the lookups on it were done by sequentially iterating through all the keys to find matching one. All I did was replacing the iteration with normal dictionary lookup.</p>
<p>The guys said that the iteration was probably necessary for something in the past, but they could not recall what could it be. They figured that the cause was probably gone, since the system still worked fine after my changes. I was told I should <strong>commit my work to the SVN, but not the tests</strong>, because they <em>&#8220;didn&#8217;t want them to clutter their repository&#8221;</em>.</p>
<h1>Thursday</h1>
<p>Next day I asked my mentor if I could replace the regexp based XML-parsing with some standard classes to make it cleaner and easier to extend. He said no, because their parsing works just fine, thank you. It just <em>&#8220;does what it&#8217;s intended to and there&#8217;s no need to extend it&#8221;</em> (although the code was literally ridden with special cases, multi-storey <code>if</code>s, workarounds and bugfixes that proved it was changed and extended many times already). He also stated that their solution was surely faster than any library could be, because <em>&#8220;it did only what was needed and any library always does many unnecessary things&#8221;</em>. I was told that he would find me another task and I was to leave that XML parsing alone.</p>
<p>Before he could find anything, Jola rushed into our office. She was very angry and told us (almost shouting) that she just had a very unpleasant phone talk with Johann and he demanded that the task he gave us on Tuesday be done today or else. Because of that <strong>she wanted us all to work today as long as it&#8217;s needed to finish those tasks</strong>, even if it takes us whole evening or night. I was quite shocked by this kind of management but other guys seemed used to it. They told her that they&#8217;d had some difficulties but now they were nearing the finish and there&#8217;s nothing to worry about.</p>
<p>After she left, I saw them <strong>working probably for the first time in four days</strong>. Of course, they were still doing many things unrelated to work, but at least they were trying to make some progress. I asked my mentor if he could give me something to work on so I can help them finish faster, but he told me that they have already divided the work and <strong>it&#8217;s too small to be divided further</strong> (which seemed to be true because the tasks Johann gave us looked really easy). He said that since he was too busy with his work to find me another task I should just browse the code and try to learn what it does.</p>
<p>At 17:00 I asked them again if I could help them anyhow, but they told me they were almost finished, just fixing some minor bugs. I decided to go home then, because it made no sense to me to sit there and just wait for them to finish.</p>
<h1>Friday</h1>
<p>Next morning Jola asked me to come to her office. I was expecting some kind of reprimand for not staying at work with the other guys (they stayed until about 20:00 that day) and tried to prepare some explanations. She gave me a talk about how they, being a small startup, should be working twice as hard as the bigger companies and then she said that <strong>she had to fire me and had my walking papers ready</strong>.</p>
<p>After first shock I tried to explain to her why I left earlier and that it&#8217;s too harsh to fire somebody for something like that, but then it struck me: <strong>I didn&#8217;t want to work there anymore</strong>. So I just said: <em>&#8220;I see that you have already made your decision, so there is no use in arguing&#8221;</em>, grabbed my things and left.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/szeryf.wordpress.com/41/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/szeryf.wordpress.com/41/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/41/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/41/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/41/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=41&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2008/03/20/tales-from-the-wtf-company-part-ii/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>
	</item>
		<item>
		<title>Tales from the WTF company, part I</title>
		<link>http://szeryf.wordpress.com/2008/02/28/tales-from-the-wtf-company-part-i/</link>
		<comments>http://szeryf.wordpress.com/2008/02/28/tales-from-the-wtf-company-part-i/#comments</comments>
		<pubDate>Thu, 28 Feb 2008 15:59:14 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[WTF]]></category>
		<category><![CDATA[funny]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=40</guid>
		<description><![CDATA[Some time ago I had a short episode of working for a Polish branch of a Germany based software company. In this entry (and probably a few following) I&#8217;m going to share with you a couple of WTF moments, so if you&#8217;re in for a few good laughs, read on! There is also part II [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=40&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Some time ago I had a short episode of working for a Polish branch of a Germany based software company. In this entry (and probably a few following) I&#8217;m going to share with you a couple of <a href="http://thedailywtf.com/" title="Curious Perversions in Information Technology">WTF</a> moments, so if you&#8217;re in for a few good laughs, read on! <a href="http://szeryf.wordpress.com/2008/03/20/tales-from-the-wtf-company-part-ii/">There is also part II of this story</a>. </p>
<p><span id="more-40"></span></p>
<h1>Monday</h1>
<p>The first day started quite normal: I was introduced by the company manager to all 7 programmers, divided in two teams. I was assigned to the smaller, 3 people team. My first task was to build a computer for myself from parts scattered around the company: the box was here, the harddisk there and the monitor had to be taken &#8220;temporarily&#8221; from one of the servers.</p>
<p>After my computer was up and running, my teammates engaged in a fierce quarrel about which distribution of Linux I should install on my box. As I learned each of them was running a different one and in the second team the situation was looking similar. I chose Ubuntu because the guy sitting next to me (who was assigned as my &#8220;mentor&#8221;) was using it and he had the install CD ready.</p>
<p>Then the other guys started to remind him that he had several problems with this distribution (some related to work and some completely unrelated but that seemed irrelevant to them) and he fought back arguing that they had also  trouble with their distros and it was at least as bad as his own if not worse. From this argument I understood that they had continuous problems with running their app on their systems (as in &#8220;it works on my box, why doesn&#8217;t it work on yours?&#8221;) and spent quite a lot of time trying to fix them. It also seemed that each of them used their own set of incompatible tools and scripts which they developed or configured individually.</p>
<p>Don&#8217;t get me wrong: I&#8217;m not trying to prove that they were completely stupid. It was just the opposite: they were smart, friendly, helpful and fun to talk with. We spend a lot of time talking about their hobbies, cars, games, movies, music and books. But at the same time I started to get a feeling that they were completely amateurish in their work.</p>
<p>To the end of first day I managed to get Ubuntu running, installed Eclipse and some other tools and checked out the project from the SVN. In the meantime, my mentor gave me a talk about the architecture of their system which seemed awfully complicated to me but I decided to keep my comments to myself at least until I get to see and understand the code. The system was written in Python and its main purpose was to process requests from the web app and issue queries to many different vendors, gather the results and send them back to the web app. He also told me that they had a big problem with the system being much too heavy and slow.</p>
<h1>Tuesday</h1>
<p>Next day I started browsing the source and felt my heart sinking like, well, something that is sinking really fast. So fast it&#8217;s going to fall into pieces when it smacks into the bottom of the sea. I hoped that their system would be elegant and beautiful just because of being written in Python. Instead it looked like if someone was trying create Python&#8217;s equivalent of worst PHP anti-patterns. Most of the classes were several thousand lines long and contained code dealing with everything for one vendor. Each of those behemoths sported methods of at least 200 lines long but 500 wasn&#8217;t rare at all.</p>
<p>After taking a closer look I noticed that most of the code was carefully copied/pasted from one place to another. Each of those methods processed one kind of request from start to end: initialized database connection with hardcoded username and password, constructed and issued the query, processed and formatted the results, caught exceptions and so on. I regret not running any metrics on this steaming pile of excrements but my guess was that after the duplicated code would be properly refactored into separate methods, it would be 3 to 4 times smaller. Do I have to add that the system wasn&#8217;t stained with a single line of test code?</p>
<p>I started asking the guys about those problems and their answers shocked me even more. The conversation ran something like this:</p>
<p><strong>Me:</strong> <em>Why don&#8217;t you guys use separate functions to avoid all this code duplication?</em></p>
<p><strong>Them:</strong> <em>Don&#8217;t you know that functions induce time overhead? Calling them and returning just takes too much time.</em></p>
<p><strong>Me:</strong> <em>AFAIK this overhead is negligible in most cases. Have you run some profiler to see if calling functions is really a bottleneck here?</em></p>
<p><strong>Them:</strong> <em>Of course we have. But you see this Python profiler is really stupid. It didn&#8217;t tell us anything useful.</em></p>
<p>I had a hard time believing this but not being an expert in Python profiling myself I decided to leave this path for now and concentrate on other aspects:</p>
<p><strong>Me:</strong> <em>But don&#8217;t you think that this copied/pasted code looks like a mess?</em></p>
<p><strong>Them:</strong> <em>Not at all. You have all the code right before your eyes. You don&#8217;t have to go looking for a function definition to see what it does.</em></p>
<p><strong>Me:</strong> <em>What if the duplicated code contained some bug? Don&#8217;t you think fixing it would be a problem?</em></p>
<p><strong>Them:</strong> <em>How can this be a problem when Eclipse has search&amp;replace function?</em></p>
<p>That&#8217;s it for part one, but stay tuned! <a href="http://szeryf.wordpress.com/2008/03/20/tales-from-the-wtf-company-part-ii/">There is part II of this story</a>.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/szeryf.wordpress.com/40/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/szeryf.wordpress.com/40/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/40/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=40&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2008/02/28/tales-from-the-wtf-company-part-i/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>
	</item>
		<item>
		<title>Multilingual page caching in Ruby on Rails</title>
		<link>http://szeryf.wordpress.com/2008/02/02/multilingual-page-caching-in-ruby-on-rails/</link>
		<comments>http://szeryf.wordpress.com/2008/02/02/multilingual-page-caching-in-ruby-on-rails/#comments</comments>
		<pubDate>Sat, 02 Feb 2008 17:10:22 +0000</pubDate>
		<dc:creator>szeryf</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[cookie]]></category>
		<category><![CDATA[mongrel]]></category>
		<category><![CDATA[multilingual]]></category>
		<category><![CDATA[page caching]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://szeryf.wordpress.com/?p=39</guid>
		<description><![CDATA[There is plenty of stuff written about caching in Ruby on Rails. You can easily cache anything from objects returned by a query to fragments or even whole pages. Especially storing full pages (known as page caching) in a directory when Apache1 can grab them is really efficient. And there are quite decent tutorials about [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=39&subd=szeryf&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>There is plenty of stuff written about caching in Ruby on Rails. You can easily cache anything from objects returned by a query to fragments or even whole pages. Especially storing full pages (known as <strong>page caching</strong>) in a directory when Apache<a href="http://szeryf.wordpress.com/2008/02/02/multilingual-page-caching-in-ruby-on-rails/#footnote1"><sup>1</sup></a><a name="back1"></a> can grab them is really efficient. And there are quite decent tutorials about it.</p>
<p>Sadly, most of the tutorials assume that you live in a small, cozy, speak-english-or-die type of world and your only contact with foreign languages is when you order &#8220;pommes frites&#8221; at MacDonald&#8217;s.<a href="http://szeryf.wordpress.com/2008/02/02/multilingual-page-caching-in-ruby-on-rails/#footnote1"><sup>2</sup></a><a name="back2"></a> The rest of us, working on multilingual applications, might have a lot of problems with implementing page caching. Fortunately, it&#8217;s not that difficult. Read on to see for yourself.</p>
<p><span id="more-39"></span></p>
<h1>The problem</h1>
<p>The main problem is that default Rails caching mechanism tries to <strong>map page URL directly to a path on the disk</strong>. This works in most of the cases, of course, and the rewrite rules in Apache configuration are simple. But if your application might provide <strong>different content for the same URL</strong>, depending on other data (like session settings), you&#8217;re in trouble.</p>
<p>There are many things normally stored in session that can alter what you see on a given page, even if at first glance you might think that the page content is fairly static. Things like whether you are logged in or not, what is your role in the application (admin/regular user), what language you prefer to see the page in and so on. </p>
<p>Tutorials on Rails caching will tell you that in this case you can forget about page caching. If you cannot guarantee that the URL in question will always provide the same content, page caching might be a problem.</p>
<h1>The solution</h1>
<p>To solve it, you have to do two things:</p>
<ol>
<li>Make sure that <strong>every piece of information that can alter the page content is included in cached path</strong>. That is, instead of <code>cache/index.html</code>, your page should probably be stored under something like <code>cache/en_GB/not_logged_in/msie/index.html</code>.</li>
<li>Make sure that <strong>every piece of said information is retrievable by Apache</strong> or it won&#8217;t be able to find the cached page. Retrievable by Apache means URL or cookie. URL can&#8217;t change (else we wouldn&#8217;t have this problem), so our <strong>only option is a cookie</strong>.</li>
</ol>
<p>In the following examples I&#8217;m going to present a simple recipe on how to implement a <strong>&#8220;language-aware&#8221; caching</strong>. I assume that you know how to cache and expire pages in Rails and you know what to cache. If that&#8217;s not the case, please at least read &#8220;Ruby on Rails Caching Tutorial&#8221; first (link below). I also assume that you run a configuration where Apache is serving static content and proxying dynamic content to a cluster of mongrels.</p>
<h1>Move your page cache</h1>
<p>This has nothing to do with multiple languages but it&#8217;s a good practice anyway and all the following examples depend on it, so I&#8217;d recommend that you do this. By default Rails stores cached pages right inside your application&#8217;s <code>public</code> directory. This is not the best choice IMHO because it&#8217;s hard to differentiate real static pages from cached dynamic pages, which makes it difficult to purge the whole cache. Add following line in your <code>environment.rb</code>.</p>
<pre>config.action_controller.page_cache_directory =
  RAILS_ROOT + "/public/cache/"</pre>
<h1>Store language in a cookie</h1>
<p>First, we must guarantee that the <strong>language chosen by user is stored in a cookie</strong>. How exactly you implement the choosing part is up to you. In our application, there&#8217;s a <code>before_filter</code> that checks many things like session, domain, subdomain, <code>ACCEPT_LANGUAGE</code> header etc. When the language is determined, we set a cookie like this:</p>
<pre>class ApplicationController &lt; ActionController::Base
  before_filter :set_language
  ...
private
  def set_language
    lang = ...
    cookies[:lang] = lang.locale_code
  end
end
</pre>
<p>Now, every request that makes it to Rails, will have a cookie with the language set. Be careful about the &#8220;makes it to Rails&#8221; part. If your link for changing language points to a cached page (I have been bitten by this), the change will not work, because the page will be served by Apache and you application server will not even see it.</p>
<p>Also note that even if the user prefers e.g. Italian, but your application has no Italian version and you serve them English version instead, you should save the real language of the content in the cookie, or else you will have duplicate pages in cache. This implies, obviously, that your code should be aware what languages your application is localized in.</p>
<h1>Add language to cached page path</h1>
<p>Next thing we have to do is to <strong>add language information to cache path</strong>. We can do this by overriding <code>cache_page</code> and <code>expire_page</code> class methods of <code>ApplicationController</code> like this:</p>
<pre>class ApplicationController &lt; ActionController::Base
  ...
  class &lt;&lt; self
    def cache_page content, path
      super content, GetText.locale.to_s + path
    end
    def expire_page path
      Language.all_localized.each do |lang|
        super lang.locale_code + path
      end
    end
  end
end
</pre>
<p>I tried to use our freshly baked <code>cookie[:lang]</code> in <code>cache_page</code> method, but this didn&#8217;t seem to work well with tests, so I took the easiest around it with <code>GetText.locale.to_s</code>. If you use some other library in your application, you&#8217;ll have to find its own way to determine the locale (it shouldn&#8217;t be to hard).</p>
<p>In <code>expire_page</code> method we have to clean all versions of saved pages, not only the current one. <code>Language.all_localized</code> returns a list of all languages that we have localized our application in (all three of them), you probably have something similar in your code.</p>
<h1>Configure Apache to find the cached pages</h1>
<p>The last part is to <strong>setup Apache rewriting rules so it can find the cached pages using the language saved in our cookie</strong>. In the Apache configuration file for you application (something like <code>/etc/apache2/sites-enabled/YourAppName</code>), add:</p>
<pre>RewriteEngine On
RewriteCond %{HTTP_COOKIE} lang=(en_GB|de_DE|pl_PL) [NC]
RewriteRule ^([^.]+)$ /cache/%1/$1.html [QSA]
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://mogrel_cluster%{REQUEST_URI} [P,QSA,L]
&lt;Proxy balancer://mogrel_cluster&gt;
  BalancerMember http://127.0.0.1:3000
  ...
&lt;/Proxy&gt;
</pre>
<p>Basically, these rules tell Apache to read cookie <code>lang</code> and use it in cache lookup. The crucial part is <code>/cache/%1/$1.html</code>, where <code>$1</code> is the URL requested and <code>%1</code> is the value of the cookie.</p>
<p>Now you&#8217;re ready to restart Apache and enjoy your multilingual application at much higher speed!</p>
<h1>Troubleshooting</h1>
<p>So, you&#8217;ve done everything exactly as above and nothing happens? Or even worse, Apache or Mongrel crashes? Here are some problems I have encountered and solved:</p>
<ul>
<li>Check if you have really <strong>deployed your application with all the changes and restarted Mongrels and Apache</strong>. Yeah, I know you couldn&#8217;t have possibly miss it, but please check anyway. I have forgotten to deploy this or restart that a couple of times myself.</li>
<li>Make sure that your browser lets you <strong>see the response headers</strong> so you can check whether the page was served by Mongrel (dynamically) or Apache (cached) and page loading time. For Opera I recommend <a href="http://dev.opera.com/tools/" title="Tools - Opera Developer Community">Developer Console</a> and there&#8217;s <a href="https://addons.mozilla.org/en-US/firefox/addon/1843">Firebug</a> for Firefox.</li>
<li>
    If you would like to experiment in development mode<a href="#footnote3"><sup>3</sup></a><a name="back3"></a>, don&#8217;t forget to turn caching on in <code>development.rb</code> with:</p>
<pre>config.action_controller.perform_caching = true</pre>
</li>
<li>
    Make sure you have <strong>set your application&#8217;s <code>DocumentRoot</code> correctly</strong> in Apache configuration file for you application. It should look something like:</p>
<pre>DocumentRoot /var/proj/YourAppName/current/public</pre>
<p>    Also see next bullet.
  </li>
<li>
    You have set <code>DocumentRoot</code> and now you&#8217;re getting a 500 error? Don&#8217;t panic. Check your <code>/var/log/apache2/error.log</code> file. If you see the following error: <i>Option FollowSymLinks not allowed here</i> (or similar, or something about symbolic links), add following lines above the <code>DocumentRoot</code> setting:</p>
<pre>&lt;Directory /var/proj/YourAppName&gt;
       Options FollowSymLinks
       AllowOverride All
&lt;/Directory&gt;
    </pre>
</li>
</ul>
<p>If you have any other problems, don&#8217;t hesitate to ask. I&#8217;ll try to help if only my limited knowledge of Apache configuration allows me to. If anything is problematic or can be done better, I&#8217;d be very glad to hear it. If you use something other than Apache/Mongrel Cluster/GetText and managed to implement this solution, please share.</p>
<h1>Resources</h1>
<p>For Google-impaired, here is a short list of resources. There are of course many more of them, but the ones below contain all the information you need to setup what I present here. If you had read them earlier, you wouldn&#8217;t have to read this article :)</p>
<ul>
<li><a href="http://www.railsenvy.com/2007/2/28/rails-caching-tutorial">Rails Envy: Ruby on Rails Caching Tutorial</a></li>
<li><a href="http://www.ethelred.org/articles/2006/10/22/conditional-use-of-page-cache-in-rails">The Junction &raquo; conditional use of page cache in Rails</a></li>
<li><a href="http://www.askapache.com/htaccess/htaccess-fresh.html">Fresh .htaccess Examples: Cookies, Variables, Custom Headers</a></li>
</ul>
<hr />
<p><a name="footnote1"></a><a href="#back1"><sup>1</sup></a> <font size="1">Or any other fast HTTP server you happen to be using, of course. But the examples are for Apache only, sorry.</font></p>
<p><a name="footnote2"></a><a href="#back2"><sup>2</sup></a> <font size="1">This is supposed to be a joke. If you had to look here, it&#8217;s probably not that funny.</font></p>
<p><a name="footnote3"></a><a href="#back3"><sup>3</sup></a> <font size="1">Unfortunately, if you followed my recommendation and changed default cache placement, it won&#8217;t work with Mongrel. The cached pages are stored where they should be but not read back by Mongrel, because it ignores this setting. This seems to be a known problem but I couldn&#8217;t find a fix for it. You&#8217;ll get the information about caching and expiring pages in <code>development.log</code> and this should be sufficient in most cases. You can also try to setup an Apache server for your development use.</font></p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/szeryf.wordpress.com/39/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/szeryf.wordpress.com/39/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/szeryf.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/szeryf.wordpress.com/39/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/szeryf.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/szeryf.wordpress.com/39/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/szeryf.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/szeryf.wordpress.com/39/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/szeryf.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/szeryf.wordpress.com/39/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/szeryf.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/szeryf.wordpress.com/39/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=szeryf.wordpress.com&blog=1233362&post=39&subd=szeryf&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://szeryf.wordpress.com/2008/02/02/multilingual-page-caching-in-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">szeryf</media:title>
		</media:content>
	</item>
	</channel>
</rss>