2017-04-09 17 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 
相關問題