Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix #3591] Handle modifier if in Variable#reference!() #7336

Merged

Conversation

jonas054
Copy link
Collaborator

@jonas054 jonas054 commented Sep 8, 2019

Assignments in modifier if/unless conditions are special. The following program
exits with the error "undefined local variable or method `a' for main:Object"
when executed.

puts a if (a = @x)

A preceding assignment to a is needed to put it in scope. So there are no
useless assignments in

a = nil
puts a if (a = @x)

Assignments in modifier if/unless conditions are special. The following program
exits with the error "undefined local variable or method `a' for main:Object"
when executed.

```
puts a if (a = @x)
```

A preceding assignment to `a` is needed to put it in scope. So there are no
useless assignments in

```
a = nil
puts a if (a = @x)
```
@bbatsov bbatsov merged commit fca7d43 into rubocop:master Sep 11, 2019
@bbatsov
Copy link
Collaborator

bbatsov commented Sep 11, 2019

Nice catch! I wonder if that's intentional or it's a bug in Ruby...

@jonas054 jonas054 deleted the 3591_UselessAssignment_in_modifier_if branch September 13, 2019 18:10
@jonas054
Copy link
Collaborator Author

It has to be intentional. Has to be. From The Ruby Language FAQ:

4.3 When does a local variable become accessible?

Actually, the question may be better asked as: "at what point does Ruby work out that something is a variable?" The problem arises because the simple expression a could be either a variable or a call to a method with no parameters. To decide which is the case, Ruby looks for assignment statements. If at some point in the source prior to the use of a it sees it being assigned to, it decides to parse a as a variable, otherwise it treats it as a method.

Here's an even weirder example:

a = nil if false # This line is needed.
puts a if (a = @x) # This is fine.

It's not about assignments being executed. It's all about being seen prior to use. And a = @x is not prior to puts a so it doesn't help when dereferencing a.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants