1
\$\begingroup\$
def get_all_friends(uid, client)
 friends = client.friendships.friends(uid: uid)
 total = friends.total_number
 get_friends(total, 0, uid, client)
end
def get_friends(total, cursor, uid, client)
 left = total
 count = [200, left].min
 friends = client.friendships.friends(uid: uid, count: count, cursor: cursor)
 left -= count
 next_cursor = friends.next_cursor
 return friends if (left == 0 || next_cursor == 0)
 more_firends = get_friends(left, next_cursor, uid, client)
 more_firends.users << friends.users
 return more_firends
end
get_all_friends(uid, observer.client).users.map do |info|
 user = User.find_or_create_by_uid_and_name(uid: info.id, name: info.name)
 follow(user)
 user
end

This code is written in a functional style. Maybe there is a more natural way to structure it with Block.

And how can I reuse the code when client.friendships.friends(uid: uid, count: count, cursor: cursor) differs?


Update:

I reconstruct the code. It now looks more clean and general.

def get_all_friends(client, uid)
 fetch_all do |count, cursor|
 client.friendships.friends(uid: uid, count: count, cursor: cursor)
 end
end
def fetch_all(&fetch_proc)
 res = fetch_proc.call(10, 0)
 total = res.total_number
 return res if total <= 10
 fetch(total, 0, &fetch_proc)
end
def fetch(total, cursor, &fetch_proc)
 left = total
 count = [200, left].min
 res = fetch_proc.call(count, cursor)
 left -= count
 next_cursor = res.next_cursor
 if (left == 0 || next_cursor == 0)
 return res
 end
 more_res = fetch(left, next_cursor, &fetch_proc)
 more_res.users << res.users
 more_res
end
asked Dec 14, 2012 at 18:10
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

It looks pretty good to me. Some notes:

  • I'd avoid return on the last expression
  • I'd avoid the "-=" (not very functional)
  • I'd avoid inline returns (write a full-fledged conditional instead)
  • I have my doubts about this more_friends.users <<, is this a side-effect you are doing behind the caller's back?

As a general note, Ruby is an OOP language, you can strive for functional style (I do whenever possible), but still, use also an OOP structure or you'll end up with weird undiomatic code.

answered Dec 15, 2012 at 11:28
\$\endgroup\$
2
  • \$\begingroup\$ I do want the side-effect of more_friends.users <<. \$\endgroup\$ Commented Dec 15, 2012 at 14:11
  • \$\begingroup\$ +1 re inline returns. I used to use them a lot but now I prefer an if/else structure. \$\endgroup\$ Commented Dec 15, 2012 at 21:52

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.