在Ruby中显式返回是不错的风格吗?

来自Python背景,在风格方面总是有一个“正确的方式去做”(“Pythonic”方式),我想知道Ruby是否也存在。 我一直在使用自己的风格指南,但是我正在考虑发布我的源代码,我希望它遵守任何可能存在的不成文规则。

是“Ruby途径”明确键入方法return ? 我已经看到它完成了,但有没有一个正确的方法来做到这一点? 有没有适当的时间去做? 例如:

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

老问题(和“回答”)的问题,但我会折腾我的两分钱作为答案。

TL; DR – 你不必这样做,但是在某些情况下,它可以使你的代码更加清晰。

尽pipe不使用明确的返回可能是“Ruby的方式”,但是使用不熟悉代码的程序员或者不熟悉Ruby的这个特性会让人感到困惑。

例如,可能会有一个像这样的小函数,它将传入的数字加1,并将其分配给一个实例variables。

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

这是否意味着一个函数,返回一个值,或不? 很难说开发人员的意思,因为它既分配实例variables,也返回分配的值。

假设很久以后,另外一个程序员(可能不太熟悉Ruby如何根据最后一行代码执行返回操作),并且希望将一些打印语句放入日志中,函数变成了这个…

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

现在如果有什么需要返回值的话 ,函数就会被中断。 如果没有什么期望返回的值,那没关系。 显然,如果在代码链的更远处,调用它的东西需要返回一个值,那么它就会失败,因为它没有恢复到期望值。

现在真正的问题是这样的:真的有什么期望返回值? 这是否打破了一些东西? 它会在未来破坏一些东西吗? 谁知道! 只有全面的代码审查所有电话会让你知道。

至less对我来说,最好的做法是要么非常明确地表明,如果事情重要,你就要回报什么,要么什么都不回报。

所以在我们的小演示函数的情况下,假设我们希望它返回一个值,它将被写入像这样…

 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%清楚发生了什么? 它将从字面上不会影响您的代码的执行能力。

不。良好的Ruby风格通常只使用明确的回报来提前回报 。 Ruby在代码简约/隐含的魔力方面很出色。

也就是说,如果一个明确的回报会使事情变得更清楚或更容易阅读,它不会损害任何东西。

我个人使用return关键字来区分我所谓的function方法 ,即主要针对其返回值执行的方法和主要针对其副作用执行的过程方法 。 所以,返回值很重要的方法,得到一个额外的return关键字来引起注意返回值。

调用方法时我使用相同的区别:函数方法得到括号,程序方法不能。

最后但并非最不重要的一点是,我也将这种区分用于块:function块获得大括号,程序块(即“做”某些东西的块)得到do / end

不过,我尽量不要对此表示religious:,用块,花括号和do / end有不同的优先级,而不是添加明确的括号来消除一个expression式的歧义,而是转换到另一种风格。 方法调用也是如此:如果在参数列表周围添加括号使得代码更具可读性,那么即使所讨论的方法本质上是程序性的,也是如此。

其实重要的是区分:

  1. 函数 – 为其返回值执行的方法
  2. 程序 – 为副作用执行的方法

Ruby没有区分这些方法的本地方法 – 这使得你容易写一个过程side_effect() ,另一个开发者决定滥用你程序的隐式返回值(基本上把它当作不纯的函数)。

为了解决这个问题,从Scala和Haskell的书中抽出一个叶子,让你的程序显式地返回nil (在其他语言中也被称为Unit() )。

如果你遵循这一点,那么使用明确的return语法或不只是成为个人风格的问题。

为了进一步区分function和程序:

  1. 复制JörgW Mittag用花括号编写function块的好主意,以及用do/end程序块
  2. 当你调用过程时,使用() ,而当你调用函数时,不要

请注意,JörgW Mittag实际上主张另一种方法 – 避免() s用于过程 – 但这不是可取的,因为您希望副作用的方法调用与variables明显区分,特别是当arity为0时。特别是当方法的样式指南调用细节。

风格指南指出,你不应该在你上一次的陈述中使用return 。 如果不是最后一个,你仍然可以使用它。 这是社区严格遵守的惯例之一,如果您打算与任何使用Ruby的人进行协作,也应该如此。


这就是说,使用显式return的主要论点是,来自其他语言的人们感到困惑。

  • 首先,这不完全是Ruby专有的。 例如,Perl也有隐式的返回。
  • 其次,大部分适用的人都来自阿尔戈尔语言。 其中大部分是比Ruby更“低级”的 ,所以你必须编写更多的代码来完成某些工作。

java中的方法长度(不包括getter / setter)的常见启发式是一个屏幕 。 在这种情况下,您可能不会看到方法定义和/或已经忘记了您返回的位置。

另一方面,在Ruby中,最好坚持less于10行的方法。 鉴于此,人们会想,为什么当他们明确暗示的时候,他还要多写10%的陈述。


由于Ruby没有void方法,所有东西都更加简洁,所以如果你使用显式的return ,那么只是增加开销而没有任何好处。

我同意本•休斯(Ben Hughes)并且不同意Tim Holt,因为这个问题提到了Python做这个决定性的方法,并问Ruby是否有类似的标准。

它确实。

这是这种语言的一个众所周知的特性,任何人都希望能够合理地预料到在ruby中debugging问题。

这是大多数人喜欢的风格。 如果您想从方法中间的某处返回,则必须使用关键字return。

像本说的。 “ruby方法的返回值是函数体中最后一个语句的返回值”的事实导致return关键字在大多数ruby方法中很less使用。

 def some_func_which_returns_a_list( x, y, z) return nil if failed_some_early_check # function code @list # returns the list end