3

I have a question about how the Ruby interpreter assigns variables:

I use this quite often:

return foo if (foo = bar.some_method)

where some_method returns an object or nil.

However, when I try this:

return foo if (true && (foo = bar.some_method))

I get: NameError: undefined local variable or method foo for main:Object.

What is the difference in evaluation between the first and second lines that causes the second line to error?

1
  • 2
    Because the assignment will be short-circuited in the second variation. But meh, I'm not sure this is a pattern that lends itself to readability. Commented Feb 12, 2014 at 22:53

1 Answer 1

8

Read it carefully :

Another commonly confusing case is when using a modifier if:

p a if a = 0.zero?

Rather than printing true you receive a NameError, “undefined local variable or method 'a'”. Since Ruby parses the bare a left of the if first and has not yet seen an assignment to a it assumes you wish to call a method. Ruby then sees the assignment to a and will assume you are referencing a local method.

The confusion comes from the out-of-order execution of the expression. First the local variable is assigned-to then you attempt to call a nonexistent method.

As you said - None return foo if (foo = bar.some_method) and return foo if (true && (foo = bar.some_method)) will work, I bet you, it wouldn't work, if you didn't define foo before this line.

Sign up to request clarification or add additional context in comments.

1 Comment

Damn I thought I deleted this question! I realized shortly after I posted that I had already defined foo in irb when I tested this out. I'll leave up this evidence of my noobness for others to learn from. Thanks for answering.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.