红宝石运算符|| =聪明吗? [英] Is the ruby operator ||= intelligent?
问题描述
我对ruby中的|| =语句有疑问,这对我来说特别有意义,因为我正在使用它来写入memcache.我想知道的是,|| =会在调用该setter之前先检查接收器以查看是否已设置,或者它实际上是x = x || y
I have a question regarding the ||= statement in ruby and this is of particular interest to me as I'm using it to write to memcache. What I'm wondering is, does ||= check the receiver first to see if it's set before calling that setter, or is it literally an alias to x = x || y
对于普通变量而言,这并不重要,但是使用类似以下内容的
This wouldn't really matter in the case of a normal variable but using something like:
CACHE[:some_key] ||= "Some String"
可能会执行比简单变量集更昂贵的memcache写操作.我在ruby api中找不到关于|| =的任何信息,所以我自己也无法回答.
could possibly do a memcache write which is more expensive than a simple variable set. I couldn't find anything about ||= in the ruby api oddly enough so I haven't been able to answer this myself.
我当然知道:
CACHE[:some_key] = "Some String" if CACHE[:some_key].nil?
将实现这一目标,我只是在寻找最简洁的语法.
would achieve this, I'm just looking for the most terse syntax.
推荐答案
这非常容易测试:
class MyCache
def initialize
@hash = {}
end
def []=(key, value)
puts "Cache key '#{key}' written"
@hash[key] = value
end
def [](key)
puts "Cache key '#{key}' read"
@hash[key]
end
end
现在只需尝试使用||=
语法:
Now simply try the ||=
syntax:
cache = MyCache.new
cache["my key"] ||= "my value" # cache value was nil (unset)
# Cache key 'my key' read
# Cache key 'my key' written
cache["my key"] ||= "my value" # cache value is already set
# Cache key 'my key' read
因此,我们可以得出结论,如果缓存键已经存在,则不会进行任何分配.
So we can conclude that no assignment takes place if the cache key already exists.
以下Rubyspec摘录显示 根据设计,并且不应依赖于Ruby实现:
The following extract from the Rubyspec shows that this is by design and should not be dependent on the Ruby implementation:
describe "Conditional operator assignment 'obj.meth op= expr'" do
# ...
it "may not assign at all, depending on the truthiness of lhs" do
m = mock("object")
m.should_receive(:foo).and_return(:truthy)
m.should_not_receive(:foo=)
m.foo ||= 42
m.should_receive(:bar).and_return(false)
m.should_not_receive(:bar=)
m.bar &&= 42
end
# ...
end
在同一文件中,[]
和[]=
有类似的规范,要求具有相同的行为.
In the same file, there is a similar spec for []
and []=
that mandates identical behaviour.
尽管Rubyspec仍在开发中,但是很明显,主要的Ruby实现项目都打算遵守它.
Although the Rubyspec is still a work in progress, it has become clear that the major Ruby implementation projects intend to comply with it.
这篇关于红宝石运算符|| =聪明吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!