Rubocop complains about the indentation on the .new and .permit_method_call lines in the code snippet below. Aligning the calls with the some_instance line resolves the complaints, but in this case it should be calculating the indent from the SomeService line. I am using version 0.29.0.
I also included my .rubocop.yml below. Is this a Rubocop limitation, or is it something I can resolve with my configuration? (I tried the indent and align configuration options to no avail.)
some_instance.member.attributes =
SomeService
.new(@class_member)
.permit_method_call(params[:some_key])
AlignParameters:
EnforcedStyle: with_fixed_indentation
AsciiComments:
Enabled: false
ClassLength:
Max: 500
CyclomaticComplexity:
Max: 10
LineLength:
Max: 140
MethodLength:
Max: 20
StringLiterals:
EnforcedStyle: double_quotes
If I'm not mistaken, it's not the AlignParameters cop that complains here, but instead MultilineOperationIndentation.
Sorry for the long break in communications. Using the following .rubocop.yml still results in the complaints about indentation.
AbcSize:
Max: 32
AlignParameters:
EnforcedStyle: with_fixed_indentation
AsciiComments:
Enabled: false
ClassLength:
Max: 500
CyclomaticComplexity:
Max: 10
LineLength:
Max: 140
MethodLength:
Max: 32
MultilineOperationIndentation:
EnforcedStyle: indented
StringLiterals:
EnforcedStyle: double_quotes
I included the complaints below for reference, I hope this is just a configuration issue on our side!
app/services/redacted_service.rb:34:9: C: Use 2 (not 4) spaces for indenting an expression spanning multiple lines.
.new(@class_member)
^^^^
app/services/redacted_service.rb:35:9: C: Use 2 (not 4) spaces for indenting an expression spanning multiple lines.
.permit_method_call(params[:some_key])
^^^^^^^^^^^^^^^^^^^
No, you can't solve this with configuration, unless you want to disable the cop. Looking at this issue and at #1633, it seems to me that multiline method call chains should be checked by a separate cop, as people have different expectations and preferences for expressions like the one above compared to things like
some_instance.member.attributes =
some_value +
new_class_member +
params[:some_key]
Is this solved with @jonas054's new MultilineMethodCallIndentation cop?
Not exactly. The current master supports the following styles. With
Style/MultilineMethodCallIndentation:
EnforcedStyle: indented
RuboCop accepts
some_instance.member.attributes = SomeService
.new(@class_member)
.permit_method_call(params[:some_key])
and
some_instance.member.attributes =
SomeService
.new(@class_member)
.permit_method_call(params[:some_key])
With
Style/MultilineMethodCallIndentation:
EnforcedStyle: aligned
it accepts
some_instance.member.attributes = SomeService
.new(@class_member)
.permit_method_call(params[:some_key])
and
some_instance.member.attributes = SomeService.new(@class_member)
.permit_method_call(params[:some_key])
and
some_instance.member.attributes =
SomeService
.new(@class_member)
.permit_method_call(params[:some_key])
@jonas054 OK, thanks. It seems like the style requested here is quite reasonable. Do you have any ideas what a 3rd style for MultilineMethodCallIndentation could be called?
Here's my understanding of what is requested.
The style is a variation on the indented style, and it differs from the current indented style when the expression is a binary operation, or assignment. In this new style, the base for the indentation is the right hand side of the binary operation rather than the whole expression (or the left hand side).
If my understanding is correct, it follows that the following indentation would be enforced, for example.
some_instance.member.attributes == SomeService
.new(@class_member)
.permit_method_call(params[:some_key])
The name that springs to mind is indented_rhs, but you might be able to come up with a better suggestion, @alexdowad.
I don't think this style has anything specifically to do with assignments. If the selector in a dotted method call is pushed to a following line, then you follow the chain of dotted method calls back to its root, and indent from the receiver of the first call in the chain.
So the example you gave is right. But so are these:
if Something
.call1
.call2
while Something
.call1
.call2
class A < Something
.call
@elyzion, does that seem to describe what you are looking for?
Looking forward to a style that allows:
@something = Someclass
.where(kind: :hello)
.includes(:other_class)
.order(created_at: :desc)
(using the 4 char standard continued indentation from Rubymine)
Could we call this style offset (from the receiver)? relative (to the receiver)? Or give it a long and wordy name which describes it more precisely?
I'd go for long and wordy. How about indented_from_receiver, or even indented_relative_to_receiver?
Has there been any progress on this issue? In our projects we're now disabling this cop as we're normally writing our code indented_relative_to_receiver (I like the name!).
What we'd like to have is a cop which enforces the following code style:
my_variable = MyClass
.method_1(123)
.method_2
If no one is working on this, I might have a look in how to make this possible myself.
I'm not sure I'm reading the code correctly, but shouldn't it _almost_ handle this case already?
I found this code in the cop but can't really make sense of it, because it seems that line either goes unused or ignored (hence this issue).
@nicolas-fricke I'd love to help out, we're also disabling this cop because of this same issue.
Yes, _almost_ being the operative word. What you see there is _alignment_ where the right hand side of the expression (b and .c) are aligned with each other without any extra indentation. As I've said earlier in this discussion, we need another style an addition to aligned and indented. It's doable but not trivial to implement.
Thanks @jonas054 for taking care of this – looking forward to upgrading rubocop to the next version and then reenabling this new cop :)
Most helpful comment
Looking forward to a style that allows:
(using the 4 char standard continued indentation from Rubymine)