From: "Eric I." Date: 2008-08-10T23:52:47+09:00 Subject: Re: DSL challenge. Do you guys have any elegant ideas? Hi Patrick, Here's another solution. You didn't specify the problems you were having, so I can't be certain whether this solution avoids them. Eric ==== Ruby training and Rails training available at http://LearnRuby.com . ==== module Farm class << self def create(&block) @scope_stack = [] push_frame(:farm) class_eval(&block) "Farm contains\n[\n" + indent(pop_frame) + "\n]\n" end def barn(&block) push_frame(:place) class_eval(&block) append_to_frame "Barn contains\n[\n" + indent(pop_frame) + "\n]\n" end def pond(&block) push_frame(:place) class_eval(&block) append_to_frame "Pond contains\n[\n" + indent(pop_frame) + "\n]\n" end def animal(name) raise "IllegalMethodError -- animal can only be called " \ "under a place" unless top_frame[0] == :place append_to_frame name + "\n" end private def push_frame(description) @scope_stack.push [description, ""] end def pop_frame @scope_stack.pop[1] end def top_frame @scope_stack[-1] end def append_to_frame(str) top_frame[1] << str end def indent(str, level = 2) str.split("\n").map { |s| " "*level + s }.join("\n") end end end string = Farm.create do barn do animal "dog" animal "cat" end pond do animal "whale" animal "shark" end end puts string