下面的代码在Ruby中是什么意思?
||=
它的语法有什么意义或原因吗?
下面的代码在Ruby中是什么意思?
||=
它的语法有什么意义或原因吗?
当前回答
X ||= y表示
如果x有任何值,不要改变它的值,否则 将x设为y
其他回答
准确地说,||= b意味着“如果a是未定义的或假的(false或nil),将a设置为b并求值为(即返回)b,否则求值为a”。
其他人经常试图用||= b等价于|| a = b或a = a || b来说明这一点。这些等价有助于理解这个概念,但要注意,它们并非在所有条件下都是准确的。请允许我解释:
a ||= b ⇔ a || a = b? The behavior of these statements differs when a is an undefined local variable. In that case, a ||= b will set a to b (and evaluate to b), whereas a || a = b will raise NameError: undefined local variable or method 'a' for main:Object. a ||= b ⇔ a = a || b? The equivalency of these statements are often assumed, since a similar equivalence is true for other abbreviated assignment operators (i.e. +=,-=,*=,/=,%=,**=,&=,|=,^=,<<=, and >>=). However, for ||= the behavior of these statements may differ when a= is a method on an object and a is truthy. In that case, a ||= b will do nothing (other than evaluate to a), whereas a = a || b will call a=(a) on a's receiver. As others have pointed out, this can make a difference when calling a=a has side effects, such as adding keys to a hash. a ||= b ⇔ a = b unless a?? The behavior of these statements differs only in what they evaluate to when a is truthy. In that case, a = b unless a will evaluate to nil (though a will still not be set, as expected), whereas a ||= b will evaluate to a. a ||= b ⇔ defined?(a) ? (a || a = b) : (a = b)???? Still no. These statements can differ when a method_missing method exists which returns a truthy value for a. In this case, a ||= b will evaluate to whatever method_missing returns, and not attempt to set a, whereas defined?(a) ? (a || a = b) : (a = b) will set a to b and evaluate to b.
好的,好的,那么||= b等于什么?有办法在Ruby中表达这一点吗?
好吧,假设我没有忽略任何东西,我相信||= b在功能上等价于……(击鼓声)
begin
a = nil if false
a || a = b
end
坚持住!这不是第一个前面有noop的例子吗?嗯,不完全是。还记得我之前说的||= b只有当a是一个未定义的局部变量时,||= b才不等于|| a = b吗?如果为false,则a = nil确保a永远没有定义,即使这一行永远不会执行。Ruby中的局部变量是词法范围的。
假设a = 2, b = 3
那么,||= b将得到a的值,即2。
当a计算为某个值时,结果不是false或nil..这就是为什么它不计算b的值。
现在假设a = nil, b = 3。
那么||= b将得到3,即b的值。
因为它首先尝试评估a的值,结果是nil..它求出b的值。
ror app中使用的最佳示例是:
#To get currently logged in iser
def current_user
@current_user ||= User.find_by_id(session[:user_id])
end
# Make current_user available in templates as a helper
helper_method :current_user
其中,User.find_by_id(session[:user_id])当且仅当@current_user之前未初始化时触发。
它的意思是或等于。它检查左边的值是否有定义,然后使用它。如果不是,使用右边的值。您可以在Rails中使用它来缓存模型中的实例变量。
一个基于rails的快速示例,我们创建了一个函数来获取当前登录的用户:
class User > ActiveRecord::Base
def current_user
@current_user ||= User.find_by_id(session[:user_id])
end
end
它检查是否设置了@current_user实例变量。如果是,它将返回该值,从而节省数据库调用。但如果没有设置,则执行调用,然后将@current_user变量设置为该值。这是一种非常简单的缓存技术,但非常适合在应用程序中多次获取相同的实例变量。
一个常见的误解是,||= b并不等同于a = a || b,但它的行为就像|| a = b。
但这里有一个棘手的情况。如果a未定义,则|| a = 42将引发NameError,而||= 42将返回42。所以,它们似乎不是等价的表达式。
除非x X = y 结束
除非x有值(不是nil或false),否则将其设为y
等于
X ||= y