Expressive domain specific languages (dsl) in ruby

In this example, I’m creating a User object such that I can set the name using my own DSL:

class User
  def initialize &block
    if block.arity == 1
      block[self]
    else
      instance_eval &block
    end
  end

  def name new_name = nil
    @name ||= new_name
  end

  def location new_location = nil
    @location ||= new_location
  end

  def occupation new_occupation = nil
    @occupation ||= new_occupation
  end
end

u = User.new do
  name       "Travis Jeffery"
  location   "Toronto, Ontario"
  occupation "Mathematician, Software Engineer"
end

###
#
# > u.name
# => "Travis Jeffery"
# > u.location
# => "Toronto, Ontario"
# > u.occupation
# => "Mathematician, Software Engineer"

The reason for checking the arity of the block given is so you can support the case when a user of our API would use it like so:

u = User.new do |u|
  u.name "Travis Jeffery"
end

Personally, I’d be inclined to support only one interface—my preference being the first one.

Learn more about technology and business by subscribing to my mailing list
Read more posts …
Written: December 28th, 2011
Categories: ruby, domain-specific-languages, dsl