elado
elado

Reputation: 8760

Ruby if vs end of the line if behave differently?

Why doesn't this code work?

b if b = true

Error: undefined local variable or method `b'

But this does:

if b = true
    b
end

Shouldn't they be the same?

Upvotes: 17

Views: 3100

Answers (5)

Ali Akbar
Ali Akbar

Reputation: 368

you have put only one '='

Try with '=='

Then you will get error

In second example, you are assigning 'true' to b.

Upvotes: 1

DigitalRoss
DigitalRoss

Reputation: 146231

Because the Ruby interpreter creates a local variable when it sees an assignment

In the second case, it hasn't yet seen the assignment, so the variable doesn't exist when the expression is parsed.

To be more precise, a method is first parsed into an internal representation, and then, perhaps, the code will eventually be called and actually executed.

Local variables are created in that parsing pass. It's a matter of declaration, it just means that the interpreter becomes aware of them. They won't be created in the sense of being given space or a value until the surrounding method is called by someone.

Upvotes: 0

Michael Papile
Michael Papile

Reputation: 6856

This is a very good question. It has to do with the scoping of variables in Ruby.

Here is a post by Matz on the Ruby bug tracker about this:

local variable scope determined up to down, left to right. So a local variable first assigned in the condition of if modifier is not effective in the left side if body. It's a spec.

Upvotes: 17

KARASZI István
KARASZI István

Reputation: 31477

I don't know the reason but the problem that the interpreter tries to lookup the variable k before evaluating the condition.

If you write it like this, there won't be any error and works as you expected:

k = nil
h = {k: 1}
v = k if k = h.delete(:k)

Upvotes: 2

Dave Newton
Dave Newton

Reputation: 160291

In the first version as soon as k is hit, the parser pukes because it hasn't been seen yet.

In the second version, k is part of an assignment expression, and is parsed differently.

Upvotes: 2

Related Questions