了解 Rails 方法中的布尔连接语句

Understanding a Boolean conjunction statement in Rails method

这可能是一个微不足道的问题,但我不明白,这让我很困扰。 通过 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 不会 return "true",因此为 nil。这只是风格问题,还是 'user &&' 在此表达式中做了一些微妙的事情?

尝试执行此部分:user.authenticate(params[:session][:password]) 在不知道对象是否存在的情况下会引发错误。因此,在尝试对它进行 运行 .authenticate 之前,您需要确保拥有 user 对象。这有意义吗?

if userif user.present? 相同。因此,如果它为零,则转到 else 语句,如果为真,则它运行第二条语句 user.authenticate(params[:session][:password])

你为什么不直接问 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 doesn't have an authenticate method (why would it), so trying to call authenticate on nil will raise a NoMethodError

布尔运算符从左到右延迟计算(有时称为 "short-circuiting"),仅在确定结果所需的范围内计算。因为usernil,所以已经知道整个条件的结果一定是假的,不管右操作数是什么,所以右永远不会评估操作数,因此永远不会调用不存在的方法。


注意:我不是想在这里油嘴滑舌,而是想向您展示一个强大的学习工具:如果您想知道 "what happens if I do XYZ",只需做 XYZ,看看会发生什么!与化学相反,实验在编程中是完全安全的。 (好吧……你可以删除你的硬盘,如果你真的很笨,但如果你在沙盒环境中进行实验,你会没事的。意外删除有价值的数据是极不可能的,除非你正在玩弄 FileFileUtils 类.)