更改嵌套哈希值

时间:2009-08-04 14:45:04

标签: ruby

我在Ruby中有一个配置类,它曾经有像“core.username”和“core.servers”这样的密钥,它们就像那样存储在YAML文件中。

现在我正在尝试将其更改为嵌套,但无需更改以旧方式引用键的所有位置。我用读者方法管理它:

def [](key)
  namespace, *rest = key.split(".")

  target = @config[namespace]
  rest.each do |k|
    return nil unless target[k]
    target = target[k]
  end

  target
end

但是当我尝试使用编写器类时,它可以工作,但是没有在@config - 哈希中设置。只需调用@config

即可设置YAML.load_file

我设法让它与eval合作,但这不是我想长久保留的。

def []=(key, value)
  namespace, *rest = key.split(".")

  target = "@config[\"#{namespace}\"]"
  rest.each do |key|
    target += "[\"#{key}\"]"
  end

  eval "#{target} = value"
  self[key]
end

有没有合适的方法来实现这一目标,最好不要在整个过程中更改插件和代码?

2 个答案:

答案 0 :(得分:1)

def []=(key, value)
  subkeys = key.split(".")
  lastkey = subkeys.pop
  subhash = subkeys.inject(@config) do |hash, k|
    hash[k]
  end
  subhash[lastkey] = value
end

编辑:修正了拆分。 PS:如果您愿意,也可以像[]方法一样用每个循环替换注入。重要的是你不要用最后一个键调用[],而是用[] =来设置值。

答案 1 :(得分:0)

我使用了递归:

def change(hash)
  if hash.is_an? Hash
    hash.inject({}) do |acc, kv|
      hash[change(kv.first)] = change(kv.last)
      hash 
    end
  else
    hash.to_s.split('.').trim # Do your fancy stuff here
  end
end