From: Joel VanderWerf Date: 2010-10-26T05:51:44+09:00 Subject: Re: DSL and indirection question On 10/25/2010 12:20 PM, Matt Lawrence wrote: > I'm trying to figure out the best way of writing a script that describes > various requirements in the form of "12.34.56" (from a requirement > document) that I can then create methods for reporting, verifying and > remediating the requirment on a system. > > This is script for checking and fixing systems based on a bunch of > security requirements. There are a couple of hundred rules and a few > hundred systems. I am thinking about building a hash of Procs, but I > think it is going to be too ugly. Any suggestions on a clean and easy to > read way of doing this? Maybe this helps, at least on the syntactic side (it's still a hash of procs underneath): hash_builder = proc {|h,k| h[k] = Hash.new(&hash_builder)} @rules = Hash.new(&hash_builder) @stack = [] def section name, &block begin @stack.push name yield ensure @stack.pop end end def rule name, &block section = @stack.inject(@rules) {|sect,n| sect[n]} context = (@stack + [name]).join(".") section[name] = proc do block.call(context) end end section 27 do section "B" do rule 6 do puts "this is 27B-6" end rule "foo" do |name| puts "this is #{name}" end end end section 70 do section 1 do rule 9 do |name| puts "this is rule #{name}" end end end require 'pp' pp @rules puts @rules[27]["B"][6].call @rules[70][1][9].call __END__ Output: {27=> {"B"=> {6=>#, "foo"=>#}}, 70=>{1=>{9=>#}}} this is 27B-6 this is rule 70.1.9