Reputation: 681
I have a User model, which have voting methods. I want to write proxy methods for voting.
This is readable way:
def vote_up item
return false unless can? :vote, item
vote item, :up
end
def vote_down item
return false unless can? :vote, item
vote item, :down
end
And this is DRY way:
%w(up down).each do |vtype|
define_method "vote_#{vtype}" do |item|
return false unless can? :vote, item
vote item, vtype.to_sym
end
end
Which one is better and why?
Upvotes: 9
Views: 221
Reputation: 3919
Neither(sorry).
def vote_count(item,vtype)
return false unless can? :vote, item
vote item, vtype
end
Good luck
Upvotes: 2
Reputation: 11647
Purely because OP seemed to like my comment, I'll put it as an answer:
Personally, considering you only have 2 methods here, and it's unlikely you'd ever add more (vote_sideways? vote_diagonally?) I would just go with the readable way. If you could potentially have many, many more though, I would go with the DRY way (because it becomes easily extendible) with a readable comment to explain to other developers (or to yourself later!).
Upvotes: 3
Reputation: 160261
Both.
I'm with Anil; just pass in a type--meta-programming this as a first-resort is yucky.
That said, I am a fan of convenience methods--but they should call the generic method with the type.
This keeps the generated method concise--the real work is done in the generic method, but the API user still gets the same convenience methods.
Upvotes: 0
Reputation: 798
IMHO, in this case, readability trumps dry. It scans quickly, and is easily grokked. Having said that, if you start adding vote types the second approach may be more flexible. YMMV.
Upvotes: 1