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.


Follow me on Twitter to keep up with what I’ve learned building my personal finance tool, Stash.

Subscribe to my mailing list to learn more about technology and business.

Your email will never be shared with anyone else.

Read more posts …
Written: December 28th, 2011
Categories: ruby, domain-specific-languages, dsl