2017-04-09 78 views
0

例如:有没有更好的方式来递归调用当前方法,而不使用它的名字?

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

这工作,但它是一个有点难看。

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

如果对此没有较少隐晦的语法,我可能会使用它(以避免名称重复,减少重命名函数所需的工作量等)。如果没有更好的语法,我会像正常一样对这个名字进行硬编码。

+0

的[获取当前执行方法的名称]可能的复制(http://stackoverflow.com/questions/199527/get-the-name-of-the-currently:这将任意数量的工作-executing-method) –

+4

我认为你的解决方案读得很好。作为一个附注,你可以省略'return's,并且你应该使用2个空格来缩进。 –

+1

很多时候递归方法并不像迭代那样简洁或有效。 Ruby的Enumerable库提供了比大多数更多的功能,并且可以在列表上创建奇迹。在许多情况下,递归事物可以表示为一系列列表转换。 – tadman

回答

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 
+0

技术上是真的,但在生产代码中看到这一点会让我质疑作者的意图。许多递归算法已经很复杂,这增加了更多的混淆。 – tadman

+2

@tadman,我同意生产环境,但似乎作者正在学习这种编程功能。无论如何,在Ruby迭代中几乎所有情况下都比递归更好。 – Ilya

+0

你可以添加一个迭代替代你的答案。谢谢 –

1

如果你真的想用__method__,你的方法是正确的,合理的可读性。要符合常规的Ruby指南,你可以只取出return S和使用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 

其实,我会说你根本不需要递归。你所有的方法,它只是不断增加1的值,直到达到5.如果该值大于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 
相关问题