2

According to this stack question,

and is the same as && but with lower precedence

And I understand this well. And I believe this question is not duplicate to the above question.

In my controller when executing the following code:

user = user_email.present? && User.find_by(email: user_email)

user variable holds the active record object for User model. And thus executing user.valid_password? user_password gave no error and test passed successfully.

But when I tried to replace && with and the result is quite surprising.

When I tried with following code:

user = user_email.present? and User.find_by(email: user_email)

user variable holds the boolean value and thus executing user.valid_password? user_passwordgave following error:

undefined method `valid_password?' for true:TrueClass

Can anyone please explain why this is happening.

Community
  • 1
  • 1
SujitS
  • 11,063
  • 3
  • 19
  • 41
  • 1
    It is happening because `and` has lower precenedce than assignment. Same applies to `or` in Ruby. Because of this, those 2 work more like control structures than operators, allowing you to do things like `do_something() or fail`, but is often confusing for new Ruby programmers. – Borsunho Sep 16 '15 at 12:01

2 Answers2

7
user = user_email.present? and User.find_by(email: user_email)

is interpreted as:

(user = user_email.present?) and User.find_by(email: user_email)

and present? returns true or false, which is assigned to user.

sawa
  • 165,429
  • 45
  • 277
  • 381
  • So, that means `User.find_by(email: user_email)` will not take an effect if we use `and` operator ? – SujitS Sep 16 '15 at 10:05
  • 1
    @SujitS It will not have any effect unless this single line is further part of a surrounding structure. – sawa Sep 16 '15 at 10:06
  • It is because, as was mentioned in the very beginning, "=" has a higher precedence than "and". (user = user_email.present?) and evaluation stops there because = has higher precedence. – Lonny Eachus Sep 12 '17 at 18:20
-3

Your user variable have TrueClass. TrueClass have no "valid_password?" method. Thats why it happens to your code.

> a = true 
> a.valid_passowrd?
> undefined method `valid_password?' for true:TrueClass

Why it must works?

Alexandr
  • 7
  • 4