I have 2 solutions. My first golfish one which doesn't handle any special cases: ---- require 'yaml' require 'ostruct' class Hash def to_os o=OpenStruct.new each{|k,v|o.send(k.to_s+'=',v.respond_to?(:to_os) ? v.to_os : v)} o end end if __FILE__ == $0 p data=YAML::load(ARGF.read).to_os end And my second, which attempts to prevent recursion loops and adds a '_' infront of invalid names or clashes with existing methods: class Hash def to_os os = OpenStruct.new each {|key,val| key = '_'+key.to_s if !key.to_sym ||os.methods.include?(key.to_s) key = key.gsub(/[!?]/,'_') if val.object_id!=self.object_id os.send(key.to_s+'=', val.respond_to?(:to_os) ? val.to_os : val ) end } os end end -Adam