From: Steven Jenkins Date: 2005-03-13T02:51:39+09:00 Subject: Re: tree transformation insight required Luke Graham wrote: > Hi list, > > I was wondering if anyone would have some insight into a problem Ive got. > > Im taking an xml document (looks very much like a w3c schema with some > extra attributes) and transforming it into c++ code. The method I use looks > something like... > > def recurse(file, func, element) > case func > when "declare" > file << element.attributes["type"] << element.attributes["name"] > when "instantiate" > file << element.attributes["name"] << " = new " << element.attributes["type"] > do wierd stuff based on type and state > end > element.each_child { |c| > recurse file, func, c > } > end > >[....] > > Id like to get the logic out of the recurse statement for three reasons. > First of all, Im starting recurse up more times than Ive shown > above, because I have four separate sets of header/cpp templates, > not to mention I would like to add other templates that arent c++ code. > It would be good to know that each case could be handled safely > without interfering with each others output and special cases. > Secondly, someone else would like to write their own templated > code, and their required output would be different. Thirdly, recurse is > simply becoming scary. I've done something similar to your first alternative, but using blocks. That's somewhat more Rubyesque, IMO. (This is not for XML, but the idea's the same.) def descend_with_indicators(depth, &block) yield :item, depth, self.item unless children.empty? yield :down, depth, nil children.each do |c| c.descend_with_indicators(depth + 1, &block) end yield :up, depth, nil end end Invoke it as root.descend_with_indicators(0) do |ind, dpth, item| # ind will be one of :down, :item, or :up # :down and :up indicate change in depth # :item indicates an actual node in the tree # if you don't need depth, you can omit it everywhere end Steve