我正在使用Ruby on Rails的authlogic gem,我一直在使用以下内容来获取当前登录用户的id:
current_user = UserSession.find
id = current_user && current_user.record.id
我不明白current_user&& current_user.record.id返回当前用户ID。我认为这将返回一个布尔值。有人可以解释这是如何工作的吗?
答案 0 :(得分:19)
Ruby中没有Boolean
类型; Ruby对事实有一个相当简单的看法(或者更确切地说,它有一个相当简单的 falsehood 视图)。
false
对象,FalseClass
的单例实例被视为 falsy nil
对象,NilClass
的单例实例 falsy true
对象,它是TrueClass
的单例实例 [BTW:这意味着很多在其他语言中被认为是 falsy 的对象在Ruby中实际上是 truthy ,就像整数0
,实数值0.0
,空字符串,空数组,空哈希,字符'F'
]
因此,布尔运算符&&
,||
,and
和or
不会返回布尔值。相反,他们返回确定表达式结果的第一个对象。
(它们也是短路的,这意味着它们只评估确定表达式结果所需的最小子表达式。因此,另一种表述是它们返回最后一个表达式的结果反过来,这类似于块,方法,类主体和模块体所做的事情。)
那么,意味着返回确定结果的第一个对象是什么意思?这很简单,真的:表达式的结果
a && b
如果 a
和b
真实, 真实,否则虚假< / strong>即可。因此,如果a
falsy ,完全与b
无关:结果将是 falsy 办法。所以,我们也可以简单地返回a
。 (请记住,a不必是false
,也可能是nil
,程序员可能想知道它是哪一个。)
如果,OTOH,a
真实(IOW既不是nil
也不是false
),那么整个表达式的结果是仅依赖于b
:如果b
真实,则整个结果将为 truthy ,否则如果b
是 falsy ,整个结果将是 falsy 。因此,我们也可以返回b
本身,而不是先将其转换为布尔值。
||
和or
与&&
和and
类似或更准确地对。
您发布了此示例:
id = current_user && current_user.record.id
在这里,作者甚至不希望
current_user
成为布尔值!相反,他希望它可以是User
或nil
。但这非常好,因为User
真实而nil
虚假,因此它们仍可用于布尔表达式。
基本意图是,如果作者试图在NoMethodError
上致电#record
,则希望阻止引发nil
例外。
另一种表达方式是
id = current_user.record.id unless current_user.nil?
如果您需要所有血腥细节,请查看Draft ISO Ruby Specification的第11.1节(第36页)或RubySpec project的可删除规范。 (Here's the one for &&
。)
为了好玩,我写了一次pure Ruby implementation of Ruby's Boolean operators and conditional expressions。这些实现的核心是two mixins。
答案 1 :(得分:9)
逻辑和短路。这意味着如果构造是X&amp;&amp; Y和X是假的,然后Y永远不会被检查,因为整个事情肯定会产生错误。
该代码基本上是这样说的:
if (current_user is TRUE) {
id = current_user.record.id;
]
这是一些控制台输出,显示如果第一个值为真,则获得第二个值:
irb(main):005:0> true && 9
=> 9
如果第一个是零则为零:
irb(main):008:0> nil && 9
=> nil