Ruby +递归函数+定义全局变量

时间:2015-02-27 09:27:44

标签: ruby recursion

我正在使用Ruby提取bitbucket repo列表。来自bitbucket的响应将只包含10个存储库和下一页的标记,其中将有另外10个存储库等等......(他们称之为分页)

所以,我编写了一个递归函数,如果存在下一个页面标记,它会调用自身。这将一直持续到最后一页。

这是我的代码:

#!/usr/local/bin/ruby
require 'net/http'
require 'json'
require 'awesome_print'

@repos = Array.new

def recursive(url)

    ### here goes my net/http code which connects to bitbucket and pulls back the response in a JSON as request.body 
    ### hence, removing this code for brevity

    hash = JSON.parse(response.body)

    hash["values"].each do |x|
        @repos << x["links"]["self"]["href"]
    end

    if hash["next"]
        puts "next page exists"
        puts "calling recusrisve with: #{hash["next"]}"
        recursive(hash["next"])
    else
        puts "this is the last page. No more recursions"
    end
end

repo_list = recursive('https://my_bitbucket_url')
@repos.each {|x| puts x}

现在,我的代码工作正常,它列出了所有的回购。

问题: 我是Ruby的新手,所以我不确定我使用上面的全局变量 @repos = Array.new 的方式。如果我在函数中定义数组,那么每次调用该函数都会创建一个新数组,覆盖之前调用的内容。

那么,在这种情况下,Ruby程序员如何使用全局符号。我的代码是否遵守Ruby道德规范,或者它是非常业余的东西(但它是正确的,因为它有效)这样做。

1 个答案:

答案 0 :(得分:5)

共识是尽可能避免全局变量。

我会像这样递归地构建集合:

def recursive(url)
  ### ...

  result = [] 

  hash["values"].each do |x|
    result << x["links"]["self"]["href"]
  end

  if hash["next"]
    result += recursive(hash["next"])
  end
  result
end

或将集合移交给函数:

def recursive(url, result = [])
  ### ...

  hash["values"].each do |x|
    result << x["links"]["self"]["href"]
  end

  if hash["next"]
    recursive(hash["next"], result)
  end
  result
end

无论哪种方式,你都可以调用函数

repo_list = recursive(url)

我会这样写:

def recursive(url)
  # ...

  result = hash["values"].map { |x| x["links"]["self"]["href"] }
  result += recursive(hash["next"]) if hash["next"]
  result
end