2009-06-21 29 views
116

從Python背景來看,當談到風格時總會有一種「正確的方式去做」(一種「Pythonic」方式),我想知道Ruby是否也存在。我一直在使用自己的風格指南,但是我正在考慮發佈我的源代碼,我希望它遵守任何可能存在的不成文規則。在Ruby中顯式返回是不錯的風格嗎?

它是「The Ruby Way」在方法中明確輸入return?我已經看到它完成和沒有,但有沒有一個正確的方法來做到這一點?是否有權利時間做到這一點?例如:

def some_func(arg1, arg2, etc) 
    # Do some stuff... 
    return value # <-- Is the 'return' needed here? 
end 

回答

181

舊的(和「回答」)問題,但我會折騰我的兩分錢作爲答案。

TL; DR - 您不需要,但它可以使您的代碼在某些情況下更加清晰。

雖然不使用顯式返回可能是「Ruby方式」,但是對於使用不熟悉的代碼的程序員或者不熟悉Ruby的這個特性會感到困惑。

例如,可能會有一個像這樣的小函數,它將傳入的數字加1,並將其分配給實例變量。

def plus_one_to_y(x) 
    @y = x + 1 
end 

這是否意味着一個函數返回值,或不是?很難說開發人員的意思,因爲它既分配實例變量,又返回分配的值。

假設很久以後,另一個程序員(可能不熟悉Ruby如何根據最後一行代碼執行返回操作)會出現,並且希望將某些打印語句放入日誌中,並且該函數變成了這個...

def plus_one_to_y(x) 
    @y = x + 1 
    puts "In plus_one_to_y" 
end 

現在功能壞了如果有什麼需要返回值。如果沒有什麼期望返回值,那很好。顯然,如果在代碼鏈的更遠處,調用它的東西需要一個返回值,它會失敗,因爲它沒有恢復到期望的值。

現在真正的問題是這樣的:真的有什麼期望返回值嗎?這是否破壞了某些東西?它會在未來破壞一些東西嗎?誰知道!只有全面的代碼審查所有電話會讓你知道。

至少對我來說,最佳實踐方法是要麼非常明確地表明,如果事情重要的話你會返回一些東西,或者什麼都不會返回。

在我們的小演示功能的情況下,

因此,假設我們希望它返回一個值,它會被寫成這樣...

def plus_one_to_y(x) 
    @y = x + 1 
    puts "In plus_one_to_y" 
    return @y 
end 

那將是讓程序員很清楚,它確實會返回一個價值,並且他們很難在沒有意識到的情況下打破它。

或者,我們可以把它寫像這樣,離開了返回語句...

def plus_one_to_y(x) 
    @y = x + 1 
    puts "In plus_one_to_y" 
    @y 
end 

但爲什麼還要離開了這個詞的回報?爲什麼不把它放在那裏,讓它100%清楚發生了什麼?它實際上不會影響您的代碼的執行能力。

62

號好紅寶石風格,將一般只使用一個早日迴歸明確的回報。 Ruby在代碼簡約/隱含的魔力方面很出色。這就是說,如果明確的回報會使事情變得更清晰或更易於閱讀,它不會損害任何東西。

0

贊本說。 「ruby方法的返回值是函數體中最後一條語句的返回值」這一事實導致return關鍵字在大多數ruby方法中很少使用。

def some_func_which_returns_a_list(x, y, z) 
    return nil if failed_some_early_check 


    # function code 

    @list  # returns the list 
end 
+4

如果你的意圖仍然清晰,你也可以寫「return nil if fail_some_early_check」 – 2009-06-21 08:36:27

+0

這是無效代碼,使答案混淆。 – 2011-08-10 03:17:52

+0

@Andew - 修正。希望現在適合你。 – Gishu 2011-08-10 04:49:15

1

這是你最喜歡哪種風格的問題。如果您想從方法中間的某個位置返回,則必須使用關鍵字return。

30

我個人使用的return關鍵字之間我所說功能的方法來區分,即那些主要執行用於它們的返回值的方法,和程序方法被主要是由於它們的副作用執行。因此,返回值很重要的方法會獲得一個額外的return關鍵字來引起對返回值的關注。

我使用相同的區別調用方法:功能方法得到括號,程序方法不要。

最後但並非最不重要的一點,我也將這種區別與塊結合使用:功能塊獲得大括號,程序塊(即「做」某些塊)得到do/end

不過,我儘量不信教一下:積木,大括號和do/end有不同的優先級,而不是增加明確的括號來消除歧義的表達,我只是切換到另一個風格。方法調用也是如此:如果在參數列表周圍添加括號可以使代碼更具可讀性,那麼即使所討論的方法本質上是程序性的,也是如此。

+1

現在我忽略了任何「單線」的回報,這與您所做的相似,我也做了其他所有事情。很高興知道我的風格並沒有完全消失。 :) – 2009-06-21 08:41:37

+0

@Jorg:你的代碼中使用了早期返回嗎?這是否會對您的程序/功能方案造成混淆? – 2011-08-10 03:16:36

+1

@安德魯格林:是的,是的。我正在考慮顛倒它。絕大多數我的方法都是透明的/純粹的/功能性的/無論你想要怎樣稱​​呼它,所以在那裏使用較短的形式是有意義的。用函數式編寫的方法往往沒有早期的回報,因爲這意味着「階梯」的概念,這不是很實用。雖然,我不喜歡中間的回報。我在開始的時候使用它們作爲守衛,或者在最後使用它們來簡化控制流程。 – 2011-08-10 08:06:16

13

其實最重要的是要區分:函數

  1. - 爲他們的返回值
  2. 程序執行的方法 - 其副作用執行的方法

Ruby沒有原生區分這些的方式 - 這使您容易寫程序side_effect()和另一個開發人員決定濫用程序的隱式返回值(基本上將其視爲不純功能)。

要解決這個問題,採取了葉出Scala和Haskell的書,讓你的程序明確地返回nil(又名其他語言Unit())。

如果你遵循這一點,那麼使用明確的return語法或不只是成爲個人風格的問題。

  1. 複製約爾格W¯¯米塔格真好寫有花括號和程序塊的功能塊與do/end
  2. 當你調用程序的想法,使用(),而當:

    函數和過程之間進一步區分你調用函數,不要

請注意,JörgW Mittag實際上主張其他方式 - 避免() s的程序 - 但這不是廣告因爲您希望副作用方法調用與變量明顯區分,特別是當參數爲0時。請參閱Scala style guide on method invocation以瞭解詳細信息。

3

我同意Ben Hughes,並且不同意Tim Holt的看法,因爲這個問題提到了Python的確切方式,並詢問Ruby是否有類似的標準。

It does.

這是預計在調試紅寶石問題任何人都應該合理地預期,瞭解它的語言這樣一個爲人熟知的特性。

7

The style guide指出,你不應該在最後的陳述中使用return。你仍然可以使用它if it's not the last one。這是社區嚴格遵守的慣例之一,如果您計劃與任何使用Ruby的人合作,您也應該如此。


話雖這麼說,使用顯式return S中的主要論點是,它是人們從其他語言混亂。

  • 首先,這不完全是Ruby專有的。例如Perl也有隱式返回。其次,大多數適用的人來自Algol語言。其中大多數是「較低級」比Ruby,因此你必須編寫更多的代碼來完成一些事情。

java中的方法長度(不包括getter/setters)的常見啓發式是一個屏幕。在這種情況下,您可能不會看到方法定義和/或已經忘記了您返回的位置。

另一方面,在Ruby中最好堅持使用方法less than 10 lines long。鑑於此,人們會想知道爲什麼當他們明確暗示時,他必須寫出多10%的陳述。


因爲Ruby沒有無效方法,一切也就更加簡潔,你是剛剛加入的開銷沒有的好處,如果你有明確return走吧。