Chef:没有将 String 隐式转换为 Integer TypeError

Chef: no implicit conversion of String into Integer TypeError

我写了一个像这样的小 Chef 库:

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].

这看起来很奇怪,因为搜索选项使用 return 在 Chef DSL 中搜索时有所不同。

如果您发布的是您的 return 值,那么只需 运行 first 就可以了。

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

在您调用的食谱中执行搜索时 the search method in recipe DSL,它在将结果发回之前已经遍历了结果。

当您调用 Chef::Sarch::Query.new.search 时,您是从 dsl 帮助器中调用 underlying method 并且如果您不将块传递给要处理的方法,则必须自己迭代结果结果。

你最终 here 其中 return 是一个包含查询结果数组的数组,以及结果的开始和大小(用于 UI 上的分页)。

所以@Oleander 已经给出了最终答案,在 map 之前调用 first,在 return 的结果部分调用 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

第一个结果也是 return 并得到它的名字,应该会快一点,因为它不需要 'subset' 所有条目,只需要第一个。