【发布时间】:2015-05-09 07:35:38
【问题描述】:
我有一些数据保存在深度嵌套的哈希和数组中,我在数据的文本编码方面遇到了麻烦。我知道文本是用“UTF-8”编码的,所以我决定检查每个元素并强制编码。
所以,我为Enumerable 模块创建了一个名为deep_each 的方法:
module Enumerable
def deep_each(&block)
self.each do |element|
if element.is_a? Enumerable then
element.deep_each(&block)
else
block[element]
end
end
end
end
并且期望能够使用以下方法调用来修复数据:
deephash.deep_each {|element| element.force_encoding("UTF-8") if element.class == String}
但结果令人失望:
deephash.deep_each {|element| element.force_encoding("UTF-8") if element.class == String}
> RuntimeError: can't modify frozen String
> from (pry):16:in `force_encoding'
然后我将函数向下移动到“数组”和“哈希”类:
class Hash
def deep_each(&block)
self.each do |element|
if [Array, Hash].include? element.class then
element.deep_each(&block)
else
block[element]
end
end
end
end
class Array
def deep_each(&block)
self.each do |element|
if [Array, Hash].include? element.class then
element.deep_each(&block)
else
block[element]
end
end
end
end
令人惊讶的是,同样的调用现在有效。
我在这里违反了什么约束,我如何为所有 Enumerables 定义一个方法而不为每个 Enumerables 定义它?
【问题讨论】:
-
在第一种情况下,您尝试修改哈希键(以及值)
-
@FrederickCheung 你能解释一下吗?如果您指的是使用
each_value与each方法,那么我认为这不是问题所在。each在第二个 sn-p 中同样有效,而对第一个 snipper 无效(在 Enumerator 方法中)。
标签: ruby class module enumerable