I am wandering if it is OK to use ruby’s implicit return value when using []= method
[]= uses rb_hash_aset and it is returning val – http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-5B-5D-3D
here is a little code to demonstrate what I mean:
require 'benchmark'
CACHE = {}
def uncached_method(key)
warn "uncached"
rand(100)
end
def cached(key)
CACHE[key] || (CACHE[key] = uncached_method(key))
end
def longer_cached(key)
return CACHE[key] if CACHE[key]
CACHE[key] = uncached_method(key)
CACHE[key]
end
Benchmark.bm(7) do |x|
y = rand(10000)
cached(y)
x.report("shorter:") { 10000000.times do cached(y) end }
x.report("longer:") { 10000000.times do longer_cached(y) end }
end
of course longer_cached is slower because it does two hash lookups to return cached value, but when you read it line by line it makes more sense then the cached method.
I think using implicit returns is one of the things that makes ruby awesome, but I have always questioned their use when setting values.
So my question is: would you use implicit return from (hash[key] = val)?
Just because nobody mentioned it so far: you are not relying on the return value of
Hash#[]=. That return value gets ignored anyway:In Ruby, assignment expressions always evaluate to the value that is being assigned. No exception. That is guaranteed by the Language Specification. So, I don’t see anything wrong with relying on that.