"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