意外的哈希行为

时间:2013-03-25 13:31:52

标签: ruby

我是新手。 请帮帮我。 我写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

我的错误是什么?

1 个答案:

答案 0 :(得分: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_ifwethover_ifkkvv

  3. 您将weth指定为each内的哈希值,然后将其指定为其他内容。你真的想做什么?

  4. 您说arguments[0]arguments[1]是从文件中读取的数据。这些怎么读?这些YAML文件?如果您要包含实际重现问题的代码,将会很有帮助。把它简化为必需品。

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

    n_if["eth#{kk}"] = weth
    
  6. 现在,一些答案:

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

    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设置为空哈希。
    • 没关系,扔掉那个空哈希并将weth设置为同一个对象arguments[0]

    因此,每次循环时,您都会使用weth修改相同的哈希。相反,我认为你想wethn_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"=>""以匹配模板的层次结构,以便可以应用简单合并。我已经离开了"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. )并实现相同的目的结果

    {{1}}