我有以下代码,它接受一个散列并将所有值转换为字符串。
def stringify_values obj
@values ||= obj.clone
obj.each do |k, v|
if v.is_a?(Hash)
@values[k] = stringify_values(v)
else
@values[k] = v.to_s
end
end
return @values
end
因此,给出以下散列:
{
post: {
id: 123,
text: 'foobar',
}
}
我得到了以下的yaml输出
--- &1
:post: *1
:id: '123'
:text: 'foobar'
当我想要这个输出
---
:post:
:id: '123'
:text: 'foobar'
看起来对象已经被展平,然后被赋予了对自身的引用,这会在我的规范中导致堆栈级错误。
如何获得所需的输出?
最佳答案
一个更简单的stringify_values
实现可以是-假设它总是一个散列。此函数使用活动支持核心扩展添加的Hash#deep_merge
方法-我们将散列与自身合并,以便在块中检查每个值并对其调用to_s
。
def stringify_values obj
obj.deep_merge(obj) {|_,_,v| v.to_s}
end
完整工作样品:
require "yaml"
require "active_support/core_ext/hash"
def stringify_values obj
obj.deep_merge(obj) {|_,_,v| v.to_s}
end
class Foo
def to_s
"I am Foo"
end
end
h = {
post: {
id: 123,
arr: [1,2,3],
text: 'foobar',
obj: { me: Foo.new}
}
}
puts YAML.dump (stringify_values h)
#=>
---
:post:
:id: '123'
:arr: "[1, 2, 3]"
:text: foobar
:obj:
:me: I am Foo
不确定值是数组时的期望值是多少,因为
Array#to_s
也会将数组作为字符串提供给您,无论这是否可取,您可以决定并稍微调整解决方案。