方法中的递归例程

时间:2012-03-17 03:49:40

标签: ruby recursion subroutine ruby-1.9.3

通常,我在一个方法中有一个递归例程,该方法只由该方法调用或在递归例程本身内调用:

def foo
  ...
  bar
  ...
end

def bar
  ...
  bar
  ...
end

但由于bar未在其他任何地方使用,我不想将其定义为方法,但不知何故将其置于调用它的方法中:

def foo
  ...
  bar {# some way to mark the recursive routine
    ...
    bar # some way to call the recursive routine
    ...
  }
  ...
end

这可能吗?

3 个答案:

答案 0 :(得分:4)

使用lambda / proc很容易:

def foo(n)
  fact = lambda do |i|
    i.zero? ? 1 : i * fact.call(i-1)
  end
  fact.call(n)
end

foo(4) # => 24

您也可以使用受保护或私有方法。

如果性能是一个真正的问题,每次创建一个对象(lambda)将会更慢,并且调用lambda也会更慢,关闭和所有。我的fruity宝石给了我a 3.3x slowdown关于这个微不足道的例子;对于实际做更多事情的案件,处罚应该少得多。确保性能确实是一个问题;你知道他们对过早优化的看法......

答案 1 :(得分:2)

听起来你正试图用面向对象的语言进行函数式编程。通过创建一个单一职责的小班,您可能会得到更好的服务:

class Routiner
  def foo(*args)
    # occasionally...
    do_work(some_data)
  end
protected
  def do_work(data)
    # ...work work work
    do_work(more_data) if some_condition
  end
end

Routiner.new.foo('bar', 'baz', 'bat')

答案 2 :(得分:0)

@coreyward的答案很好,但是你可以用另一个技巧来限制使用lambda的递归函数的范围。

def foo
  ...
  bar = lambda do |arg|
    ...
    bar.call(...)
    ...
  end

  bar.call(...)
  ...
end

由于bar在foo中是词法范围的,因此没有其他方法可以看到它或调用它,但是bar引用的lambda可以看到bar,因为它关闭了它所定义的词法范围。