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

Layout/LineEndStringConcatenationIndentation not following EnforcedStyle in hashes #9927

Closed
fuegas opened this issue Jul 12, 2021 · 10 comments
Closed
Assignees

Comments

@fuegas
Copy link

fuegas commented Jul 12, 2021

Given this source file test.rb:

{
  field: 'some_field',
  error: :invalid,
  reason: 'some_field has'\
    'an invalid value',
}

puts 'String on'\
  'multiple rows'

and .rubocop config:

Layout/LineEndStringConcatenationIndentation:
  EnforcedStyle: indented

running rubocop --only Layout/LineEndStringConcatenationIndentation -- test.rb gives the following output:

⋗ rubocop --only Layout/LineEndStringConcatenationIndentation -- test.rb
Inspecting 1 file
C

Offenses:

test.rb:5:5: C: [Correctable] Layout/LineEndStringConcatenationIndentation: Align parts of a string concatenated with backslash.
    'an invalid value',
    ^^^^^^^^^^^^^^^^^^

1 file inspected, 1 offense detected, 1 offense auto-correctable

I would expect no offenses in that file.

When I change the source to

{
  field: 'some_field',
  error: :invalid,
  reason: 'some_field has'\
          'an invalid value',
}

puts 'String on'\
  'multiple rows'

no offense is shown.

As I've set EnforcedStyle: indented, I expected the first example to work.

RuboCop version

⋗ bundle exec rubocop -V
1.18.3 (using Parser 3.0.2.0, rubocop-ast 1.7.0, running on ruby 2.7.4 x86_64-darwin20)
  - rubocop-performance 1.11.4
  - rubocop-rails 2.11.3
@koic koic added bug and removed bug labels Jul 13, 2021
@koic
Copy link
Member

koic commented Jul 16, 2021

Unaligned strings in hash literal values is designed to always be aligned with EnforcedStyle: aligned style. I would like to hear @jonas054 opinion.
https://github.com/rubocop/rubocop/blob/v1.18.3/spec/rubocop/cop/layout/line_end_string_concatenation_indentation_spec.rb#L51-L72

@jonas054
Copy link
Collaborator

Yes, the cop behaves as documented. https://docs.rubocop.org/rubocop/1.18/cops_layout.html#layoutlineendstringconcatenationindentation

The exception for hash values is something I added because in my opinion indentation within a hash literal was just too ugly. This is of course very subjective, and other people way find it surprising. It's a small detail though, and perhaps not worth changing?

@fuegas
Copy link
Author

fuegas commented Jul 19, 2021

In my opinion it makes the "Enforced" style not enforced as there is a (subjective) deviation from it. However, I do have to acknowledge that the deviation is written down in the documentation. It might be a bit clearer if the examples would reflect this deviation as well.

I've never written or altered a cop myself, so I can't judge how much work it would be to have an EnforcedHashStyle option (which defaults to the existing behaviour). But I do think that the term EnforcedStyle is inconsistent with the behaviour of the Cop.

@jonas054
Copy link
Collaborator

It might be a bit clearer if the examples would reflect this deviation as well.

I think they already do. Look:

# bad
[...]
my_hash = {
  first: 'a message' \
    'in two parts'
}

# good
[...]
my_hash = {
  first: 'a message' \
         'in two parts'
}

There might be a better way to express it. I'm open to suggestions.

I've never written or altered a cop myself, so I can't judge how much work it would be to have an EnforcedHashStyle option (which defaults to the existing behaviour).

To me, it seems like a clear case of "not worth the effort". There are cops with more than one style parameter today, but it's a bit complicated if you ask me.

@fuegas
Copy link
Author

fuegas commented Jul 21, 2021

Sorry for my unclear answer @jonas054, I mean under the example of EnforcedStyle: indented, as that only shows the split string and not the exception that exists for hashes.

For example, this would clear it up right away I think.

# bad
result = 'x' \
         'y'

# good
result = 'x' \
  'y'

# indented has no effect on hashes
my_hash = {
  first: 'a message' \
         'in two parts'
}

But you could say we should carefully read the paragraph as well 😉

To me, it seems like a clear case of "not worth the effort". There are cops with more than one style parameter today, but it's a bit complicated if you ask me.

Noted, I'll see that I'm going to inform the team regarding the current use of the cop and the style in our hashes.

@jonas054
Copy link
Collaborator

Yes, I think the normal style for the cop documentation is to have very terse comments in the examples ("good" and "bad"), and to put any explanations in the text above them. I'll leave the cop as it is without changes for now, and close the issue.

@shanecav84
Copy link
Contributor

The exception for hash values is something I added because in my opinion indentation within a hash literal was just too ugly. This is of course very subjective, and other people way find it surprising.

I started updating my codebase to conform to the 'indented' style and found this surprising. I think the EnforcedStyle should be applied universally. If not, then another enforced style should be introduced (maybe "indentedExceptHashValues").

@jonas054
Copy link
Collaborator

jonas054 commented Aug 8, 2021

Looking at this again, I must admit that your expectations are correct, @fuegas and @shanecav84. It's much more reasonable for Layout/LineEndStringConcatenationIndentation to behave like Layout/MultilineOperationIndentation, and in the case of hash literals it doesn't.

With the configuration

AllCops:
  NewCops: enable

Layout/LineEndStringConcatenationIndentation:
  EnforcedStyle: indented

Layout/MultilineOperationIndentation:
  EnforcedStyle: indented

Style/LineEndConcatenation:
  Enabled: false

Style/StringConcatenation:
  Enabled: false

RuboCop corrects to

# frozen_string_literal: true

puts 'Lorem ipsum dolor sit amet, consectetur ' +
  'adipiscing elit. Aenean sollicitudin maximus ' +
  'lacus eu maximus.'

h = {
  abc: 'Lorem ipsum dolor sit amet, consectetur ' +
    'adipiscing elit. Aenean sollicitudin maximus ' +
    'lacus eu maximus.',
  defghi: 'Lorem ipsum dolor sit amet, consectetur ' +
    'adipiscing elit.'
}

p h

so with backslashes it should be like this:

# frozen_string_literal: true

puts 'Lorem ipsum dolor sit amet, consectetur ' \
  'adipiscing elit. Aenean sollicitudin maximus ' \
  'lacus eu maximus.'

h = {
  abc: 'Lorem ipsum dolor sit amet, consectetur ' \
    'adipiscing elit. Aenean sollicitudin maximus ' \
    'lacus eu maximus.',
  defghi: 'Lorem ipsum dolor sit amet, consectetur ' \
    'adipiscing elit.'
}

p h

Rather than adding another style, I will consider the current behavior a bug, and submit a fix for it.

@jonas054 jonas054 reopened this Aug 8, 2021
@jonas054 jonas054 self-assigned this Aug 8, 2021
@fuegas
Copy link
Author

fuegas commented Aug 8, 2021

Thank you for revisiting this @jonas054 ! I'm looking forward to the fix being merged 👍

@koic koic closed this as completed in acd01be Aug 8, 2021
koic added a commit that referenced this issue Aug 8, 2021
…nIndentation_indented_hash_values

[Fix #9927] Indent hash values in LineEndStringConcatenationIndentation
@shanecav84
Copy link
Contributor

shanecav84 commented Aug 9, 2021

Thanks for considering our feedback @jonas054!

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

No branches or pull requests

4 participants