Ruby 这两种风格的 ruby 代码大 PK

zyfire · 2014年02月21日 · 最后由 coolesting 回复于 2014年03月05日 · 3993 次阅读

  1. 你自己写哪种。
  2. 当你需要维护他人代码时,代码是哪种。
  3. 当我说上面两个代码可能有 bug 时,你觉得哪个代码的 bug 好确认。

其实我有严重的倾向性:我期望第 1 种。

我是 ruby 新手。。。严重倾向第 2 种。。。。

倾向第二种:第二种 bug 不好确认,因为他引起 bug 的机会不多……

倾向第二种,因为毕竟简洁太多了

class Integer
  def fact
    (1..self).reduce(:*) || 1
  end
end

抄的 stackoverflow 的,他又是抄的http://rosettacode.org/wiki/Factorial#Ruby

当我说上面两个代码可能有 bug 时,你觉得哪个代码的 bug 好确认。

当然是第二种,代码越长 bug 越多

当然第二种 推荐仔细研读 API 找到 API 里最合适的方法 这样的一行代码是必然不能出错的 出错只能说明 还需要练习...

好像大家都觉得 思考第 2 种风格的代码是否有 bug 的时间比第 1 种少

个人感觉就算熟悉 inject 的人,在考虑实现 bug 时,思考复杂度第 2 种也更高。

有没有人推崇《代码大全》 推崇《代码大全》的你,会倾向哪个呢?

刚从别的语言转过来时用第一种,对 ruby 的各种方法了解了以后用第二种。ruby 的方法特别是 Array、String 这两个类的方法太重要了,最好把这两个类的所有方法都滚瓜烂熟

第二种。并且我倾向于使用 reduce 而不是 inject,虽然它们互为别名。

第一种是过程式编程的风格。手动定义中间变量,手动迭代,手动相加。

第二种是函数式编程的风格。将 fact 的运算思考成一个以 1 到 n 的数组的 reduce 相乘。如果用 haskell 来写的话,第一种根本写不出来。

#8 楼 @zyfire 或者换一种思考方式不知道你能不能接受 这种局部小功能的代码 应该是条件反射一样的写出来而不是先思考怎样的复杂度和怎样的计算过程 想做这个功能就固定反射出某些写法

第二种一眼就能看出干什么, 第一种花费的时间更长一点。

有简洁的函数式用,为啥还要用 C 语言样的过程?

除非有一种可能,就是代码暂时是用的 Ruby 写的, 不久的未来是打算迁移到 C/C++ 上的。

关键问题是,第一种写法并没有增加可读性啊。反而因为多了冗余信息,我感觉可读性还下降了。

当然,从来没接触过 Ruby 的人,可能更容易看懂第一种写法,但问题是这样的人,还敢让他维护 Ruby 代码?那得是多心宽啊。

既然标题是 Ruby 代码大 PK 答案就很明显了 :)

楼主,第一种实现是错的,会报 returne 方法未定义

#4 楼 @heliang7

def fact
  (1..self).reduce 1, :*
end

1: 2 2: 2 3: 2 #4 楼 @heliang7 猴子还是不要太多...

歪楼的来了~

"程序的优雅性不是可以或缺的奢侈品,而是决定成功还是失败的一个要素。优雅并不是一个美学的问题,也不是一个时尚品味的问题,优雅能够被翻译成可行的技术。牛津字典对 elegant 的解释是:pleasingly ingenious and simple。如果你的程序真的优雅,那么它就会容易管理。第一是因为它比其它的方案都要短,第二是因为它的组件都可以被换成另外的方案而不会影响其它的部分。很奇怪的是,最优雅的程序往往也是最高效的。

为什么这么少的人追求优雅?这就是现实。如果说优雅也有缺点的话,那就是你需要艰巨的工作才能得到它,需要良好的教育才能欣赏它。"

为什么有人说别的语言转 Ruby 会写第一种,我的第一反应是::

def fact(n)
  if n == 0
    1
  else
    n * fact(n - 1)
  end
end

或者用?:三元运算符写成单行版。

#19 楼 @yuhaidonghd 递归太深就栈溢出了

reduce + 1,inject 语义上感觉怪怪的,reduce 更主流些 Python 和 JavaScript 里都是 reduce。

匿名 #22 2014年02月22日

人艰不拆,这和风格没有关系。 菜鸟一般都不熟悉 fold map 之类的东西,只能看懂第一种,如果和一群菜鸟合作,就这样写。

人艰也拆

建议第二种,第一种明显是从 c java 等语言的思路,ruby 的强大在于提供的 lib 能够解决实际问题的同时能够保持代码的简洁

#22 楼 @jex 如果和一群菜鸟合作,就教他们学会第二种

当然第 2 种,一眼看出来是在搞啥,第 1 个盯 5 秒才明白,还是参考了方法名字。

匿名 #26 2014年02月23日

#24 楼 @fsword 菜鸟之所以为菜鸟,不是知识储备上的问题,而是。。。他们永远不想学第二种

怎么说呢,既然你用 ruby,当然是第二种,这完全不算风格上的差异,而是思维和认知上的差异,如果真心喜欢第一种风格我觉得 ruby 不适合你

<- 单行代码控

这个问题本质上是抽象模式 和 协作便捷性 间的权衡。

第二种是函数式编程,抽象模式上更接近问题域,更具有表达性。因此第二种在抽象模式上完胜。 如果你的协作对象是没有函数式思想的程序员(无论他是不是新手),用第二种编程方式对于协作者而言并不友好。

如果是我,我会用第二种编程方式,但会加上注释给协作者解释第二种的意思。

如果加上合理的注释你就不会纠结了

#11 楼 @alsotang 用哪个方法别名主要还是看上下文情境,没有定死了的。

我觉得最最最关键的就是闭包里的逻辑是不是真这么简单,如果真这么简单 肯定第二种。。。现实中复杂的业务逻辑就得更容易阅读

第一种,一开始就 return,表面看似节能,其实对于代码的维护带来不少的麻烦, 第二种,虽然自己也经常用,虽然简洁,但也不是正确的写法。

一个良好的习惯就是,

1,开始对所有要用的值进行初始化。 2,返回值 放到最后,尽量不要中间 return 或开头。

不同的人有不同的看法,但我是从一个软件的设计和维护来看待这个问题

需要 登录 后方可回复, 如果你还没有账号请 注册新账号