puppet将数组转换为基于键的哈希

时间:2014-03-05 14:29:10

标签: puppet

我有一个数组如下:

  $servers = [
     {name => 'server1', address => '10.10.10.11', port => 8081}, 
     {name => 'server2', address => '10.10.10.12', port => 8082}, 
  ]

我需要以编程方式将其转换为基于'name'键的哈希:

  $serversMap = {
    server1 => {address => '10.10.10.11', port => 8081},
    server2 => {address => '10.10.10.12', port => 8082},
  }

这适用于傀儡3:

  $serversMap = $servers.reduce({}) |$cumulate, $server| { 
    $key = "${server['name']}"
    $value = $server.filter |$entry| { $entry[0] != 'name' }
    $tmp = merge($cumulate, {"$key" => $value }) 
    $tmp
   }

然而,有更简单的方法吗?

为什么我需要创建时态变量$ tmp? 没有它,我得到Error: Function 'merge' must be the value of a statement错误。

ps:很明显,但无论如何我会说:$ servers变量是给我的,我不能改变它的结构。我需要相同的数据,但需要$ serversMap的形式。所以,我问如何以编程方式从$ servers转换为$ serversMap。

1 个答案:

答案 0 :(得分:4)

除了$ tmp变量,此代码是最佳的。

$ tmp变量需要存在,因为合并函数是rvalue。来自docs

  

实际上有两种完全不同的函数类型 - rvalues(返回值)和语句(不是)。如果您正在编写右值函数,则必须传递:type => :创建函数时的右值;见下面的例子。

当涉及到rvalue语句时,产生此错误的puppet源是非常自我解释的:

    # It is harmless to produce an ignored rvalue, the alternative is to mark functions
    # as appropriate for both rvalue and statements
    # Keeping the old behavior when a pblock is not present. This since it is not known
    # if the lambda contains a statement or not (at least not without a costly search).
    # The purpose of the check is to protect a user for producing a meaningless rvalue where the
    # operation has no side effects.
    #
    if !pblock && Puppet::Parser::Functions.rvalue?(@name)
      raise Puppet::ParseError,
        "Function '#{@name}' must be the value of a statement"
    end

真正的原因是Puppet并不像语言那么复杂。如果你想要真正的电源切换到Ruby。