3

我是新手。请帮帮我。我写了Puppet函数一段代码:

    n_if={}
     over_if = arguments[1]

    over_if.each do |kk,vv|
      weth={}
        puts kk,vv,weth
        weth = arguments[0]
        weth['in_vlan'] = vv['in_vlan']
        weth['options']['MTU'] = vv['mtu']
    n_if['eth'+ kk.to_s]=weth
end

从 2 个文件中读取数据,并分别传入 arguments[0] 和 arguments[1]:

# template of ethernet interfaces
eth_: 
  method: "static"
  family: "inet"
  ip: ""
  netmask: "255.255.0.0"
  onboot:  true
  options: 
    MTU: ""
  in_vlan: ""

# values for include into ethernet interfaces
eth_values:
 0:
  mtu: 1500
  in_vlan: 15
 1:
  mtu: 9000
  in_vlan: 125

我希望得到带有键 'eth0' 和 'eth1' 的哈希,如下所示:

eth1methodstaticfamilyinetin_vlan125ipnetmask255.255.0.0onboottrueoptionsMTU9000eth0methodstaticfamilyinetin_vlan15ipnetmask255.255.0.0onboottrueoptionsMTU1500

但我得到:

eth1methodstaticfamilyinetin_vlan125ipnetmask255.255.0.0onboottrueoptionsMTU9000eth0methodstaticfamilyinetin_vlan125ipnetmask255.255.0.0onboottrueoptionsMTU9000

我的错误是什么?

4

1 回答 1

1

首先,一些评论:

  1. 您的代码没有像大多数其他人那样缩进,这使得其他人很难帮助您。它应该看起来像这样:

    n_if={}
    over_if = arguments[1]
    
    over_if.each do |kk,vv|
      weth={}
      puts kk,vv,weth
      weth = arguments[0]
      weth['in_vlan'] = vv['in_vlan']
      weth['options']['MTU'] = vv['mtu']
      n_if['eth'+ kk.to_s]=weth
    end
    
  2. 也许你的变量名对你有意义,但对我来说没有意义。什么是n_if, weth,over_ifkk?vv

  3. 您将其分配weth为 内部的哈希each,然后将其分配为其他内容。你真正想做什么?

  4. 你这么说arguments[0]并且arguments[1]是从文件中读取的数据。这些是如何读入的?这些是 YAML 文件吗?如果您包含代码以实际重现您的问题,那将很有帮助。把它减少到必需品。

  5. 在 Ruby 中,不连接字符串,而是使用字符串插值通常更惯用且性能更高:

    n_if["eth#{kk}"] = weth
    

现在,一些答案:

我的猜测是您的设置包含这样的数据:

arguments = {
  "eth_"=>{
    "method"=>"static",
    "family"=>"inet",
    "ip"=>"",
    "netmask"=>"255.255.0.0",
    "onboot"=>true,
    "options"=>{"MTU"=>""},
    "in_vlan"=>""
  },
  "eth_values"=>{
    0=>{"mtu"=>1500, "in_vlan"=>15},
    1=>{"mtu"=>9000, "in_vlan"=>125}
  }
}

arguments[0] = arguments['eth_']
arguments[1] = arguments['eth_values']

我相信(基于对你拥有什么和你可能想要什么的许多猜测)你的问题是这种组合:

weth={}
weth=arguments[0]

我认为您的意图是说"是一种哈希类型的对象;现在用"weth的值填充它arguments[0]。这些行实际上说的是:

  • 设置weth为空哈希。
  • 没关系,扔掉那个空哈希并设置wetharguments[0].

因此,每次通过循环时,您都使用weth. 相反,我认为您想复制. weth以下修改后的代码是否为您提供了所需的内容?

n_if={}
over_if = arguments[1]

over_if.each do |kk,vv|
  weth = arguments[0].dup
  weth['in_vlan'] = vv['in_vlan']
  weth['options']['MTU'] = vv['mtu']
  n_if["eth#{kk}"]=weth
end

require 'pp' # for nice wrapping inspection
pp n_if
#=> {"eth0"=>
#=>   {"method"=>"static",
#=>    "family"=>"inet",
#=>    "ip"=>"",
#=>    "netmask"=>"255.255.0.0",
#=>    "onboot"=>true,
#=>    "options"=>{"MTU"=>9000},
#=>    "in_vlan"=>15},
#=>  "eth1"=>
#=>   {"method"=>"static",
#=>    "family"=>"inet",
#=>    "ip"=>"",
#=>    "netmask"=>"255.255.0.0",
#=>    "onboot"=>true,
#=>    "options"=>{"MTU"=>9000},
#=>    "in_vlan"=>125}}

如果没有,请编辑您的问题,详细说明您实际拥有的内容(提示:p arguments并向我们展示结果)以及您真正想要的结果。


编辑:为了好玩,这里是一个功能转换。它留给读者作为练习,以了解它的工作原理并提高他们的函数式编程技能。请注意,我已经修改eth_values以匹配模板的层次结构,以便可以应用简单的合并。我保留了"MTU"=>""and"in_vlan"=>""条目,但请注意它们不是代码工作所必需的,您可以删除两者(以及结果"options"=>{})并获得相同的结果。

args = {
  "eth_"=>{
    "method"=>"static",
    "family"=>"inet",
    "ip"=>"",
    "netmask"=>"255.255.0.0",
    "onboot"=>true,
    "options"=>{"MTU"=>""},
    "in_vlan"=>""
  },
  "eth_values"=>{
    0=>{"options"=>{"MTU"=>1500}, "in_vlan"=>15},
    1=>{"options"=>{"MTU"=>9000}, "in_vlan"=>125}
  }
}

n_if = Hash[
  args['eth_values'].map do |num,values|
    [ "eth#{num}",
      args['eth_'].merge(values) do |k,v1,v2|
      if v1.is_a?(Hash) and v2.is_a?(Hash) then
        v1.merge(v2)
      else
        v2
      end
    end ]
  end
]

pp n_if #=> Same result as in the previous code.
于 2013-03-25T13:52:36.280 回答