I'm wondering if there is a more "Ruby-like" way to memoize functions with multiple parameters in Ruby. Here's a way that I came up with that works but not sure if it's the best approach:
@cache = {}
def area(length, width) #Just an example, caching is worthless for this simple function
key = [length.to_s, width.to_s].join(',')
if @cache[key]
puts 'cache hit!'
return @cache[key]
end
@cache[key] = length * width
end
puts area 5, 3
puts area 5, 3
puts area 4, 3
puts area 3, 4
puts area 4, 3
The parameters are joined with a comma which is then used as a key for storage in the @cache
variable.
When you do not need to print Cache hit!
than I would do something like this:
def area(length, width)
@cache ||= {}
@cache["#{length},#{width}"] ||= length * width
end
Or if you need some output, but a Cache miss!
is fine too:
def area(length, width)
@cache ||= {}
@cache.fetch("#{length},#{width}") do |key|
puts 'Cache miss!'
@cache[key] = length * width
end
end
If you want to accept even more arguments you might want to use something like this:
def area(*args)
@cache ||= {}
@cache[args] ||= args.inject(:*)
end
You can use the array directly:
def area(length, width)
key = [length, width]
if @cache[key]
puts 'cache hit!'
return @cache[key]
end
@cache[key] = length * width
end
Or use nested hashes:
def area(length, width)
c = (@cache[length] ||= {})
if c[width]
puts 'cache hit!'
return c[width]
end
c[width] = length * width
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With