将实例方法与变量#[]一起使用

时间:2018-06-28 04:21:32

标签: chef

我需要使用this method

#[](attrib) ⇒ Object
Return an attribute of this node.

我可以这样使用它,效果很好:

# Create node instance and print specific attribute
node = Chef::Node.load("mynode22.zz.mysite.com")
puts node["my"]["application"]["version"]

但是我试图以循环方式运行它,因此我需要将["my"]["application"]["version"]部分作为变量传递。 下面,attr将分配给["my"]["application"]["version"]

attributes.each do |attr|
    puts node#{attr}
end

但这不起作用。有人知道在这种情况下如何使用变量吗?我仍在学习Ruby,但仍坚持使用它。

1 个答案:

答案 0 :(得分:0)

您可以创建一个方法,如果该方法返回任何内容,则该方法将继续在上一次调用的返回值上调用#[]方法:

def nested_accessor(object, *keys)
  keys.reduce(object) do |current, key|
    current[key] if current
  end
end

然后可以调用该方法,例如:

class Node
  def initialize
    @attributes = {
      'my' => {
        'application' => {
          'version' => '0.0.1',
          'name' => 'Test App'
        },
        'config' => {
          'key' => 'value'
        }
      }
    }
  end

  def [](attrib)
    @attributes[attrib]
  end
end

node = Node.new
nested_accessor(node, 'my', 'application', 'version') # => "0.0.1"
nested_accessor(node, 'my', 'config') # => {"key"=>"value"}
nested_accessor(node, 'someone elses', 'application', 'version') # => nil

如果您已经在数组中拥有了所需的键,则只需将其放在参数列表中即可

nested_accessor(node, *['my', 'application', 'version'])

nested_accessor方法将对任何对象都有效,只要该对象和从对#[]的调用返回的每个对象都对#[]方法作出响应或为nil (或false)。


顺便说一句,Ruby在HashArray上有一个名为dig的方法,它的功能与此类似,它将在每个方法上继续调用dig中间步骤,直到返回nil或它没有更多需要检查的键为止。我通常会推荐该方法,但是由于这是一个自定义对象,似乎没有dig方法,因此我创建了一个伪挖掘方法(上面),该方法适用于#[]#dig