下面的代码在Ruby中是什么意思?

||=

它的语法有什么意义或原因吗?


当前回答

一个常见的误解是,||= b并不等同于a = a || b,但它的行为就像|| a = b。

但这里有一个棘手的情况。如果a未定义,则|| a = 42将引发NameError,而||= 42将返回42。所以,它们似乎不是等价的表达式。

其他回答

这个问题在Ruby邮件列表和Ruby博客上讨论得如此频繁,以至于现在Ruby邮件列表上甚至有一些线程,它们的唯一目的就是收集到Ruby邮件列表上讨论这个问题的所有其他线程的链接。

这里有一个:||= (OR Equal)线程和页面的最终列表

如果你真的想知道发生了什么,可以看看Ruby语言规范草案的第11.4.2.3节“缩写赋值”。

作为第一近似,

a ||= b

等于

a || a = b

并不等同于

a = a || b

然而,这只是一种近似,特别是在a未定义的情况下。根据是简单的变量赋值、方法赋值还是索引赋值,语义也有所不同:

a    ||= b
a.c  ||= b
a[c] ||= b

都有不同的待遇。

简而言之,||=b意味着:如果a是undefined、nil或false,则将b赋值给a。否则,保持a不变。

||=是一个条件赋值运算符

  x ||= y

等于

  x = x || y

或者

if defined?(x) and x
    x = x
else 
    x = y
end

如果X没有值,它将被赋值为y,否则,它将保留它的原始值,在本例中为5:

irb(main):020:0> x = 5
=> 5
irb(main):021:0> y = 10
=> 10
irb(main):022:0> x ||= y
=> 5

# Now set x to nil. 

irb(main):025:0> x = nil
=> nil
irb(main):026:0> x ||= y
=> 10
b = 5
a ||= b

这句话的意思是:

a = a || b

这将是

a = nil || 5

所以最后

a = 5

现在如果你再调用这个:

a ||= b
a = a || b
a = 5 || 5
a = 5

b = 6

现在如果你再调用这个:

a ||= b
a = a || b
a = 5 || 6
a = 5 

如果你观察,b的值不会被分配给a, a仍然有5。

它是Ruby中用来加快访问速度的一种记忆模式。

def users
  @users ||= User.all
end

这句话的意思是:

@users = @users || User.all

第一次调用这个方法时,你会调用数据库。

以后对该方法的调用将只返回@users实例变量的值。