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

Lint/UnusedMethodArgument overriding reassignment and zsuper #4892

Closed
akhramov opened this issue Oct 20, 2017 · 5 comments
Closed

Lint/UnusedMethodArgument overriding reassignment and zsuper #4892

akhramov opened this issue Oct 20, 2017 · 5 comments

Comments

@akhramov
Copy link

akhramov commented Oct 20, 2017

Per #4823 (comment) @mvz discovered an interesting case when overriding reassignment appears with zero-arity super call.

In this case, the value of a variable is unused, so cop suggests to rename the variable. But since super call is zsuper, it captures the reassigned variable:

def foo(a)
  a = 43

  super
end

The problem has been resolved by using non-zero arity super:

def foo(_a)
  super 43
end

That being said, reassignment is capured by zsuper, but original variable's value is not used.

What should we do in such situation? Suggest using super instead of zsuper? Add a configuration option to ignore this case? Both?

Update: binding call should have a similar problem.

@Drenmi
Copy link
Collaborator

Drenmi commented Oct 20, 2017

I think we could augment the "unused argument" logic to tell if there's a call to super. In that case we consider it used. 🙂

@akhramov
Copy link
Author

@Drenmi, i thought of that solution. My concern is that argument's value is unused. Is it a big deal?

@Drenmi
Copy link
Collaborator

Drenmi commented Oct 20, 2017

@akhramov: Perhaps that is a new cop entirely? Lint/ShadowedArgument?

Something like:

Argument `a` was shadowed by a local variable before it was used.

WDYT?

@akhramov
Copy link
Author

@Drenmi, agreed.

Should the cop have config options for disabling zsuper / binding cases? Like IgnoreBinding and IgnoreZeroAritySuper?

@mvz
Copy link
Contributor

mvz commented Oct 20, 2017

I solved my case by changing the zsuper to super with arguments. If that's the preferred syntax (and I tend to agree that it is), then the cops basically work and the only issue is documentation.

akhramov pushed a commit to akhramov/rubocop that referenced this issue Nov 6, 2017
Since recently, unused argument cops (`Lint/UnusedBlockArgument` and
`Lint/UnusedMethodArgument`) handle the case of shadowed
arguments. However, shadowed arguments detection functionality differs
semantically from unused arguments cops, and, as such, should be
extracted to a separate cop.

This change
* Introduces `Lint/ShadowedArgument` cop.
* Makes `Cop::VariableForce::Assignment` capable of tracking
  assignment's references.
* Removes the shadowed argument detection algorithm from unused
  argument cops.

## `Lint/ShadowedArgument` cop.

### The algorithm
The shadowed argument detection algorithm is slightly improved, so it
handles the case when reassignment occurs inside blocks or conditionals
of arbitrary nesting. The algoritm takes in account argument
reassigning in blocks (fixes rubocop#4898).

The algorithm searches for reassignment nodes and reports offenses on them
if an argument was reassigned before it was referenced.
In case if the argument  was reassigned inside a block or conditional, the
algorithm signals that precise offense location is undecidable (since
it's unknown whether an entity is executed). In this case, offense
is reported on argument's declaration node.

### Configuration
It's reported (rubocop#4892) that in real-life code there may be situtations
when argument shadowing is used in order to pass
parameters to `zsuper`:

```ruby
def foo(bar)
  bar = 42
  super
end
```

If authors tend to use this style, they can use the
`IgnoreImplicitReferences` configuration option.
@bbatsov bbatsov closed this as completed in 6857e0a Nov 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants