How to refactor the following 2 function (4 lines each)

Hello

I’m trying to DRY my code and I think It could be done even better. The
following 2 functions are “before_save” callbacks that practically do
the
same thing, but on a different set of attributes.

Since the code is highly similar, I was wondering if someone could help
me
to refactor the code?

def normalize_budget
result = normalize_generic(self.budget)
self.budget_min = result[:min]
self.budget_max = result[:max]
self.budget = result[:display]
end

def normalize_size
result = normalize_generic(self.size)
self.size_min = result[:min]
self.size_max = result[:max]
self.size = result[:display]
end

Kind regards,
Axinte

def normalize(property)
result = normalize_generic(self.send(property))
self.send(“#{property}_min=”, result[:min])
self.send(“#{property}_max=”, result[:max])
self.send(“#{property}=”, result[:display])
end

object.normalize(:size)
object.normalize(:budget)

Maurício Linhares
http://codeshooter.wordpress.com/ | http://twitter.com/mauriciojr

Hi,

try this:

def normalize
update_result(“budget”)
update_result(“size”)
end

def update_result(field_name)
result = normalize_generic(self.send(field_name))
eval(“self.#{field_name}_min = result[:min]”)
eval(“self.#{field_name}_max = result[:max]”)
eval(“self.#{field_name} = result[:display]”)
end

Thank you both for your feedback. Based on your suggestions, I’ve
finally
decided to implement it in the following way:

%w[size budget].each do |property|
define_method(“normalize_#{property}_range”) do |*args|
result = normalize_generic_range(self.send(property))
self.send(“#{property}_min=”, result[:min])
self.send(“#{property}_max=”, result[:max])
self.send(“#{property}=”, result[:display])
end
end

this code defines normalize_size_range and normalize_budget_range and
updates both sets of attributes accordingly.

kind regards,
Axinte

2009/8/27 Gianluca T. [email protected]

Here’s a better solution:

%w[size budget].each do |property|
class_eval %Q!
def normalize_#{property}_range
result = normalize_generic_range( self.#{property} )
self.#{property}_min = result[:min]
self.#{property}_max = result[:max]
self.#{property} = result[:display]
end
!
end

Maurício Linhares
http://codeshooter.wordpress.com/ | http://twitter.com/mauriciojr

Mauricio,

Thank you again for your help. Is there any difference between your
solution
and mine?
Kind regards,
Axinte

2009/8/27 Maurício Linhares [email protected]

Yes, you’re defining and method and using send at every call, my
solution will generate a method with direct calls instead of sending
them.

Maurício Linhares
http://codeshooter.wordpress.com/ | http://twitter.com/mauriciojr