On 9/7/05, Joe Van Dyk <joevandyk / gmail.com> wrote: > On 8/18/05, Jacob Fugal <lukfugl / gmail.com> wrote: > > > node :node1 do > > > ip 192.whatever > > > title "Node 1" > > > end > > > > > > node :node2 do > > > ip 192.whatever > > > title "Node 2" > > > end > > > > <snip> > > > > > class ClusterManager > > > > > > def load_config_file config_file > > > instance_eval File.read(config_file) > > > end > > > > > > def node node_id, &block > > > # What goes here? > > > end > > > > > > end > > > > I'd think similarly, but a bit different in that > > ClusterManager::Builder should be the one doing the instance eval: > > > > class ClusterManager > > attr_accessor :nodes > > > > def initialize > > @nodes = [] > > end > > > > def describe > > @nodes.collect{ |node| node.describe }.join("\n") > > end > > > > class Node > > attr_accessor :id, :ip, :title > > > > def initialize( id ) > > @id = id > > end > > > > def describe > > "#@id -> #@ip \"#@title\"" > > end > > > > class Builder > > def process( node, dsl ) > > @node = node > > instance_eval &dsl > > end > > > > def ip( value ) > > @node.ip = value > > end > > > > def title( value ) > > @node.title = value > > end > > end > > end > > > > class Builder > > def process( manager, dsl ) > > @manager = manager > > @node_builder = Node::Builder.new > > instance_eval &dsl > > end > > > > def node( node_id, &block ) > > node = Node.new( node_id ) > > @node_builder.process( node, block ) > > @manager.nodes << node > > end > > end > > end > > > > dsl = lambda{ > > node :node1 do > > ip '192.whatever' > > title 'Node 1' > > end > > > > node :node2 do > > ip '192.whatever' > > title 'Node 2' > > end > > } > > > > manager = ClusterManager.new > > builder = ClusterManager::Builder.new > > builder.process( manager, dsl ) > > > > puts manager.describe > > > > ############### > > > > A few caveats about the above: > > > > 1) You'll notice I changed the DSL a little (quoted the 192.whatever > > values). That was simply for brevity in this illustration. > > > > 2) My Builders require the argument to process be lambdas (Procs) not > > strings. This was because I didn't want to complicate things with > > switches on whether to use the prefix & or not. But it would be as > > simple as an if/else to hide the lambda/string distinction from the > > "user" (which will be yourself, not the person writing in the DSL) > > inside the Builder. Alternatively, you can take a string and build it > > into a lambda for the Builder via eval("lambda{ #{dsl} }"). I wouldn't > > necessarily recommend that though (with all the evils of eval). > > Thank you for your ideas. I've adapted it somewhat for parts of my > application, but I'm running into problems. > > I've got the following configuration file: > > option :display do > display :text, :size => 20, :title => "DISPLAY" > value :DISPLAY, :default => ENV['DISPLAY'] || 'localhost:0' > end > > argument :xterm_title do > display :text, :size => 20, :title => "Xterm Title" > value "-T", :default => "You are on a xterm!" > end > > argument :xterm_text_color do > display :text, :size => 20, :title => "Xterm Font Color" > value "-fg", :default => "red" > end > > > application :xterm do > executable "/usr/X11R6/bin/xterm" > title :Xterm > node :fatire > options :display > arguments :xterm_text_color, :xterm_title > end > > application :xeyes do > executable "/usr/X11R6/bin/xeyes" > title :Xeyes > node :fatire > options :display > end > > > Should be self-explanatory. I have some applications that take env > options and command-line arguments, and I want to have a very readable > and configurable file for defining those applications, options, and > arguments (and some other things). The 'node' option for the > application is the machine that the application should be started on. > The 'display' option for the options/arguments state how the GUI > should display the option/argument. > > My problem is trying to adapt your solution to fit something like > this. There would be a lot of duplication if I had Builders for > applications, nodes, options, and arguments. And I'm also having some > difficulties getting each Application object to know what options and > arguments it should have. > > I considered using YAML for the configuration file format, but I'm > still leaning towards having a pure Ruby file. > > Thoughts are greatly appreciated! This is my first time trying to do > this type of programming, so it's a little weird. > I would also like to be able to 'group' things together, like group :xterm_options_arguments do arguments :xterm_title, :xterm_text_color options :display end application :xterm do group :xterm_options_arguments title :Xterm ... end So that applications with common options and arguments can specify a grouping. (btw, an 'argument' is a command-line argument, like 'ls -F'... the -F is an argument. An option is something like "DISPLAY=my_machine:1 xeyes".. the DISPLAY is an option).