Ruby code below seems to be not so dry. Can you please help me reduce the code.

self.value = case self.type
when 'fast'
  Increment.first.max_hours * Incrementor.first.fast_completion_day
when 'super_fast'
  Increment.first.max_hours * Incrementor.first.super_fast_completion_day 
when 'ludicrous'
  Increment.first.max_hours * Incrementor.first.ludicrous_completion_day 
  Increment.first.max_hours * Incrementor.first.budget_completion_day 

I think we can use Ruby metaprogamming here to reduce the code. But I am not very good with ruby meta programming at the moment.


You can try:

day = case self.type
  when 'fast'       then :fast_completion_day
  when 'super_fast' then :super_fast_completion_day
  when 'ludicrous'  then :ludicrous_completion_day
  else                   :budget_completion_day

self.value = Increment.first.max_hours * Incrementor.first.send(day)

From a friend that knows more than me:

prefix = %w[ fast super_fast ludicrous ].include?(self.type) ? self.type : "budget"
self.value = Increment.first.max_hours * Incrementor.first.send(:"#{prefix}_completion_day")

This is probably about as short and dry as you can get it. That said, I'm not sure that this is more clear/easy to read. I'd probably add a method to Incrementor like Incrementor#completion_day_for(type) that would take care of this logic for you.

  • \$\begingroup\$ Thank you so much @Martin. Hope this is just a start for me to write better codes. \$\endgroup\$ Aug 19 '11 at 7:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.