I have a class that has hashes in various stages of “completion”. This is to optimize so that I don’t have to keep recreating hashes with root data that I already know. For example this is a counter called @root that would serve as a starting point.
{3=>4, 4=>1, 10=>3, 12=>5, 17=>1}
and it took key+key+key+key+key number of iterations to create @root. But now I have all combinations of [x,y] left to be added to the counter and individually evaluated. So I could do it like:
a = (1..52)
a.combination{|x,y|
evaluate(x,y)
}
But instead of I would like to do this:
a.each{|x|
evaluate(x, "foo")
a.each {|y| evaluate(y, "bar")}
}
Where i have a method like this to keep track of the hash at each state:
def evaluate index, hsh
case hsh
when "root"
@root.key?(index) ? @root[index] += 1 : @root[index] = 1
when "foo"
@foo = @root.clone
@foo.key?(index) ? @foo[index] += 1 : @foo[index] = 1
when "bar"
@bar = @foo.clone
@bar.key?(index) ? @bar[index] += 1 : @bar[index] = 1
end
end
But there is alot of repetition in this method. Is there a way that I could do this dynamically without using eval?
Instead of using
hshas a string descriptor, you can directly pass thehashobject as parameter to your methodevaluate? E.g. instead ofevaluate(x, "foo")you writeAlso note the
@root.clonein your code overwrites the field several times inside the loop.Additionally if you use a default initializer for your hash you save quite some logic in your code. E.g. the code lines
will set the default value to zero if non was set for
index. Thus you do not have to take care of the special case inside yourevaluatemethod.