# from http://www.jayfields.com/src/dslcontext.txt script = <<-eos if the '$5-$10 Limit' list is more than 12 then notify the floor to open if the '$1-$2 No Limit' list is more than 15 then notify the floor to open if the '$5-$10 Limit' list is more than 8 then notify the brush to announce if the '$1-$2 No Limit' list is more than 10 then notify the brush to announce eos class Broadcast def self.notify(stakes, options) puts DslContext.sym_to_stakes(stakes) options.each_pair do |name, value| puts " #{name} #{value}" end end end class List def self.size_for(stakes) 20 end end class DslContext def self.execute(text) rules = polish_text(text) rules.each do |rule| result = self.new.instance_eval(rule) yield result if block_given? end end def self.bubble(*methods) methods.each do |method| define_method(method) { |args| args } end end def self.polish_text(text) rules = text.split("\n") rules.collect do |rule| rule.gsub!(/'.+'/,extract_stakes(rule)) rule << " end" end end def self.extract_stakes(rule) stakes = rule.scan(/'.+'/).first stakes.delete!("'").gsub!('$','dollar').gsub!('-','dash').gsub!(' ','space') end def self.sym_to_stakes(sym) sym.to_s.gsub!('dollar','$').gsub!('dash','-').gsub!('space',' ') end end class ContextOne < DslContext bubble :than, :is, :list, :the, :to def more(value) '> ' + value.to_s end def method_missing(sym, *args) @stakes = sym eval "List.size_for(sym) #{args.first}" end def floor(value) __position(value, :floor) end def brush(value) __position(value, :brush) end def open __action(:open) end def announce __action(:announce) end def __action(to) { :action => to } end def __position(value, title) value[:position] = title value end def notify(value) [@stakes, value] end end class ContextTwo < DslContext bubble :than, :is, :list, :the, :to, :more, :notify, :floor, :open, :brush def announce @stakes end alias open announce def method_missing(sym, *args) @stakes = sym end end class ContextThree < DslContext bubble :than, :is, :list, :the, :to, :more, :notify, :announce, :open, :open def announce; end def open; end def brush(value) :brush end def floor(value) :floor end def method_missing(sym, *args) true end end module Kernel def silence_warnings # multiple assignment old_verbose, $VERBOSE = $VERBOSE, nil yield ensure $VERBOSE = old_verbose end end silence_warnings do puts "\nContext One:" ContextOne.execute(script) do |notification| Broadcast.notify(*notification) end puts "\nContext Two:" ContextTwo.execute(script) do |stakes| puts ContextTwo.sym_to_stakes(stakes) end puts "\nContext Three" ContextThree.execute(script) do |positions| puts positions end end