这可能是一个微不足道的观点,但我不理解它并且困扰我。 经过Michael Hartl的Ruby on Rails Tutorial,有这个方法定义:
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
redirect_to user
else
flash.now[:danger] = "Invalid email/password combination"
render 'new'
end
end
我不明白为什么是连词
user && user.authenticate(params[:session][:password])
是必要的。当然,user.authenticate不会返回" true"如果用户对象为空,则为零。这仅仅是一种风格问题,还是用户&&'在这个表达中做一些微妙的事情?
答案 0 :(得分:2)
if user
与if user.present?
相同。所以如果它是nil,它会转到else语句,如果它是true,那么它运行第二个语句为user.authenticate(params[:session][:password])
答案 1 :(得分:1)
尝试执行此部分:user.authenticate(params[:session][:password])
而不首先知道对象是否存在将引发错误。因此,在尝试运行user
之前,您需要确保拥有.authenticate
对象。这有意义吗?
答案 2 :(得分:1)
为什么不问问Ruby自己有什么区别?
user = nil
if user && user.authenticate(nil) then end
if user user.authenticate(nil) then end
# NoMethodError: undefined method `authenticate' for nil:NilClass
正如您所看到的,nil
没有authenticate
方法(为什么会这样),因此尝试在authenticate
上调用nil
{{}} raise
3}}一个NoMethodError
。
只有在确定结果所需的范围内,才会从左到右懒惰地评估布尔运算符(有时称为"短路")。由于user
是nil
,因此已知整个条件的结果必须是假的,无论右操作数是什么,因此右操作数永远不会评估,因此,永远不会调用不存在的方法。
注意:我并不想在这里做个傻瓜,我试图向你展示一个强大的学习工具:如果你想知道如果我做XYZ"会发生什么,只是做XYZ,看看会发生什么!相反,比如化学,实验在编程中是完全安全的。 (嗯......你可以删除你的硬盘,如果你真的很愚蠢,但是如果你在沙盒环境中进行实验,那你就没事了。除非你在玩弄,否则很可能删除有价值的数据File
或FileUtils
类。)