锁定老帖子 主题:Ruby函数式风格编程
该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2007-02-05
回到主题,Ruby之所以比Python、groovy和Javascript更适合函数风格的编程,尤其是erlang风格,主要因为以下几点:
例一、 命令式风格: ruby 代码
ruby 代码
注意15行删nil项,因为在一个if .. end子句中,总会返回一个值,在不满足所有条件的情况下,就是返回nil 例二 命令式风格: ruby 代码
ruby 代码
或者: ruby 代码
函数式风格的好处是,如果这一段代码只是为了给某几个变量赋值,那么函数式的写法一目了然,副作用也变得尽在掌控中。而命令式风格则没那个好处了。 说明: 1、并行赋值的重要性主要在于让处理分支中的多变量赋值时方便,否则例二中的情况就很难用函数式风格处理了 2、例二中的a,b,c,d当然可以直接用[]括起来处理(如上),但我用abcd也是为了让代码一目了然,个人感觉而已。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-02-06
确实有意思,能多讲讲ruby的FP编程吗?
|
|
返回顶楼 | |
发表时间:2007-02-06
返回多值其实就是个列表
并行赋值倒是有意思,但这不是FP的一部分 |
|
返回顶楼 | |
发表时间:2007-02-06
* everything is message(也即任何语句都会返回值)
* may return multiple values(可以返回多值) * parallel assignment(并行赋值 ------------------------------------ 这些跟FP编程有什么关系? |
|
返回顶楼 | |
发表时间:2007-02-06
有意思
|
|
返回顶楼 | |
发表时间:2007-02-06
我的意思是函数式“风格”,尤其是我打算用的erlang的风格。
即使没有上面说的几条,python, javascript和groovy等也都可以有各自的函数式风格,但就是不那么直接了当。 比如在javascript里,if-else子句是不能想象成一个函数的,也就是说你不能写: var a = if (cond()) 1; else 2; 当然有其它转换成函数形式的方法(不包括var a = cond() ? 1 : 2;),比如象上面那句: var a = (cond() && 1) || (true && 2); 这种例子很多人写过。 还有就是ruby的begin-end子句,可以直接把一段“括”起来并返回最后一句作为值,这样就可以随手在ruby代码中写一段函数,而不用先定义lambda,然后再call它。比如上面那一段: :limit => begin limit = par[:m] ? par[:m].to_i : 20 limit >= 4096 ? 4096 : limit end, 并行赋值和多值返回跟是否FP确实关系不大,但ruby里的这些内建语法让这些东西写起来比较有我喜欢的风格。如果写一个javascript的例子,也不会那么直接了当滴。 有空我会把找到的erlang和ruby之间的一些对应贴出来。 |
|
返回顶楼 | |
发表时间:2007-02-06
begin...end就是个lambda
if cond()那个例子是模式匹配,我只在haskell erlang见过 |
|
返回顶楼 | |
发表时间:2007-02-07
这是另一段代码,是一个直来直去的权限条件判定,返回一个hash给以后的find用:
prvlg_cond = privilege_cond(user, params[:g]) Feed.find(:all, :conditions => [prvlg_cond[:pre], *prvlg_cond[:sub]) 有点象erlang了。 # grp_str: p -> public(0) , u -> user(1), f -> friends(2) def privilege_cond(user, grp_str) grp_str ||= 'puf' cond = {:pre => "", :sub => []} cond = if loggedin?(user) frds = grp_str.include?('f') ? user.friends.find(:all) : [] frd_ids = frds.collect { |frd| frd.friend_id.to_i } cond = if grp_str.include?('u') {:pre => cond[:pre] + (cond[:pre] == "" ? "" : "OR") + " user_id = ? ", :sub => cond[:sub] + [user.id]} else cond end cond = if grp_str.include?('f') && !frd_ids.empty? {:pre => cond[:pre] + (cond[:pre] == "" ? "" : "OR") + " user_id in (?) AND privilege in (?) ", :sub => cond[:sub] + [frd_ids, [0, 2]]} else cond end cond = if grp_str.include?('p') {:pre => cond[:pre] + (cond[:pre] == "" ? "" : "OR") + " user_id != ? AND privilege = ? ", :sub => cond[:sub] + [user.id, 0]} else cond end else {:pre => "privilege = ?", :sub => [0]} end end |
|
返回顶楼 | |
发表时间:2007-02-10
Javascript if-else的方案:
var a = function() { if (cond()) return 1; else return 2; }() 不知道是不是画了一条用脚走路的蛇,另外对性能可能也有影响。 |
|
返回顶楼 | |
发表时间:2007-02-14
dcaoyuan 写道 这是另一段代码,是一个直来直去的权限条件判定,返回一个hash给以后的find用:
prvlg_cond = privilege_cond(user, params[:g]) Feed.find(:all, :conditions => [prvlg_cond[:pre], *prvlg_cond[:sub]) 有点象erlang了。 # grp_str: p -> public(0) , u -> user(1), f -> friends(2) def privilege_cond(user, grp_str) grp_str ||= 'puf' cond = {:pre => "", :sub => []} cond = if loggedin?(user) frds = grp_str.include?('f') ? user.friends.find(:all) : [] frd_ids = frds.collect { |frd| frd.friend_id.to_i } cond = if grp_str.include?('u') {:pre => cond[:pre] + (cond[:pre] == "" ? "" : "OR") + " user_id = ? ", :sub => cond[:sub] + [user.id]} else cond end cond = if grp_str.include?('f') && !frd_ids.empty? {:pre => cond[:pre] + (cond[:pre] == "" ? "" : "OR") + " user_id in (?) AND privilege in (?) ", :sub => cond[:sub] + [frd_ids, [0, 2]]} else cond end cond = if grp_str.include?('p') {:pre => cond[:pre] + (cond[:pre] == "" ? "" : "OR") + " user_id != ? AND privilege = ? ", :sub => cond[:sub] + [user.id, 0]} else cond end else {:pre => "privilege = ?", :sub => [0]} end end 上面的代码感觉有点坏味道,可以重构一下么? |
|
返回顶楼 | |