How do I recursively traverse a data structure containing a mix of types?

For starters, I'm a total ruby noob who needs to be able to structure
the input data in such a way that it can be accessed & structured
sensibly.
I found an example on here that I've modified to the best of my
ability..but it does not do what I want.
The attached input file contains a real-life piece of data.

Here is the recursive function: I appreciate anyone who'd take a stab at
this.

def strip_hash_values(hash)

#hash.each_value do |v|
  hash.each do |v|
    puts " strip_hash_values -- >"
    case v
      when String then puts "STRING #{v}"
        #v.strip!
        puts "<--strip_hash_values"
        return v
      #when Array then strip_array_values(v)# i.strip!}
      when Array then v.each {|i| #puts #Z"ARRAY value: #{i}"
       strip_hash_values(v)} # i.strip!}
      when Hash then strip_hash_values(v)
      when Integer then puts "Integer #{v}"
        puts "<--strip_hash_values"
        return v
      else raise ArgumentError, "Unhandled type #{v.class}"
    end
  end
end

Attachments:
http://www.ruby-forum.com/attachment/7097/SampleInput.txt

···

--
Posted via http://www.ruby-forum.com/.

that needs to be `hash.each do |k,v|`

···

On Feb 24, 2012, at 15:41 , mike lupo wrote:

hash.each do |v|

Thanks Ryan Davis.
Problem #1, not every piece of data passed in is a hash. So
restructuring the function a little helps clarify that. Apologies for my
shoddy first attempt, and thanks again you for your input.

For the readers finding this via search, find the input contained in a
text file attached to my initial post.

#2, I have this working now. Not elegant, hardly fault tolerant, but
works.

#define a boolean "test".
class Object
  def boolean?
    self.is_a?(TrueClass) || self.is_a?(FalseClass)
  end
end

def traverse_data(input, indent="")
  puts "#{indent}traverse_data -- >"

  if input.class==Fixnum
    puts "#{indent}Integer: #{input}"
    return
  end
  if input.boolean?
    puts "#{indent}Boolean: #{input}"
    return
  end
  if input.class==Bignum
    puts "#{indent}Bignum: #{input}"
    return
  end

  input.each do |v|
    case v
      when String then puts "#{indent}STRING #{v}"
        puts "#{indent}<--traverse_data"
        return
      when Array then v.each_index {|i| #puts
       traverse_data(v[i], "#{indent} ")}
      when Hash then puts "#{indent}HASH: #{v}"
        traverse_data(v, "#{indent} ")
        #return v
      else raise ArgumentError, "Unhandled type #{v.class}"
    end
  end
end

#call it now.
input = {gotten from attached text file}
traverse_data(input)

···

--
Posted via http://www.ruby-forum.com/.