Functinal Style Ruby
After playing with Ruby for weeks, I found Ruby is yet interesting. I try to write my code a bit in the likeness of Erlang, where symbol vs atom, array vs list. And the most important syntax that I like are:
- everything return a value
- may return multiple values
- begin-end clause is lambda that may be directly applied
- parallel assignment
Now, let's write some code before and after (functional):
Example1:
Before
1. cond = {}
2. if par[:id]
3. feed = Feed.find(par[:id])
4. if feed
5. cond[:feed] = feed.id
6. end
7. end
8. if par[:m]
9. limit = par[:m].to_i
10. else
11. limit = 20
12. end
13. if limit >= 4096
14. limit = 4096
15. end
16. cond[:limit] = limit
17. if par[:d]
18. days = par[:d].to_f
19. if days <= 0 || days >= 365
20. days = 365
21. end
22. cond[:time] = Time.now - days*86400
23. end
After
1. cond = {
2. :feed => if par[:id]
3. feed = Feed.find(par[:id])
4. feed ? feed.id : nil
5. end,
6. :limit => begin
7. limit = par[:m] ? par[:m].to_i : 20
8. limit >= 4096 ? 4096 : limit
9. end,
10. :time => if par[:d]
11. days = par[:d].to_f
12. days = days <= 0 || days >= 365 ? 365 : days
13. Time.now - days * 86400
14. end,
15. }.delete_if { |k, v| v.nil? } # delete all nil elements of cond
Example2:
Before
1. if f[:mode] == "rss" 2. rss = f[:feed] 3. params[:feed][:channel] = rss.channel.title 4. params[:feed][:description] = rss.channel.description 5. params[:feed][:link] = rss.channel.link 6. params[:feed][:copyright] = rss.channel.copyright 7. else 8. atom = f[:feed] 9. params[:feed][:channel] = atom.title 10. params[:feed][:description] = atom.subtitle 11. params[:feed][:link] = atom.links.join 12. params[:feed][:copyright] = atom.rights 13. endAfter
1. params[:feed][:channel], 2. params[:feed][:description], 3. params[:feed][:link], 4. params[:feed][:copyright] = if f[:mode] == "rss" 5. rss = f[:feed] 6. 7. [rss.channel.title, 8. rss.channel.description, 9. rss.channel.link, 10. rss.channel.copyright] 11. else 12. atom = f[:feed] 13. 14. [atom.title, 15. atom.subtitle, 16. atom.links.join, 17. atom.rights] 18. end
Example3
1. # grp_str: p -> public(0) , u -> user(1), f -> friends(2)
2. def privilege_cond(user, grp_str)
3. grp_str ||= 'puf'
4. cond = {:pre => "", :sub => []}
5. cond = if loggedin?(user)
6. frds = grp_str.include?('f') ? user.friends.find(:all) : []
7. frd_ids = frds.collect { |frd| frd.friend_id.to_i }
8.
9. cond = if grp_str.include?('u')
10. {:pre => cond[:pre] + (cond[:pre] == "" ? "" : "OR") +
11. " user_id = ? ",
12. :sub => cond[:sub] + [user.id]}
13. else
14. cond
15. end
16.
17. cond = if grp_str.include?('f') && !frd_ids.empty?
18. {:pre => cond[:pre] + (cond[:pre] == "" ? "" : "OR") +
19. " user_id in (?) AND privilege in (?) ",
20. :sub => cond[:sub] + [frd_ids, [0, 2]]}
21. else
22. cond
23. end
24.
25. cond = if grp_str.include?('p')
26. {:pre => cond[:pre] + (cond[:pre] == "" ? "" : "OR") +
27. " user_id != ? AND privilege = ? ",
28. :sub => cond[:sub] + [user.id, 0]}
29. else
30. cond
31. end
32. else
33. {:pre => "privilege = ?",
34. :sub => [0]}
35. end
36. end
![(please configure the [header_logo] section in trac.ini)](/chrome/site/blog_logo.png)
rss
Comments
No comments.