Использование метода экземпляра с переменной # [] - PullRequest
0 голосов
/ 28 июня 2018

У меня этот метод Мне нужно использовать.

#[](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 голосов
/ 28 июня 2018

Вы можете создать метод, который продолжает вызывать метод #[] для возвращаемого значения предыдущего вызова, если он возвращает что-либо:

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 есть метод для Hash и Array, называемый dig, который делает что-то похожее на это, он будет продолжать вызывать dig на каждом промежуточном шаге, пока не будет возвращено nil или у него больше нет ключей, которые нужно проверять. Я бы обычно рекомендовал этот метод, но так как это пользовательский объект, который, похоже, не имеет метода dig, я создал метод псевдокопания (см. Выше), который работает на #[] вместо #dig

...