-
-
Save mileszs/406791 to your computer and use it in GitHub Desktop.
| class Memcached | |
| def fetch(key) | |
| if value = get(key) | |
| value | |
| elsif block_given? | |
| begin | |
| add(key, value = yield) | |
| rescue Memcached::NotStored => e | |
| value = get(key) | |
| end | |
| value | |
| end | |
| end | |
| end |
So: def fetch(key); get(key) || yield if block_given?; end
This is a copy of ActiveSupport::Cache::Store#fetch, more or less. http://apidock.com/rails/ActiveSupport/Cache/Store/fetch
The goal is, if there's no value from the #get, store the return value of the block as the value for the given key.
@avdi recently highlighted Hash#fetch. idk, place the yield as an argument to #add. One liner bliss?
Haha, there's that. It's a difficult method to make elegant, because it seems necessary to write it very defensively.
Looking at it again...the rescue clause is useless since #get should return nil since nothing was stored. Here's another stab:
def fetch(key)
value = get(key)
if value.nil? && block_given?
value = yield
add(key, value)
end
value
rescue Memcached::NotStored
nil # or do we want value, the result of the yield? change the above to ensure?
end
And now to curse FriendFeed. :-)
I don't know that it's necessarily completely useless. If, for some reason, the add to Memcache is slow, and a key of the same name gets added between the check for a value and the completion of our add, we'll get the NotStored error. If that happens, we want to return the value of the key that was stored while we were trying to store something else. Haha.
Maybe it's overly defensive? I don't know. I left it out initially, but I can see its purpose.
def fetch(key)
get(key) || add(key, yield) rescue get(key) if block_given?
end
Is that legal? Ruby ♥ moment if it is. Where's the spec?
Semantics are wrong. Hash#fetch doesn't store if there's no value. So you should yield and do nothing else but return.