如果这是一个新手问题,请原谅,但我正在读一本关于Rails的书,其中作者在Helper方法中使用了这个表达式:
@current_user ||= User.find_by_id(session[:user_id])
这种双管道的使用仍然是布尔或语句吗?
如果是这样的话,它是如何运作的?
dldeef671#
这是一种有条件的分配。来自here:
x = find_something() #=>nil x ||= "default" #=>"default" : value of x will be replaced with "default", but only if x is nil or false x ||= "other" #=>"default" : value of x is not replaced if it already is other than nil or false
f0brbegy2#
代码foo ||= bar几乎等同于foo = foo || bar。在Ruby中(就像在许多语言中一样,如JavaScript或Io),布尔运算符是“守卫”运算符。它们不是总是返回true或false,而是计算为第一个操作数的值,该操作数的计算结果为“真”值。
foo ||= bar
foo = foo || bar
true
false
例如,代码foo = 1 || delete_all_files_from_my_computer()不会删除任何内容:foo将设置为1,第二个操作数甚至不会求值。
foo = 1 || delete_all_files_from_my_computer()
1
在Ruby中,唯一“不真实”的值是nil和false。因此,如果foo是nil或false,代码foo ||= bar将只计算bar并将foo设置为结果。
nil
foo
bar
由于示例变量在未设置时默认为nil,因此,如果尚未设置示例变量,类似@foo ||= bar的代码是用于设置示例变量的常见Ruby习惯用法。
@foo ||= bar
r6l8ljro3#
你可以把它想成是:
@current_user = @current_user || User.find_by_id(session[:user_id])
首先计算@current_user,如果它非空,则OR短路,返回@CURRENT_USER的值,并且不调用User.find_by_id。
@current_user
(这只是因为在布尔上下文中,Ruby将NULL视为FALSE,而将非NULL视为TRUE。它不适用于像Java这样不将非布尔值视为真的语言。)
3条答案
按热度按时间dldeef671#
这是一种有条件的分配。来自here:
f0brbegy2#
代码
foo ||= bar
几乎等同于foo = foo || bar
。在Ruby中(就像在许多语言中一样,如JavaScript或Io),布尔运算符是“守卫”运算符。它们不是总是返回true
或false
,而是计算为第一个操作数的值,该操作数的计算结果为“真”值。例如,代码
foo = 1 || delete_all_files_from_my_computer()
不会删除任何内容:foo将设置为1
,第二个操作数甚至不会求值。在Ruby中,唯一“不真实”的值是
nil
和false
。因此,如果foo
是nil
或false
,代码foo ||= bar
将只计算bar
并将foo
设置为结果。由于示例变量在未设置时默认为
nil
,因此,如果尚未设置示例变量,类似@foo ||= bar
的代码是用于设置示例变量的常见Ruby习惯用法。r6l8ljro3#
你可以把它想成是:
首先计算
@current_user
,如果它非空,则OR短路,返回@CURRENT_USER的值,并且不调用User.find_by_id。(这只是因为在布尔上下文中,Ruby将NULL视为FALSE,而将非NULL视为TRUE。它不适用于像Java这样不将非布尔值视为真的语言。)