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

时间:2015-11-29 20:19:45

标签: ruby search 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].

这看起来很奇怪,因为在Chef DSL中搜索时使用的搜索选项会返回不同的内容。

2 个答案:

答案 0 :(得分:2)

在您正在调用the search method in recipe DSL的食谱中执行搜索时,该食谱已经在结果发送之前迭代结果。

当您调用Chef::Sarch::Query.new.search时,您正在调用dsl帮助程序中的underlying method并且如果您未将块传递给方法来处理结果,则必须自己迭代结果

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

所以@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 :(得分:1)

如果您发布的内容是您的返回值,那么只需在其上运行first即可。

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