Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何让Ruby YAML将散列子类转储为简单散列?_Ruby_Hash_Yaml - Fatal编程技术网

如何让Ruby YAML将散列子类转储为简单散列?

如何让Ruby YAML将散列子类转储为简单散列?,ruby,hash,yaml,Ruby,Hash,Yaml,我有一个类Foo,它是Hash的子类 class Foo < Hash # whatever Foo-specific methods/etc end 我希望它只是作为一个普通的旧散列来编写(而不是!ruby/hash:Foo) …这样我的数据的消费者就不需要知道Foo。是否有一个神奇的方法添加到我的类中以转换自身进行序列化,或者有一个神奇的选项传递到YAML.dump 当然,将一个Foo对象转换为散列是很容易的,但是它们可能会嵌套在我想要转储的实际散列中的任何级别上,我宁愿不必进行

我有一个类
Foo
,它是
Hash
的子类

class Foo < Hash
  # whatever Foo-specific methods/etc
end
我希望它只是作为一个普通的旧散列来编写(而不是
!ruby/hash:Foo

…这样我的数据的消费者就不需要知道
Foo
。是否有一个神奇的方法添加到我的类中以转换自身进行序列化,或者有一个神奇的选项传递到YAML.dump


当然,将一个
Foo
对象转换为散列是很容易的,但是它们可能会嵌套在我想要转储的实际散列中的任何级别上,我宁愿不必进行搜索和替换。

您可以使用(文档不全的)
encode\u with
representation\u map
方法来实现这一点。要自定义对象的YAML序列化,请为其提供一个
encode\u with
方法,该方法接受一个对象,其中一个方法是


在您需要Yaml之前,但在Ruby 2.0中,这似乎不起作用,原因我无法理解。不过,使用Bundler指定Gem版本确实有效,因此如果尚未使用它,您可能需要创建一个
Gem文件并在其中指定Psych。

搜索和替换实际上还不错:

# Convert Hash/Array subclasses into plain hashes/arrays for YAML dump.
# Assumptions:
#   Hash keys will be simple objects - don't need to clear them
#   No custom objects containing Hash/Array subclass instances
def deep_clear_subclasses(obj, dedup = {})
  case obj
  when Hash
    return dedup[obj] if dedup.has_key? obj
    dedup[obj] = copy = {}
    obj.each {|k,v| copy[k] = deep_clear_subclasses(v, dedup)}
    copy
  when Array
    return dedup[obj] if dedup.has_key? obj
    obj.inject(dedup[obj] = []) {|a,v| a << deep_clear_subclasses(v,dedup)}
  else
    obj # not going to operate on other kinds of objects
  end
end
#将散列/数组子类转换为用于YAML转储的普通散列/数组。
#假设:
#散列键将是简单的对象-不需要清除它们
#没有包含哈希/数组子类实例的自定义对象
def deep_clear_子类(obj,dedup={})
案例obj
当散列
如果dedup.has_key,返回dedup dedup[obj]?obj
重复数据消除[obj]=复制={}
obj.each{k,v|copy[k]=deep_clear_子类(v,dedup)}
复制
当数组
如果dedup.has_key,返回dedup dedup[obj]?obj

obj.inject(dedup[obj]=[]){a,v | a这可能是正确的答案……现在,对于我的ruby 1.9.3代码库,我猜我需要实现搜索和替换。如果您展示示例代码、演示问题的示例YAML输出和显示您希望它的外观的示例输出,这会有所帮助。请参阅
> puts YAML.dump({bar:"baz"})
---
:bar: baz
class Foo < Hash

  # other methods ...

  def encode_with coder
    coder.represent_map nil, self
  end

end
gem 'psych', '2.0.0'
# Convert Hash/Array subclasses into plain hashes/arrays for YAML dump.
# Assumptions:
#   Hash keys will be simple objects - don't need to clear them
#   No custom objects containing Hash/Array subclass instances
def deep_clear_subclasses(obj, dedup = {})
  case obj
  when Hash
    return dedup[obj] if dedup.has_key? obj
    dedup[obj] = copy = {}
    obj.each {|k,v| copy[k] = deep_clear_subclasses(v, dedup)}
    copy
  when Array
    return dedup[obj] if dedup.has_key? obj
    obj.inject(dedup[obj] = []) {|a,v| a << deep_clear_subclasses(v,dedup)}
  else
    obj # not going to operate on other kinds of objects
  end
end