使用哈希键

时间:2018-04-11 08:46:43

标签: ruby hash

我遇到了一个我无法找到合适解决方案的问题。

我有环境的YAML配置文件,我们称之为development.yml

此文件用于创建应更新的哈希:

data = YAML.load_file(File.join(Rails.root, 'config', 'environments', 'development.yml'))

我想要完成的是这些方面。我们假设我们有一个排序元素

data['server']['test']['user']
data['server']['test']['password']

我想要的是:

data['server']['test']['user'] = #{Server.Test.User}
data['server']['test']['password'] = #{Server.Test.Password}

我们的想法是为每个值创建一个占位符,该值是动态的键映射,一直到哈希的最后一级,并用映射到该值替换值,连接键。

对不起,它没有解决我的问题。位置data['server']['test']['user']将通过循环来动态构建,该循环将通过嵌套的哈希。我发现这样做的唯一方法是在字符串中附加当前Hash迭代的键。最后,我有一个像"data['server']['test']['name']"这样的字符串,我正在考虑转换为变量data['server']['test']['name'],然后为此变量赋值#{Server.Test.Name}。阅读我的问题我不确定这是否清楚,我希望这有助于澄清它。

输入样本:

api: 'active'
server:
  test:
    user: 'test'
    password: 'passwordfortest'
  prod:
    user: 'nottest'
    password: 'morecomplicatedthantest'

在这种情况下,最终结果应该是以这种方式更新此yml文件:

api: #{Api}
server:
  test:
    user: #{Server.Test.User}
    password: #{Server.Test.Password}
  prod:
    user: #{Server.Prod.User}
    password: #{Server.Prod.Password}

听起来很傻,但我无法找到办法。

3 个答案:

答案 0 :(得分:1)

使用String#%

input = %|
  data['server']['host']['name'] = %{server_host}
  data['server']['host']['user'] = %{server_host_user}
  data['server']['host']['password'] = %{server_host_password}
|
puts (
  input % {server_host: "Foo",
           server_host_user: "Bar",
           server_host_password: "Baz"})
#⇒ data['server']['host']['name'] = Foo
#  data['server']['host']['user'] = Bar
#  data['server']['host']['password'] = Baz

答案 1 :(得分:1)

我现在正在发布另一个答案,因为我意识到问题的全部内容。

使用Iteraptor gem:

require 'iteraptor'
require 'yaml'

# or load from file
yaml = <<-YAML.squish
api: 'active'
server:
  test:
    user: 'test'
    password: 'passwordfortest'
  prod:
    user: 'nottest'
    password: 'morecomplicatedthantest'
YAML

mapped =
  yaml.iteraptor.map(full_parent: true) do |parent, (k, _)|
    v = parent.map(&:capitalize).join('.')
    [k, "\#{#{v}}"]
  end

puts YAML.dump(mapped)
#⇒ ---
#  api: "#{Api}"
#  server:
#    test:
#      user: "#{Server.Test.User}"
#      password: "#{Server.Test.Password}"
#    prod:
#      user: "#{Server.Prod.User}"
#      password: "#{Server.Prod.Password}"

puts YAML.dump(mapped).delete('"')
#⇒ ---
#  api: #{Api}
#  server:
#    test:
#      user: #{Server.Test.User}
#      password: #{Server.Test.Password}
#    prod:
#      user: #{Server.Prod.User}
#      password: #{Server.Prod.Password}

答案 2 :(得分:0)

您无法将键值对添加到字符串中。

data['server']['host'] # => which results in a string

选项1:

您可以将Server.Host保存为哈希

中的主机名
data['server']['host']['name'] = "#{Server.Host}"
data['server']['host']['user'] = "#{Server.Host.User}"
data['server']['host']['password'] = "#{Server.Host.Password}"

选项2:

您可以在一个步骤中构建哈希,并将主机作为密钥。

data['server']['host'] = { "#{Server.Host}" => { 
                              'user' => "#{Server.Host.User}",
                              'password' => "#{Server.Host.Password}"
                            } 
                          }