1

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

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

这可能吗?

4

3 回答 3

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 也会更慢,闭包等等。我的fruitygem 让我在这个微不足道的例子上减速了 3.3 倍;对于实际上涉及更多事情的案件,处罚应该少得多。只要确保性能确实是一个问题;你知道他们怎么说过早优化...

于 2012-03-17T04:04:45.450 回答
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')
于 2012-03-17T03:55:21.317 回答
0

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

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

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

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

于 2012-03-17T04:19:03.577 回答