"Nicholas Van Weerdenburg" <vanweerd / gmail.com> schrieb im Newsbeitrag news:632154f705010520196f99e845 / mail.gmail.com... > On Thu, 6 Jan 2005 05:56:31 +0900, Robert Klemme <bob.news / gmx.net> wrote: >> >> "Nicholas Van Weerdenburg" <vanweerd / gmail.com> schrieb im Newsbeitrag >> news:632154f705010510264aea7a10 / mail.gmail.com... >> > Hi all, >> > >> > I've written a small ruby application that uses YAML and the >> > associated hash/array Ruby structure. >> > >> > I am now looking to do some query-like actions on the basic ruby data >> > structure. I'm wondering if there are any packages of >> > query-abstractions that make sense for Ruby in a generalized sort-of >> > way. E.g. XPath and XQuery for XML, SQL for RDMS, etc. >> > >> > Currently I've written my structure-parsing code with a few of my >> > cases, and I'm starting to refactor with blocks and lambdas in order >> > to keep duplication low and offer an easily configurable higher-level >> > of abstraction. Now the code is starting to pressure me to create a >> > simple query language. Maybe I should go to a ruby db or sqlite, but I >> > expect I ultimately only need the most basic functionality. >> > >> > Any suggestions or recommendations? >> >> Another thought: maybe you can even use Ruby itself. I mean, one can >> produce quite readable select expressions in Ruby and we have >> Enumerable#all?, #any? etc. You might want to add some functionality for >> recursive traversal though. >> >> Kind regards >> >> robert >> >> > > I like the idea of using Ruby, and have been extending my code in that > manner. However, XML becomes interesting soon because of it's DOM > traversal capabilities. > > I'm also wondering if I'm missing some common Ruby/Perl/Python idiom > for handling in-memory data-structure traversal in a more abstract > way, but so far it doesn't look like it. > > Does it make sense to have a general data-structure traversal/query > api in a language like Ruby? I'd say yes, but maybe only for certain types (DOM tree nodes) - not necessarily for general Hash, Array and the like. OTOH you can cook up something quite easily though: class Object def traverse() yield self end end module Enumerable def traverse(&b) each {|o| o.traverse(&b)} end end class Hash def traverse(&b) each {|k,v| v.traverse(&b)} end end Note that this does not take care of looks in the object graph. To do that, you need to do a bit more: class Object def traverse(context = {}) context[self.id] ||= (yield self; true) end end module Enumerable def traverse(context = {}, &b) unless context[self.id] context[self.id] = true each {|o| o.traverse(context, &b)} end end end class Hash def traverse(context = {}, &b) unless context[self.id] context[self.id] = true each {|k,v| v.traverse(context, &b)} end end end Kind regards robert