红宝石运算符|| =聪明吗? [英] Is the ruby operator ||= intelligent?

查看:65
本文介绍了红宝石运算符|| =聪明吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆