如果在使用[]=
方法
[]=
使用rb_hash_aset
并返回val
- http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-5B-5D-3D
这里有一些代码来证明我的意思:
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
当然longer_cached
速度较慢,因为它会执行两次哈希查找以返回缓存值,但是当您逐行读取它时,它比cached
方法更有意义。
我认为使用隐式返回是让ruby很棒的事情之一,但我总是质疑它们在设置值时的用法。
所以我的问题是:你会使用来自(hash[key] = val)
的隐式回复吗?
答案 0 :(得分:2)
在这种情况下,您也可以使用||=
运算符。
CACHE[key] ||= uncached_method(key)
这是一个非常常见的习语。
答案 1 :(得分:1)
因为到目前为止没人提到它:你不依赖于Hash#[]=
的返回值。无论如何,该返回值都会被忽略:
class ReturnFortyTwo
def []=(*)
return 42
end
end
r = ReturnFortyTwo.new
r[23] = 'This is the value that is going to be returned, not 42'
# => 'This is the value that is going to be returned, not 42'
在Ruby中,赋值表达式始终计算为正在分配的值。没有例外。语言规范保证了这一点。所以,我认为依靠它没有任何错误。
答案 2 :(得分:0)
在这种情况下,较短的一个是优选的。通常在子表达式中使用的=
是不受欢迎的,但这里没关系。
答案 3 :(得分:0)
我会尽可能保持简单和干净(它也更快):
def cached(key)
value = CACHE[key]
unless value
value = uncached_method(key)
CACHE[key] = value
end
value
end