KEMBAR78
`Layout/FirstParameterIndentation` and `Layout/ClosingParenthesisIndentation` do not take into account method call chains · Issue #5650 · rubocop/rubocop · GitHub
Skip to content

Layout/FirstParameterIndentation and Layout/ClosingParenthesisIndentation do not take into account method call chains #5650

@cupakromer

Description

@cupakromer

Both Layout/FirstParameterIndentation and Layout/ClosingParenthesisIndentation do not take into account method call chains when suggesting alignment options when the first method call is multi-line.

Expected behavior

Rubocop passes with the following alignment styles.

good1 = bar.meth(
  :arg1,
  :arg2,
  options: :hash,
)

good2 = foo.methA(:arg1, :arg2, options: :hash)
           .methB(
             :arg1,
             :arg2,
           )
           .methC

good3 = foo.methA(
             :arg1,
             :arg2,
             options: :hash,
           )
           .methB(
             :arg1,
             :arg2,
           )
           .methC

Going from the good2 example, where the first method is all on a single line, to good3 example is common when arguments or options are added to the method call making the line too long.

Additionally, this multi-line method call chain style is more common in Rails where the methods are query conditions (where) or other similar query relation/condition method (e.g. includes, select, etc.).

Actual behavior

The good3 example fails with the following errors:

example.rb:15:14: C: Layout/FirstParameterIndentation: Indent the first parameter one step more than the start of the previous line.
             :arg1,
             ^^^^^

example.rb:18:12: C: Layout/ClosingParenthesisIndentation: Indent ) the same as the start of the line where ( is.
           )
           ^

As demonstrated via the good2 example this only affects the first method call in the chain.

Asking Rubocop to autofix the issue results in the following which, in IMO, is harder to read / parse:

good3 = foo.methA(
  :arg1,
  :arg2,
  options: :hash,
)
           .methB(
             :arg1,
             :arg2,
           )
           .methC

Steps to reproduce the problem

  • Copy the Expected Behavior example into a file example.rb
  • Using the default Rubocop run: rubocop example.rb

RuboCop version

Include the output of rubocop -V. Here's an example:

$ rubocop -V
0.53.0 (using Parser 2.5.0.3, running on ruby 2.5.0 x86_64-darwin16)

If this is a duplicate of #2625 my apologies, I wasn't sure given the method chaining nature of this style.

The follow cops seem related, but don't seem to affect the first method call when it is on the same line as the receiver:

  • Layout/MultilineMethodCallIndentation
  • Layout/MultilineMethodCallBraceLayout

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementstaleIssues that haven't been active in a while

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions