虽然打算把自己的一个开源项目移植到erlang,但手头的一个工作项目却是在用ruby on rails,花了一段时间了解ruby后,发现ruby还是有点意思的。(反倒是不太喜欢Rails。我喜欢直来直去的编程,rails里面太多的magic,实在让我这个喜欢刨根究底的人难受)。
回到主题,Ruby之所以比Python、groovy和Javascript更适合函数风格的编程,尤其是erlang风格,主要因为以下几点:
例一、
命令式风格:
函数时风格:
注意15行删nil项,因为在一个if .. end子句中,总会返回一个值,在不满足所有条件的情况下,就是返回nil
例二
命令式风格:
函数式风格:
或者:
函数式风格的好处是,如果这一段代码只是为了给某几个变量赋值,那么函数式的写法一目了然,副作用也变得尽在掌控中。而命令式风格则没那个好处了。
说明:
1、并行赋值的重要性主要在于让处理分支中的多变量赋值时方便,否则例二中的情况就很难用函数式风格处理了
2、例二中的a,b,c,d当然可以直接用[]括起来处理(如上),但我用abcd也是为了让代码一目了然,个人感觉而已。
回到主题,Ruby之所以比Python、groovy和Javascript更适合函数风格的编程,尤其是erlang风格,主要因为以下几点:
- everything is message(也即任何语句都会返回值)
- may return multiple values(可以返回多值)
- parallel assignment(并行赋值)
例一、
命令式风格:
ruby 代码
- cond = {}
- if par[:id]
- feed = Feed.find(par[:id])
- if feed
- cond[:feed] = feed.id
- end
- end
- if par[:m]
- limit = par[:m].to_i
- else
- limit = 20
- end
- if limit >= 4096
- limit = 4096
- end
- cond[:limit] = limit
- if par[:d]
- days = par[:d].to_f
- if days <= 0 || days >= 365
- days = 365
- end
- cond[:time] = Time.now - days*86400
- end
ruby 代码
- cond = {
- :feed => if par[:id]
- feed = Feed.find(par[:id])
- feed ? feed.id : nil
- end,
- :limit => begin
- limit = par[:m] ? par[:m].to_i : 20
- limit >= 4096 ? 4096 : limit
- end,
- :time => if par[:d]
- days = par[:d].to_f
- days = days <= 0 || days >= 365 ? 365 : days
- Time.now - days * 86400
- end,
- }.delete_if { |k, v| v.nil? } # delete all nil elements of cond
注意15行删nil项,因为在一个if .. end子句中,总会返回一个值,在不满足所有条件的情况下,就是返回nil
例二
命令式风格:
ruby 代码
- if f[:mode] == "rss"
- rss = f[:feed]
- params[:feed][:channel] = rss.channel.title
- params[:feed][:description] = rss.channel.description
- params[:feed][:link] = rss.channel.link
- params[:feed][:copyright] = rss.channel.copyright
- else
- atom = f[:feed]
- params[:feed][:channel] = atom.title
- params[:feed][:description] = atom.subtitle
- params[:feed][:link] = atom.links.join
- params[:feed][:copyright] = atom.rights
- end
ruby 代码
- params[:feed][:channel],
- params[:feed][:description],
- params[:feed][:link],
- params[:feed][:copyright] = if f[:mode] == "rss"
- rss = f[:feed]
- a, b, c, d = rss.channel.title,
- rss.channel.description,
- rss.channel.link,
- rss.channel.copyright
- else
- atom = f[:feed]
- a, b, c, d = atom.title,
- atom.subtitle,
- atom.links.join,
- atom.rights
- end
或者:
ruby 代码
- params[:feed][:channel],
- params[:feed][:description],
- params[:feed][:link],
- params[:feed][:copyright] = if f[:mode] == "rss"
- rss = f[:feed]
- [rss.channel.title,
- rss.channel.description,
- rss.channel.link,
- rss.channel.copyright]
- else
- atom = f[:feed]
- [atom.title,
- atom.subtitle,
- atom.links.join,
- atom.rights]
- end
函数式风格的好处是,如果这一段代码只是为了给某几个变量赋值,那么函数式的写法一目了然,副作用也变得尽在掌控中。而命令式风格则没那个好处了。
说明:
1、并行赋值的重要性主要在于让处理分支中的多变量赋值时方便,否则例二中的情况就很难用函数式风格处理了
2、例二中的a,b,c,d当然可以直接用[]括起来处理(如上),但我用abcd也是为了让代码一目了然,个人感觉而已。