def transform_hash(original, options={}, &block)
      options[:safe_descent] ||= {}
      new_hash = {}
      options[:safe_descent][original.object_id] = new_hash
      original.inject(new_hash) { |result, (key,value)|
        if (options[:deep] && Hash === value)
          value = options[:safe_descent].fetch( value.object_id ) {
            transform_hash(value, options, &block)
          }
        end
        block.call(result,key,value)
        result
      }
    end
def transform_hash(original, options={}, &block)
      options[:safe_descent] ||= {}
      new_hash = {}
      options[:safe_descent][original.object_id] = new_hash
      original.inject(new_hash) { |result, (key,value)|
        if (options[:deep] && Hash === value)
          value = options[:safe_descent].fetch( value.object_id ) {
            transform_hash(value, options, &block)
          }
        end
        block.call(result,key,value)
        result
      }
    end
https://gist.github.com/dbenhur/1070399