有没有更好的方法来递归调用当前方法,而不使用其名称?

时间:2017-04-09 02:55:33

标签: ruby

例如:

def recurse(value)
  if value < 5
    self.send(__method__, value + 1)
  else
    value
  end
end

这有效,但有点难看。

基本上我正在寻找一种更漂亮的方法来调用当前正在执行的方法,而不是通过名称明确引用它。

如果有一个不那么神秘的语法,我可能会使用它(避免名称重复,减少重命名函数所需的工作量等)。如果没有更好的语法,我只会硬编码正常的名称。

2 个答案:

答案 0 :(得分:2)

这是一个评论,正如@ sagarpandya82所提到的,你可以省略一些冗余部分并使用这两种变体。我会稍微重构一下:

def recurse(value)
  return value unless value < 5 # return value if value >= 5
  send(__method__, value + 1) # or just recurse(value + 1)
end

带块的非递归版本:

def non_recurse(value)
  if value >= 5
    yield value
  else 
    (value..5).each do |i|
      yield i
    end
  end
end
non_recurse(3) {|i| puts i}
#=> 3, 4, 5
non_recurse(6) {|i| puts i}
#=> 6

答案 1 :(得分:1)

如果您真的想使用__method__,那么您的方法是正确且可读的。要遵守通常的Ruby准则,您可以删除return并使用2个空格作为缩进(如评论中@ sagarpandya82所述):

def recurse(value)
  if value < 5
    self.send(__method__, value + 1)
  else
    value
  end
end

我认为没有理由在这里使用self.send(__method__),所以你可以写:

def recurse(value)
  if value < 5
    recurse(value + 1)
  else
    value
  end
end

实际上,我会说你根本不需要递归。你所有的方法都是在值达到5时继续加1.如果值大于5,则返回值:

对于整数:

def no_recurse(value)
  [value, 5].max
end

no_recurse(4)
# 5
no_recurse(-3)
# 5
no_recurse(7)
# 7
no_recurse(-2**1000)
# 5
no_recurse(4.5)
# 5 # <- That's wrong

对于浮点数,您只需要将小数部分添加到5。这适用于任何数字:

def no_recurse(value)
  [value, 5 + value % 1].max
end

no_recurse(4.5)
# 5.5
no_recurse(5.5)
# 5.5
no_recurse(6)
# 6
no_recurse(-7)
# 5