从[] =使用ruby的隐式返回值是否可以

时间:2012-10-30 09:15:24

标签: ruby

如果在使用[]=方法

时使用ruby的隐式返回值,我可以徘徊

[]=使用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)的隐式回复吗?

4 个答案:

答案 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