From: Luke Graham Date: 2005-03-09T19:00:46+09:00 Subject: tree transformation insight required 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 headerfile << "some template" doc.each_child { |c| recurse headerfile, "declare", c } headerfile << "some more template" cppfile << "some template" doc.each_child { |c| recurse cppfile, "instantiate", c } cppfile << "some more template" (I know doc can only have one child but I use the xpath bit of rexml, like doc.elements.each("/*/foo"), just couldnt be bothered typing it) Needless to say, recurse is now ~500 lines, and has more than a few oddities like a begin-ensure block, special cases that dont recurse, about 4 places where it calls itself, some of which dont use the same function they were passed, lots of places that do strange things to the state and so on. 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. Can anyone suggest a good way to get the c++-producing code out of recurse and into some sort of template language, or into functions that get passed into simplified recurse? I figured those functions would need to return functions (usually themselves) to simulate some state changes, ala... def recurse(file, func, element) file << func.call "pre", element element.each_child { |c| recurse file, func.call("getfunc",element), c } file << func.call "post", element end Or would I be better doing this... def sampleDeclare(file, element) ... end def startDeclare(file, element) file << "pre declare" element.each_child { |c| sampleDeclare.call file, c # choose different funcs based on state } file << "post declare" end startDeclare headerfile, doc.root I think that dragging state around might get hard after a while tho and the recursion would be specified many times. Sorry for the long post and thanks for reading this far! -- Luke