Ruby 你一般怎么写链式调用的代码

fsword · August 26, 2012 · Last by zw963 replied at September 02, 2012 · 3556 hits

其实就是如何对齐的问题,我一般这么做

post.tags = post.tags.
                      delete_if(&:nil?).
                      map{|value| value.sub /^!/,''}.
                      delete_if(&:empty?)

我大概会写成这样:

post.tags = post.tags.
  delete_if(&:nil?).
  map{|value| value.sub /^!/,''}.
  delete_if(&:empty?)
post.tags = post.tags
                .delete_if(&:nil?)
                .map{|value| value.sub /^!/,''}
                .delete_if(&:empty?)

#1 楼 @lgn21st 我的 vim 就会这么自动格式化,不过感觉不太好,我贴出来的格式其实是参考了下面的格式

terminal_width ||= if $stdin && $stdin.tty?
                     ::HighLine::SystemExtensions::terminal_size[0]
                   else
                     80
                   end

#2 楼 @leozwa 我有时也会写成你这样的

.写前面好,可以随时注释掉任意一行

#4 楼 @reus 是的,我是从 1.8 继承下来的习惯,对于 1.9 来说已经没必要把点写到后面了

post.tags = post.tags.some_method

def some_method
  delete_if(&:nil?)
    .map{|value| value.sub /^!/,''}
    .delete_if(&:empty?)
end

只有我一个人写成一行吗。。

有的编辑器格式化功能会把别人对的很齐的代码给毁了。。

#7 楼 @jjym 写成一行也可以,只要你确信不会有麻烦就行,话说我又凑了篇博客 http://fsword.github.com/blog/2012/08/26/lian-shi-diao-yong-de-dai-ma-zen-yao-xie/ #8 楼 @hooopo 也许这能算个例子,说明 IDE 的作用在 DSL 语言中渐渐变得不重要了

好吧 我来 troll 一下

一个表达式里面有四个点是很强的 code smell 了。看你的代码,你是说 tag 为 nil 的,开头!的,空字串都不是有效的 tag。因为你用了 Ruby 里面比较基础的类 String(猜的)来表达 tag 所以就只能依赖 String 的操作来实现这个业务逻辑,就只能把多个方法穿起来

更好的方法是对 tag 的更好封装,在一个 class 里面。然后把逻辑定义在 tag.valid? 里面。这样你的 post.tags 可以按 {|tag| tag.valid?} 来选出合理的 tags. 这样的方法很方便被复用,需要增加或改变什么样的 tag 是 valid 也很容易

#10 楼 @knwang 用 java 开发类似功能的时候我确实会把 tag 变成一个 class,不过如果是 ruby 则不一定,一开始的逻辑其实很简单,就是把 tag 里面的一些特殊的东西剔除出去,因为没把握写好正则,所以写了这样的代码。 至于判断 code smell 也是要看场景的,当然如果要添加日志,还可以用 tap,我在 blog 里补充了例子(链接见 #9 楼)。 总的说来,是否需要建立对象其实是看复杂度的,只是 ruby 本身会把事情简化,所以其它语言需要建立很多对象,而用 ruby 的时候我会把精力放在更必要的场合

#4 楼 @reus 就是。删减中间行都很方便。

#1 楼 @lgn21st

Emacs 默认格式化后,和你的一样。

delete_if(&:nil?) ==> compact

#10 楼 @knwang

我赞成。👍 , 关键是 Ruby 下面,创建这样一个类,并实现验证方法,成本的确很低呀。

You need to Sign in before reply, if you don't have an account, please Sign up first.