无法获得递归方法

时间:2016-04-13 20:04:29

标签: ruby pipedrive-api

我有以下方法:

def all(response = nil, options = {}, data = [])
  response ||= get(resource_path, options)
  parsed_response = JSON.parse(response.body)
  return bad_response(response) unless response.code == '200'

  data += parsed_response['data'].nil? ? [] : parsed_response['data'].map { |obj| new(obj) }
  puts data.count
  if parsed_response.dig('additional_data', 'pagination', 'more_items_in_collection')

    options[:start] = parsed_response.dig('additional_data', 'pagination', 'next_start')
    all(nil, options, data) # recursively calls itself, passing cumulated data
  end
  puts data.count # WHY WOULD IT NOT JUST RETURN ONCE, BUT INSTEAD GO DOWN TO INITIAL VALUE?
  data
end

我对这个方法的问题是,当它退出方法时:  (if parsed_response.dig('additional_data', 'pagination', 'more_items_in_collection')返回false,最后一个方法的行应该被触发),它开始倒带..

输出结果为:

Pipedrive::Customer.all.count
100
200
300
400
500
600
700
800
900
1000
1100
1200
1300
1400
1500
1600
1700
1800
1900
2000
2100
2200
2300
2400
2500
2600
2700
2800
2900
3000
3100
3200
3300
3400
3500
3600
3700
3800
3900
3991
3991
3900
3800
3700
3600
3500
3400
3300
3200
3100
3000
2900
2800
2700
2600
2500
2400
2300
2200
2100
2000
1900
1800
1700
1600
1500
1400
1300
1200
1100
1000
900
800
700
600
500
400
300
200
100
=> 100

这看起来很疯狂,但我希望我只是遗漏了一些非常简单的东西(事实上我是,但究竟是什么:)。

修改

我的问题是方法的结果,而不是put本身。我希望Pipedrive::Customer.all.count返回3991,但它会返回100而不是......有什么想法吗?我已经尝试将最后一行(data)放入else

  def all(response = nil, options = {}, data = [])
    response ||= get(resource_path, options)
    parsed_response = JSON.parse(response.body)
    return bad_response(response) unless response.code == '200'

    data += parsed_response['data'].nil? ? [] : parsed_response['data'].map { |obj| new(obj) }
    if parsed_response.dig('additional_data', 'pagination', 'more_items_in_collection')

      options[:start] = parsed_response.dig('additional_data', 'pagination', 'next_start')
      all(nil, options, data)
    else
      data
    end
    data 
  end

- 它仍会返回100 ..

2 个答案:

答案 0 :(得分:2)

您只需要并且希望方法中有一个puts语句。现在你将它告诉puts data.count,然后进行递归计算,然后再从那些递归计算puts data.count返回。在这两个puts之间,递归调用将注入自己的puts结果。这就是为什么它似乎积累,然后解开。积累是puts进入的,倒带来自递归调用后的puts

答案 1 :(得分:2)

问题是你在递归调用之后没有退出函数,所以当它从递归调用返回时它会继续并完成函数,因此每次递归都会调用puts data.count呼唤出路。相反的顺序与功能堆栈有关。你的代码结构如下:

all:
  puts 100
  all:
    puts 200
    all:
      puts 300
      all:
        ...
      puts 300
    puts 200
  puts 100
done

根据您的代码,我认为您打算将第二个putsdata放在else中?这应该做你想要的我认为,虽然我不能完全理解你的代码