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

时间:2009-06-21 03:38:12

标签: ruby coding-style return-value

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

在方法中明确键入return是“Ruby方式”吗?我已经看到它有没有完成,但有没有正确的方法呢?可能有正确的时间吗?例如:

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

8 个答案:

答案 0 :(得分:213)

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

TL; DR - 您没有必要,但它可以使您的代码在某些情况下更加清晰。

虽然不使用显式返回可能是“Ruby方式”,但是对于使用不熟悉的代码或者不熟悉Ruby的这个特性的程序员来说,它会让人感到困惑。

这是一个有点人为的例子,但是成像具有这样的小功能,它会为传递的数字增加一个,并将其分配给实例变量。

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

任何程序员都会非常清楚它确实会返回一个值,并且在没有意识到的情况下更难以打破它。

或者,可以像这样编写它并省略return语句......

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

但是为什么要把这个词留下来呢?为什么不把它放在那里,让它100%清楚发生了什么?它实际上对您的代码执行能力没有影响。

答案 1 :(得分:66)

没有。好的Ruby样式通常只会为早期返回使用显式返回。 Ruby在代码极简主义/隐式魔法方面很重要。

那就是说,如果一个明确的回报会让事情变得更清晰,或者更容易阅读,那么它就不会有任何损害。

答案 2 :(得分:31)

我个人使用return关键字来区分我称之为功能方法,即主要针对其返回值执行的方法,以及程序方法这主要是为了他们的副作用而执行的。因此,返回值很重要的方法是,获取额外的return关键字以引起对返回值的注意。

调用方法时,我使用相同的区别:函数方法获取括号,而程序方法则没有。

最后但并非最不重要的是,我也使用块的区别:功能块获得花括号,程序块(即“做”某事的块)获得do / end

但是,我尽量不对它有所了解:使用块,花括号和do / end具有不同的优先级,而不是添加明确的括号来消除表达式的歧义,我只是切换到另一种风格。方法调用也是如此:如果在参数列表周围添加括号使得代码更具可读性,我就这样做,即使所讨论的方法本质上是程序性的。

答案 3 :(得分:13)

实际上重要的是区分:

  1. 函数 - 为其返回值执行的方法
  2. 程序 - 为其副作用执行的方法
  3. Ruby没有本地区分这些的方法 - 这使您很容易编写过程side_effect()而另一个开发人员决定滥用过程的隐式返回值(基本上将其视为不纯函数)。

    要解决此问题,请从Scala和Haskell的书中删除,并让您的过程明确返回nil(又名Unit()其他语言)。

    如果您遵循这一点,那么使用明确的return语法或不仅仅是个人风格。

    进一步区分功能和程序:

    1. 复制JörgWMittag使用花括号编写功能块的好主意,以及do/end
    2. 的程序块
    3. 调用过程时,请使用(),而在调用函数时,请不要
    4. 请注意,JörgWMittag实际上提倡反过来 - 避免程序使用() - 但这是不可取的,因为您希望副作用方法调用能够与变量明确区分,特别是当arity为0时。 Scala style guide on method invocation了解详情。

答案 4 :(得分:7)

The style guide表示,您不应该在上次发言时使用return。您仍然可以使用它if it's not the last one。这是社区严格遵守的惯例之一,如果您计划与使用Ruby的任何人合作,也应如此。

话虽如此,使用明确的return的主要理由是,对于来自其他语言的人来说,这会让人感到困惑。

  • 首先,这并不是Ruby独有的。例如,Perl也有隐式返回。
  • 其次,这适用的大多数人来自Algol语言。其中大部分都是&#34;低级&#34; 而不是Ruby,因此你必须编写更多代码才能完成任务。

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

另一方面,在Ruby中,最好坚持使用方法less than 10 lines long。考虑到这一点,人们会想知道为什么当他们明确暗示时,他必须多写10%以上的陈述。

由于Ruby没有 void 方法,而且一切都更加简洁,如果你使用明确的return,你只是增加了开销,没有任何好处。

答案 5 :(得分:4)

我同意Ben Hughes并且不同意Tim Holt,因为这个问题提到了Python的确切方式,并询问Ruby是否有类似的标准。

It does.

这是一种众所周知的语言功能,任何人都希望能够合理地预期调试ruby中的问题。

答案 6 :(得分:1)

这是你最喜欢哪种风格的问题。如果要从方法中间的某处返回,则必须使用关键字return。

答案 7 :(得分:0)

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

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


  # function code 

  @list     # returns the list
end