David Heinemeier Hansson, the creator of Rails is doing an outstanding series of blog posts on his blog to derail (pun intended) some common myths that claim Rails does not do this or that and that hinders (or rather, slows down) its widespread acceptance.

I am sure David holds his best for last and will refute the infamous “Rails does not scale” in the final episode of the series.

I have just returned from Madrid where the Spanish Rails Conference, Conferencia Rails was held. I liked it quite a lot, there were several interesting talks most of which made me want to learn all of that and very fast (one thing conferences do to me is to boost that healthy feeling of wanting to always learn and discover new things). So I would like to add my e-voice to the web noise: congratulations and thank you to the organizers and presenters!

I recently spent some time debugging while I can’t connect to a local postgreSQL database. I wanted the nice_db database to be accessible to all local users (not real names) without any authentication. The “trust” authentication method was what I needed for this scenario, I was sure of this much. So I set up an authentication record in the configuration file below the one that existed by default:

# TYPE  DATABASE    USER    CIDR-ADDRESS    METHOD
LOCAL    ALL          ALL                   ident sameuser
LOCAL    nice_db      ALL                   trust

But this gave me the following error and denied access:

psql: FATAL:  Ident authentication failed for user “balint”

I tried several things making the second record more allowing each time (in fact, what you see above is the final, most liberal version) to no avail. I then swapped the order of the two records and finally was granted access.

Of course, I should have been wiser and apply the grand old RTFM principle. The PostgreSQL documentation states in very clear terms how each line in the pg_hba.conf is accessed:

The first record with a matching connection type, client address, requested database, and user name is used to perform authentication. There is no “fall-through” or “backup”: if one record is chosen and the authentication fails, subsequent records are not considered. If no record matches, access is denied.

For my particular case, the “local all all ident sameuser” record blocked access to all databases but to those whose name matched that of the operating system’s user (that’s what the ident sameuser does) since that matches all user and database names.

Beyond the mechanics of PostgreSQL authentication (put the authentication records that match more users/databases below the ones that are more specific), I have learned something which is more precious and that I can put into good use in the future: RTFM!

I read a few posts about how good fit Ruby is for building DSLs, Domain Specific Languages. Ever the curious I have been waiting for the opportunity to build a very simple one for a particular problem.

Well, I did not have to wait very long (when you have a hammer everything looks like a nail). I needed a quick method which generates nice html graphs for my post about browser javascript engine benchmarking. After spending a few minutes searching for a free tool (I did not want anything fluffy, just something very basic) I hit the nail in the head with my hammer. Only the nail was the generated HTML charts for my post and the hammer, (my desire to build) a DSL in Ruby.

I would like to say it was difficult but in fact it was a piece of cake with Ruby (and armed with the knowledge of previous DSL builders). The solution is composed of the following three parts:

  1. The DSL file which defines the charts
  2. The interpreter which understands the definitions in the DSL file
  3. The “controller” which just passes the data contained in the DSL file to the interpreter

So let’s see each part separately:

browser_js_benchmarks.dsl (the DSL)

chart "Score" do |c|
	c.add "Safari 3.1.2" => 164
	c.add "Firefox 3.0.1" => 156
	c.add "Shiretoko" => 145
	c.add "Google Chrome" => 1589
end

chart.rb (the interpreter)

require "math_aux"
 
class ChartDSL
 
	Template = %(<table border="0" cellspacing="5" cellpadding="5"><caption>%%CAPTION%%</caption>%%ITEMS%%</table>)
	Background_colors = %w(red blue green yellow grey)
 
	attr_reader :values
	def initialize
		@charts = Array.new
		@values = Hash.new
	end
 
	def chart(name)		
		@name = name
		yield self
		@charts.push(make_html)
	end
 
	def add(name_and_value)
		@values ||= Hash.new
 		@values.merge!(name_and_value)
	end
 
	def load(filename)
		# c = new
		instance_eval(File.read(filename), filename)
		write_output
	end
 
	def make_html
		sorted_pairs = @values.sort_by { |v| - v[1] }
		vals = sorted_pairs.map { |p| p[1] }
		norm_values = MathAux::normalize(vals, 100.0)
		html = Array.new
		sorted_pairs.each_with_index do |pair, i|
			name, value = pair
			html.push(%Q(<tr><td>#{name}</td><td><div style="width:#{norm_values[i]}px;background-color:#{ChartDSL::Background_colors[i]}">&nbsp;</div></td><td>#{value}</td></tr>))
		end
		filled_chart = ChartDSL::Template.sub("%%CAPTION%%", @name)		
		filled_chart.sub("%%ITEMS%%", html.join)
	end
 
	def write_output
		File.open("generated_charts.html", "w") do |f|
			f.write(@charts)
		end
	end
end

chart_loader.rb (the controller)

require "chart"
class ChartLoader
	def self.load_chart(dsl_filename)
		c = ChartDSL.new
		c.load(dsl_filename)
	end
end
 
if __FILE__ == $0
	ChartLoader.load_chart(ARGV[0])
end

For the sake of completeness here is math_aux.rb:

module MathAux
	def self.normalize(numbers, to=1.0)
		norm_rat = to / numbers.max
		numbers.map { |n| n * norm_rat }
	end
end

To generate the charts, one only has to run “the interpreter” with a dsl file as the first parameter:

ruby chart_loader.rb browser_js_benchmarks.dsl

The output is called generated_charts.html and contains the following:

<table border="0" cellspacing="5" cellpadding="5">
<caption>Score</caption>
 <tr>
  <td>Google Chrome</td>
  <td><div style="width:100.0px;background-color:red">&nbsp;</div></td>
  <td>1589</td>
 </tr>
 <tr>
  <td>Safari 3.1.2</td>
  <td><div style="width:10.3209565764632px;background-color:blue">&nbsp;</div</td>  <td>164</td></tr>
 <tr>
  <td>Firefox 3.0.1</td>
  <td><div style="width:9.81749528005034px;background-color:green">&nbsp;</div</td> <td>156</td>
</tr>
<tr>
 <td>Shiretoko</td>
 <td><div style="width:9.12523599748269px;background-color:yellow">&nbsp;</div</td><td>145</td>
</tr>
</table>

Note that in ~30-40 code lines we have a “language interpreter”, one that understands the chart DSL and spits out some HTML code that represents the charts. Of course there is plenty of room for improvement, like having the same color denote the same actor between charts (Firefox 3.0.1 should always be the blue bar, for example, unlike in my post), using a better solution for the template strings, adding the possibility of pie charts (although “standard” HTML is not very flexible on different chart forms, one would probably have to use a <canvas> ), and so on.

The essential thing is that it works and it does what the particular situation demanded. It took me a couple of interrupted hours plus the time to read through two related posts which is not that much given that I now have a “tool” (once again, I feel a bit conceited to call it that) which I can use for my future posts whenever the need arises. A custom hammer for my custom nail.

(If you care, feel free to download, use and modify the source code located here)

I returned two weeks ago from the fantastic Euruko 2008 conference in Prague dazzled by the outstanding presentations and the power of Ruby. It is hard to pick a favorite but I especially liked David Black’s “Per-Object Behavior in Ruby” (slides hopefully coming up) mainly because I am a sucker for metaprogramming and the true object-orientedness of Ruby in all its glory.

One fundamental concept was the singleton class which I think I’ve finally understood from this session. His example was the OpenStruct class whose instances learn to respond to all messages sent to them (this is Smalltalk/Ruby parlance, we could also say they learn to handle method calls) instead of throwing a NoMethodError. So I thought a great way to gain an insight of how this works is to actually code that up myself. Here is what I got:

require 'test/unit'
class QuickAdaptor
  def method_missing(method_id, *args)
    method_name = method_id.to_s
    if method_name =~ /=$/
      attr = method_name.to_s.chop
      self.class.class_eval do
        define_method method_id do |x|
          instance_variable_set("@#{attr}", x)
        end
        method_name.chop!
        define_method method_name.to_sym do
          instance_variable_get "@#{attr}"
        end
      end
      instance_variable_set("@#{attr}", args[0])
    end
  end
 
end
 
class QuickSingletonAdaptor
  # does the same as QuickAdaptor
  # but only defines methods for singleton
  # class of object, so it is not the class
  # that "learns", but the singleton class
  def method_missing(method_id, *args)
    method_name = method_id.to_s
    if method_name =~ /=$/
      attr = method_name.to_s.chop
      singleton_class = class << self ; self; end
      singleton_class.instance_eval do
        define_method method_id do |x|
          instance_variable_set("@#{attr}", x)
        end
        method_name.chop!
        define_method method_name.to_sym do
          instance_variable_get "@#{attr}"
        end
      end
      instance_variable_set("@#{attr}", args[0])
    end
  end
 
end
 
if __FILE__ == $0
  class ModuleTester < Test::Unit::TestCase
 
    def test_quick_adaptor_creates_methods
      qa = QuickAdaptor.new
      qa.age = 18
      assert_equal(18, qa.age)
      qa.age = 24
      assert_equal(24, qa.age)
      assert_equal(nil, qa.name)
      qa.name = 'joe'
      assert_equal('joe', qa.name)
      assert(!qa.respond_to(:nam))
    end
 
    def test_quick_adaptor_creates_instance_methods
      qa1 = QuickAdaptor.new
      qa1.age = 18
      qa2 = QuickAdaptor.new
      assert(qa2.respond_to?(:age=))
      assert(qa2.respond_to?(:age))
      assert_equal(nil, qa2.age)
    end
 
    def test_quick_singleton_adaptor_creates_singleton_methods
      qa1 = QuickSingletonAdaptor.new
      qa1.age = 18
      qa2 = QuickSingletonAdaptor.new
      # qa2 at this point should not know anything!
      assert(!qa2.respond_to?(:age=))
      assert(!qa2.respond_to?(:age))
    end
 
  end
end

As a test enthusiastic I embedded the tests in the same file which also has the advantage of giving a documentation of what the code achieves.

You can see that the real difference between the QuickAdaptor and QuickSingletonAdaptor classes lies in the following lines:

class QuickAdaptor
  ...
  self.class.class_eval do
    define_method method_id do |x|
      ...
    end
  end
end
class QuickSingletonAdaptor
  ...
  singleton_class = class << self ; self; end
  singleton_class.instance_eval do
    define_method method_id do |x|
      ...
    end
  end
end

You can see from the tests that the QuickAdaptor shares the knowledge it gained with its peers (other QuickAdaptor instances), whereas QuickSingletonAdaptor is an egoist, it keeps it to itself! That’s why I agree with David Black that the best way to call the class that only one instance can access is singleton class because this has more expressive power than other terms (e.g metaclass, eigenclass, etc.)

My goal is to act like the QuickAdaptor, to suck in all ruby knowledge and learn as fast as QuickAdaptor does while having fun at the same time!

ps. I have also taken a look at how Matz’s OpenStruct class accomplishes the same (well, much more :) ). It uses a table of fields where each new “member method” is defined. Nice.