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

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)
```
@koic
koic approved these changes Sep 8, 2019
@bbatsov bbatsov merged commit fca7d43 into rubocop-hq:master Sep 11, 2019
0 of 15 checks passed
0 of 15 checks passed
ci/circleci: cc-setup Your tests are queued behind your running builds
Details
ci/circleci: documentation-checks Your tests are queued behind your running builds
Details
ci/circleci: jruby-9.2-ascii_spec Your tests are queued behind your running builds
Details
ci/circleci: jruby-9.2-rubocop Your tests are queued behind your running builds
Details
ci/circleci: ruby-2.3-ascii_spec Your tests are queued behind your running builds
Details
ci/circleci: ruby-2.3-rubocop Your tests are queued behind your running builds
Details
ci/circleci: ruby-2.4-ascii_spec Your tests are queued behind your running builds
Details
ci/circleci: ruby-2.4-rubocop Your tests are queued behind your running builds
Details
ci/circleci: ruby-2.5-ascii_spec Your tests are queued behind your running builds
Details
ci/circleci: ruby-2.5-rubocop Your tests are queued behind your running builds
Details
ci/circleci: ruby-2.6-ascii_spec Your tests are queued behind your running builds
Details
ci/circleci: ruby-2.6-rubocop Your tests are queued behind your running builds
Details
ci/circleci: ruby-head-ascii_spec Your tests are queued behind your running builds
Details
ci/circleci: ruby-head-rubocop Your tests are queued behind your running builds
Details
continuous-integration/appveyor/pr Waiting for AppVeyor build to complete
Details
@bbatsov

This comment has been minimized.

Copy link
Collaborator

commented Sep 11, 2019

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

@bbatsov bbatsov added the weird ruby label Sep 11, 2019
@jonas054 jonas054 deleted the jonas054:3591_UselessAssignment_in_modifier_if branch Sep 13, 2019
@jonas054

This comment has been minimized.

Copy link
Collaborator Author

commented Sep 13, 2019

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
3 participants
You can’t perform that action at this time.