2015-11-29 3 views
1

Я написал небольшую библиотеку Chef, которая выглядит следующим образом:Chef: нет неявного преобразования строки в Integer TypeError

module Test 
    module Search 
    extend self 

    def single_node(type, value) 
     result = Chef::Search::Query.new.search(:node, "#{type}:#{value}", 
               filter_result: { 
               'name' => ['name'] 
               }).map { |n| n['name'] }.first 
     return result 
    end 

    end 
end 

При запуске тестового кода против него я получаю следующее сообщение об ошибке:

TypeError 
--------- 
no implicit conversion of String into Integer 

     1: module Test 
     2: module Search 
     3:  extend self 
     4:  def single_node(type, value) 
     5:  result = Chef::Search::Query.new.search(:node, "#{type}:#{value}", 
     6:            filter_result: { 
     7:             'name' => ['name'] 
     8>>            }).map { |n| n['name'] }.first 
     9:  return result 
     10:  end 


     13: end 
     14: 

После некоторых игр я обнаружил, что поиск содержал эту информацию:

[[{"name"=>"influxdb.example.org"}], 0, 1]. 

Это кажется странным, поскольку используемые варианты поиска возвращают что-то другое при поиске в рамках DSL-шеф-повара.

+0

Что вы думаете? – Oleander

+0

Извинения за неясность. Почему результат отличается от результата поиска повара DSL? Формат кажется странным с дополнительными целыми числами, и значение, которое я хочу, является хешем (правильным) внутри массива (также правильным, я думаю) в массиве. Этот же поиск в DSL возвращает первый результат правильно (имя узла) без ошибки вообще. – kemra102

ответ

2

При выполнении поиска в рецепте вы звоните the search method in recipe DSL, которые уже итерации по результатам перед отправкой их обратно.

Когда вы вызываете Chef::Sarch::Query.new.search, вы вызываете underlying method из помощника dsl и должны сами выполнять итерацию результатов, если вы не передадите блок методу для работы с результатами.

В итоге вы получите here, который возвращает массив, содержащий массив результатов запроса, вместе с началом и размером результатов (для разбивки на страницы в пользовательском интерфейсе).

Таким образом, окончательный ответ, как уже было дано @Oleander, вызовите first перед тем map, вызвать map в результате части возврата (первый элемент массива), игнорируя переменные нумерации страниц.

Или, чтобы получить такое же поведение, как в рецепте DSL использовать Chef :: DSL :: DataQuery так:

require 'chef/dsl/data_query' 

module Test 
    module Search 
    extend self 
    include Chef::DSL::DataQuery 

    def single_node(type, value) 
     result = search(:node, "#{type}:#{value}", 
          filter_result: { 
           'name' => ['name'] 
          }).map { |n| n['name'] }.first 
     return result 
    end 
    end 
end 

На той же идее сократить код:

require 'chef/dsl/data_query' 

module Test 
    module Search 
    extend self 
    include Chef::DSL::DataQuery 

    def single_node(type, value) 
     return search(:node, "#{type}:#{value}", 
          filter_result: { 
           'name' => ['name'] 
          }).first['name'] 
    end 
    end 
end 

Какие верните первый результат и получите его имя, должно быть немного быстрее, поскольку он не должен «подмножать» все записи, а только первый.

1

Если вы указали свое возвращаемое значение, просто запустите на нем first, и все готово.

result = Chef::Search::Query.new.search(:node, "#{type}:#{value}", filter_result: { 
    'name' => ['name'] 
}).first.map { |n| n['name'] }.first 
Смежные вопросы